Kunzisoft / KeePassDX

Lightweight vault and password manager for Android, KeePassDX allows editing encrypted data in a single file in KeePass format and fill in the forms in a secure way.
https://www.keepassdx.com/
GNU General Public License v3.0
4.57k stars 269 forks source link

java.io.IOException: Invalid Hmac #949

Closed sniff-numeral closed 3 years ago

sniff-numeral commented 3 years ago

Describe the bug I wanted to merge the database from my smartphone with the one on my laptop with the merge function from KeePassXC. That threw an "Invalid inner header id size" error. KeePassDX is configured to open the database with my fingerprint, that works. I then made another exact copy of the database on my smartphone, the one that I open with a fingerprint without any problems. Now, when I try to open the copy with password and keyfile, KeePassDX throws "Could not load your database. java.io.IOException: Invalid Hmac"

I tried to open said database with several other KeePass-Implementations, so far all throw the same or similar error tracing back to an invalid hmac.

I have used that database with KeePassDX and KeePassXC for years without any problems.

To Reproduce Steps to reproduce the behavior:

Expected behavior

KeePass Database

KeePassDX (please complete the following information):

Android (please complete the following information):

Additional context Add any other context about the problem here.

J-Jamet commented 3 years ago

~Your scenario clearly indicates that the problem is with the transfer between your PC and your mobile device. Correctly reconfigure your file transfer method with a backup to have a functional synchronization system.~

sniff-numeral commented 3 years ago

I checked the integrity of each copy with sha256sum. They are identical according to that. To clarify, the database opens with the fingerprint. To do that, I had to open the database first with the password, then choose the fingerprint. I did this month ago. So back then, the database opened with the password, now it doesn't. Between then and now, the database must have somehow been corrupted, but not due to some transfer error. It was on the phone storage the whole time. So the corruption must have happened on the phone. But this could have happened anytime in the last few month.

If I try to open it now with the password, KeePassDX "throws java.io.IOException: Invalid Hmac".

As I understand it, this exception is thrown by the readSafeBlock() function in class HmacBlockInputStream(). I guess my question should then be: Is it the intended behaviour that the readSafeBlock() doesn't get called, when a fingerprint is used to open a database?

J-Jamet commented 3 years ago

I checked the integrity of each copy with sha256sum. They are identical according to that. To clarify, the database opens with the fingerprint.

In this case, the credential (password or/and key file) associated with the fingerprint is correct and the one you try to enter manually is not.

Between then and now, the database must have somehow been corrupted, but not due to some transfer error. It was on the phone storage the whole time. So the corruption must have happened on the phone. But this could have happened anytime in the last few month.

If the database file can be opened with the fingerprint, then the file is not corrupted.

Try to find out why it doesn't open with the ones you are currently trying, maybe a bad key file whose integrity has been changed. As you can open it with your fingerprint, you can also still change the credential. Do it with the ones you think are correct but it can be dangerous.

J-Jamet commented 3 years ago

As I understand it, this exception is thrown by the readSafeBlock() function in class HmacBlockInputStream(). I guess my question should then be: Is it the intended behaviour that the readSafeBlock() doesn't get called, when a fingerprint is used to open a database?

Opening by fingerprint doesn't change anything, it's the same as using credentials manually, the function is called in both cases, the most likely explanation for the exception if it works with the fingerprint is that the credential is not correct.

sniff-numeral commented 3 years ago

Ok, I did as you recommended, opened the db with fingerprint and changed deleted all credentials. Works just fine. So thanks for your help!

Now that my passwords are rescued, I played a little bit with the backup of the db. Here's the thing.

When I try to open it with KeePassDX and enter the password that I think should be correct (and I'm pretty sure it is), then I get the IOException, if I enter just some random chars, it says "Could not read credentials".

And the same with KeePassXC, the password which shuld be correct gives a different error than some random text.

J-Jamet commented 3 years ago

Maybe the encoding of a character has changed on the password or on the copy, that's what I don't understand either. Indeed, the exception is only raised if there is a block header which is not signed correctly with HMAC-SHA-256. So this exception should be thrown only in case of corruption. But it can't be a corruption because you managed to open it with the fingerprint and you checked the hash of the duplicated files. So something is wrong with the copy. I concluded that the credential was not good (theory : maybe visually the same and passed the first verification because a type of character encoding that provides a good hash but not a good block or a bad padding somewhere). The important thing is that you could open your database, so changing the credential rewrote the whole structure of the database anyway. Tell me if you have other effects, can the database be opened everywhere?

sniff-numeral commented 3 years ago

Tell me if you have other effects, can the database be opened everywhere?

The one where I removed the credentials? Yes, opened it with KeepassXC on the laptop.

J-Jamet commented 3 years ago

Can you try to make a backup and put back the credentials you thought were correct to verify that it works correctly? Because there might be a bug, I'd like to make sure it's not.

sniff-numeral commented 3 years ago

Did that, works fine.

J-Jamet commented 3 years ago

So it's OK.