-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Due to a change in AES Key Wrap implementation in JDK 17, AesKeyWrap.wrap(...) and AesKeyWrap.unwrap(..) can not re-use a DestroyableSecretKey.
DestroyableSecretKey.getEncoded() will always return the original raw key (which is intended):
cryptolib/src/main/java/org/cryptomator/cryptolib/common/DestroyableSecretKey.java
Lines 107 to 119 in d32856f
| /** | |
| * Returns the raw key bytes this instance wraps. | |
| * <p> | |
| * <b>Important:</b> Any change to the returned array will reflect in this key. Make sure to | |
| * {@link #clone() make a local copy} if you can't rule out mutations. | |
| * | |
| * @return A byte array holding the secret key | |
| */ | |
| @Override | |
| public byte[] getEncoded() { | |
| Preconditions.checkState(!destroyed, "Key has been destroyed"); | |
| return key; | |
| } |
However, the new implementation of Cipher.init(...) in JDK17's AESKeyWrap does exactly this: It modifies the returned byte array. Reusing the same key for two consecutive key wrap or unwrap operations is therefore not possible, which leads to invalid results in cases like these:
cryptolib/src/main/java/org/cryptomator/cryptolib/common/MasterkeyFileAccess.java
Lines 143 to 145 in d32856f
| try (DestroyableSecretKey kek = scrypt(passphrase, parsedFile.scryptSalt, pepper, parsedFile.scryptCostParam, parsedFile.scryptBlockSize)) { | |
| encKey = AesKeyWrap.unwrap(kek, parsedFile.encMasterKey, Masterkey.ENC_ALG).getEncoded(); | |
| macKey = AesKeyWrap.unwrap(kek, parsedFile.macMasterKey, Masterkey.MAC_ALG).getEncoded(); |