Lines 40-45
Link Here
|
40 |
import javax.crypto.spec.SecretKeySpec; |
40 |
import javax.crypto.spec.SecretKeySpec; |
41 |
|
41 |
|
42 |
import org.apache.poi.EncryptedDocumentException; |
42 |
import org.apache.poi.EncryptedDocumentException; |
|
|
43 |
import org.apache.poi.poifs.crypt.ChainingMode; |
43 |
import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; |
44 |
import org.apache.poi.poifs.crypt.ChunkedCipherInputStream; |
44 |
import org.apache.poi.poifs.crypt.CipherAlgorithm; |
45 |
import org.apache.poi.poifs.crypt.CipherAlgorithm; |
45 |
import org.apache.poi.poifs.crypt.CryptoFunctions; |
46 |
import org.apache.poi.poifs.crypt.CryptoFunctions; |
Lines 93-103
Link Here
|
93 |
public boolean verifyPassword(String password) throws GeneralSecurityException { |
94 |
public boolean verifyPassword(String password) throws GeneralSecurityException { |
94 |
AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); |
95 |
AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); |
95 |
AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); |
96 |
AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); |
96 |
HashAlgorithm hashAlgo = header.getHashAlgorithmEx(); |
97 |
HashAlgorithm hashAlgo = ver.getHashAlgorithm(); |
97 |
CipherAlgorithm cipherAlgo = header.getCipherAlgorithm(); |
|
|
98 |
int blockSize = header.getBlockSize(); |
99 |
int keySize = header.getKeySize()/8; |
100 |
|
98 |
|
|
|
99 |
int keySize = (ver.getKeySize() == -1 ? header.getKeySize() : ver.getKeySize())/8; |
100 |
int blockSize = (ver.getBlockSize() == -1 ? header.getBlockSize() : ver.getBlockSize()); |
101 |
|
101 |
byte[] pwHash = hashPassword(password, ver.getHashAlgorithm(), ver.getSalt(), ver.getSpinCount()); |
102 |
byte[] pwHash = hashPassword(password, ver.getHashAlgorithm(), ver.getSalt(), ver.getSpinCount()); |
102 |
|
103 |
|
103 |
/** |
104 |
/** |
Lines 113-119
Link Here
|
113 |
* blockSize bytes. |
114 |
* blockSize bytes. |
114 |
* 4. Use base64 to encode the result of step 3. |
115 |
* 4. Use base64 to encode the result of step 3. |
115 |
*/ |
116 |
*/ |
116 |
byte verfierInputEnc[] = hashInput(getEncryptionInfo(), pwHash, kVerifierInputBlock, ver.getEncryptedVerifier(), Cipher.DECRYPT_MODE); |
117 |
byte verfierInputEnc[] = hashInput(ver, pwHash, kVerifierInputBlock, ver.getEncryptedVerifier(), Cipher.DECRYPT_MODE); |
117 |
setVerifier(verfierInputEnc); |
118 |
setVerifier(verfierInputEnc); |
118 |
MessageDigest hashMD = getMessageDigest(hashAlgo); |
119 |
MessageDigest hashMD = getMessageDigest(hashAlgo); |
119 |
byte[] verifierHash = hashMD.digest(verfierInputEnc); |
120 |
byte[] verifierHash = hashMD.digest(verfierInputEnc); |
Lines 130-136
Link Here
|
130 |
* blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes. |
131 |
* blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes. |
131 |
* 4. Use base64 to encode the result of step 3. |
132 |
* 4. Use base64 to encode the result of step 3. |
132 |
*/ |
133 |
*/ |
133 |
byte verifierHashDec[] = hashInput(getEncryptionInfo(), pwHash, kHashedVerifierBlock, ver.getEncryptedVerifierHash(), Cipher.DECRYPT_MODE); |
134 |
byte verifierHashDec[] = hashInput(ver, pwHash, kHashedVerifierBlock, ver.getEncryptedVerifierHash(), Cipher.DECRYPT_MODE); |
134 |
verifierHashDec = getBlock0(verifierHashDec, hashAlgo.hashSize); |
135 |
verifierHashDec = getBlock0(verifierHashDec, hashAlgo.hashSize); |
135 |
|
136 |
|
136 |
/** |
137 |
/** |
Lines 146-152
Link Here
|
146 |
* blockSize bytes. |
147 |
* blockSize bytes. |
147 |
* 4. Use base64 to encode the result of step 3. |
148 |
* 4. Use base64 to encode the result of step 3. |
148 |
*/ |
149 |
*/ |
149 |
byte keyspec[] = hashInput(getEncryptionInfo(), pwHash, kCryptoKeyBlock, ver.getEncryptedKey(), Cipher.DECRYPT_MODE); |
150 |
byte keyspec[] = hashInput(header, pwHash, kCryptoKeyBlock, ver.getEncryptedKey(), Cipher.DECRYPT_MODE); |
150 |
keyspec = getBlock0(keyspec, keySize); |
151 |
keyspec = getBlock0(keyspec, keySize); |
151 |
SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.getCipherAlgorithm().jceId); |
152 |
SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.getCipherAlgorithm().jceId); |
152 |
|
153 |
|
Lines 163-170
Link Here
|
163 |
* array with 0x00 to the next integral multiple of blockSize bytes. |
164 |
* array with 0x00 to the next integral multiple of blockSize bytes. |
164 |
* 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3. |
165 |
* 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3. |
165 |
*/ |
166 |
*/ |
166 |
byte vec[] = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityKeyBlock, blockSize); |
167 |
byte vec[] = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityKeyBlock, blockSize); |
167 |
Cipher cipher = getCipher(secretKey, cipherAlgo, ver.getChainingMode(), vec, Cipher.DECRYPT_MODE); |
168 |
CipherAlgorithm cipherAlgo = ver.getCipherAlgorithm(); |
|
|
169 |
Cipher cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE); |
168 |
byte hmacKey[] = cipher.doFinal(header.getEncryptedHmacKey()); |
170 |
byte hmacKey[] = cipher.doFinal(header.getEncryptedHmacKey()); |
169 |
hmacKey = getBlock0(hmacKey, hashAlgo.hashSize); |
171 |
hmacKey = getBlock0(hmacKey, hashAlgo.hashSize); |
170 |
|
172 |
|
Lines 257-274
Link Here
|
257 |
return fillSize; |
259 |
return fillSize; |
258 |
} |
260 |
} |
259 |
|
261 |
|
260 |
protected static byte[] hashInput(EncryptionInfo encryptionInfo, byte pwHash[], byte blockKey[], byte inputKey[], int cipherMode) { |
262 |
/* package */ static byte[] hashInput(AgileEncryptionConfig aec, byte pwHash[], byte blockKey[], byte inputKey[], int cipherMode) { |
261 |
EncryptionVerifier ver = encryptionInfo.getVerifier(); |
263 |
int keySize = aec.getKeySize()/8; |
262 |
AgileDecryptor dec = (AgileDecryptor)encryptionInfo.getDecryptor(); |
264 |
int blockSize = aec.getBlockSize(); |
263 |
int keySize = dec.getKeySizeInBytes(); |
265 |
byte salt[] = aec.getSalt(); |
264 |
int blockSize = dec.getBlockSizeInBytes(); |
266 |
HashAlgorithm hashAlgo = aec.getHashAlgorithm(); |
265 |
HashAlgorithm hashAlgo = ver.getHashAlgorithm(); |
267 |
CipherAlgorithm cipherAlgo = aec.getCipherAlgorithm(); |
266 |
byte[] salt = ver.getSalt(); |
268 |
ChainingMode chainMode = aec.getChainingMode(); |
267 |
|
269 |
|
268 |
byte intermedKey[] = generateKey(pwHash, hashAlgo, blockKey, keySize); |
270 |
byte intermedKey[] = generateKey(pwHash, hashAlgo, blockKey, keySize); |
269 |
SecretKey skey = new SecretKeySpec(intermedKey, ver.getCipherAlgorithm().jceId); |
271 |
SecretKey skey = new SecretKeySpec(intermedKey, cipherAlgo.jceId); |
270 |
byte[] iv = generateIv(hashAlgo, salt, null, blockSize); |
272 |
byte[] iv = generateIv(hashAlgo, salt, null, blockSize); |
271 |
Cipher cipher = getCipher(skey, ver.getCipherAlgorithm(), ver.getChainingMode(), iv, cipherMode); |
273 |
Cipher cipher = getCipher(skey, cipherAlgo, chainMode, iv, cipherMode); |
272 |
byte[] hashFinal; |
274 |
byte[] hashFinal; |
273 |
|
275 |
|
274 |
try { |
276 |
try { |