jorabin / KeePassJava2

Java API for KeePass Password Databases - Read/Write 2.x (File versions 3 and 4), Read 1.x
Apache License 2.0
250 stars 71 forks source link

Writing and saving to V4-ChaCha-AES/test123-ChaCha20-AES saves them with AES encryption #36

Closed ng-23 closed 1 year ago

ng-23 commented 2 years ago

I tried adding a new group and entry to the test databases in the title and their encryption was changed from ChaCha20 to AES. I suspect it has something to do with (1) both files being KDBX 3.1 and (2) ChaCha20 encryption being reserved for KDBX 4.x in KeePass versions 2.44+, as mentioned here.

jorabin commented 2 years ago

I'm not clear what you are describing here, can you clarify, please?

ng-23 commented 2 years ago

Basically, if you made any changes to the cipher algorithm/KDF algorithm (i.e. chose ChaCha20 instead of AES as the cipher), saving with the API will ignore them and assume the defaults (AES for cipher and KDF, as well as default transform rounds for KDF). I think it mainly has to do with how the save method in KdbxStreamFormat creates a default KDBX header itself each time and uses that when saving the database. Since the method itself is making the header, you have no control over it and thus whatever fields a KdbxHeader object has when its constructor is called is what the header of your database will have after saving, which may/may not be what you wanted.

In my fork, I added another save method to KdbxStreamFormat that takes a KdbxHeader as a parameter and uses it instead of creating a new KdbxHeader itself. This would allow you to create a KdbxHeader yourself outside the save method, customize its fields with the setters, and then pass it to that save method. I don't know if this the best solution but it does give you control over the header and allows for saving with more than just AES for cipher and KDF.

jorabin commented 2 years ago

Thanks for the clarification. That's definitely one for the list.

jorabin commented 1 year ago

This turned out to be a lot more complicated than I had expected. The basic idea has been to add a method to the underlying Database interface

   <C extends StreamConfiguration> void save(StreamFormat<C> streamFormat, Credentials credentials, OutputStream outputStream) throws IOException;

For most purposes StreamFormat is KdbxStreamFormat and StreamConfiguration is KdbxHeader.

The static methods load for the various Database implementations also get a StreamFormat parameter.

The simple implementation is yet to be done at the time of this comment. Watch for that commit.

jorabin commented 1 year ago

closed in 2.2.1