// Algorithm 8b: Compute UE
byte[] hashUE = computeHash2B(concat(userPasswordBytes, userKeySalt),
userPasswordBytes, null);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(hashUE, "AES"),
new IvParameterSpec(new byte[16]));
byte[] ue = cipher.doFinal(encryptionKey);
// Algorithm 9a: Compute O
byte[] ownerPasswordBytes = truncate127(ownerPassword.getBytes("UTF-8"));
byte[] ownerValidationSalt = new byte[8];
byte[] ownerKeySalt = new byte[8];
rnd.nextBytes(ownerValidationSalt);
rnd.nextBytes(ownerKeySalt);
byte[] hashO = computeHash2B(concat(ownerPasswordBytes, ownerValidationSalt, u),
ownerPasswordBytes, u);
byte[] o = concat(hashO, ownerValidationSalt, ownerKeySalt);
// Algorithm 9b: Compute OE
byte[] hashOE = computeHash2B(concat(ownerPasswordBytes, ownerKeySalt, u),
ownerPasswordBytes, u);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(hashOE, "AES"),
new IvParameterSpec(new byte[16]));
byte[] oe = cipher.doFinal(encryptionKey);
// Set keys and other required constants in encryption dictionary
encryptionDictionary.setUserKey(u);
encryptionDictionary.setUserEncryptionKey(ue);
encryptionDictionary.setOwnerKey(o);
encryptionDictionary.setOwnerEncryptionKey(oe);
PDCryptFilterDictionary cryptFilterDictionary = new PDCryptFilterDictionary();
cryptFilterDictionary.setCryptFilterMethod(COSName.AESV3);
cryptFilterDictionary.setLength(keyLength);
encryptionDictionary.setStdCryptFilterDictionary(cryptFilterDictionary);
encryptionDictionary.setStreamFilterName(COSName.STD_CF);
encryptionDictionary.setStringFilterName(COSName.STD_CF);
setAES(true);
// Algorithm 10: compute "Perms" value
byte[] perms = new byte[16];
perms[0] = (byte)permissionInt;
perms[1] = (byte)(permissionInt >>> 8);
perms[2] = (byte)(permissionInt >>> 16);
perms[3] = (byte)(permissionInt >>> 24);
perms[4] = perms[5] = perms[6] = perms[7] = (byte)0xFF;
perms[8] = 'T'; // we always use EncryptMetadata == true
perms[9] = 'a';
perms[10] = 'd';
perms[11] = 'b';
for (int i = 12; i <= 15; i++)
{
perms[i] = (byte)rnd.nextInt();
}
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptionKey, "AES"),
new IvParameterSpec(new byte[16]));
byte[] permsEnc = cipher.doFinal(perms);
encryptionDictionary.setPerms(permsEnc);
}