-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Make implementation of Challenge-Response more compatible to Keepass 2 #1060
Description
As the author of Keepass2Android I was looking into implementing the Challenge-Response functionality as in KeepassXC. While I like the idea of using the Master seed as "challenge", I am not so happy with the implementation of Challenge-Response. To explain why, here is a short overview of the key generation in Keepass 2 (by Dominik Reichl) which is used by Keepass2Android as well:
Keepass2:
pbPassword = CryptoUtil.HashSha256(StrUtil.Utf8.GetBytes(strPassword))
pbKeyFile = LoadKeyFile(...)
pbCustomKey = challengeResponse //for example when using KeeChallenge Plugin in keepass 2
//CompositeKey concatenates the data of ALL IUserKey objects
pbAllData = pbPassword + pbKeyfile + pbCustomKey
pbRaw32 = CryptoUtil.HashSha256(pbAllData)
pUserKey32 = kdf.Transform(pbRaw32)
pbCmp = MasterSeed + pUserKey32
pbHmacKey64 = h.ComputeHash(pbCmp);
KeepassXC, with the naming conventions from Keepass 2
pbPassword = CryptoUtil.HashSha256(StrUtil.Utf8.GetBytes(strPassword))
pbKeyFile = LoadKeyFile(...)
//CompositeKey only concatenates password + keyfile but not challengeResponse
pbAllData = pbPassword + pbKeyFile
pUserKey32 = kdf.Transform(pbRaw32)
pbRaw32 = CryptoUtil.HashSha256(pbAllData)
//challengeResponse is added later, where no plugin can modify the computation in Keepass2
pbCmp = MasterSeed + challengeResponse + pUserKey32
pbHmacKey64 = h.ComputeHash(pbCmp);
In Keepass 2, it is very common for Plugins to add elements to the Composite Key. These elements are objects of KcpCustomKey or custom classes implementing the IUserKey interface. The data of all these elements are concatenated and transformed. When I added support for KeeOtp or KeeChallenge in Keepass2Android, I did exactly this, which was very simple.
In KeepassXC, the challengeRespose is not concatenated with password and (potentially) key file. Instead, it is prepended to the hashed and transformed key. This cannot be implemented for Keepass2 by a plugin, so the current KeepassXC implementation will not be usable for Keepass 2 users, and nobody can change this by developing a plugin. It also requires some pretty intrusive code changes if I want to implement this in Keepass2Android which I believe are not necessary if KeepassXC would offer (at least as an option or better as the default) to concat the challengeResponse to the pbAllData.
If I didn't miss any important reason to integrate the challengeResponse at this point in the processing, I suggest you make the key computation more compatible to other Keepass implementations. Please let me know what you think so I can plan further development on the feature for keepass2android.