protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); hashAlg.update(ver.getSalt()); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); byte salt[] = ver.getSalt(); hashAlg.reset(); for (int i = 0; i < 16; i++) { hashAlg.update(hash, 0, 5); hashAlg.update(salt); } hash = new byte[5]; System.arraycopy(hashAlg.digest(), 0, hash, 0, 5); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver, int keySize) { HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte pwHash[] = hashPassword(password, hashAlgo, ver.getSalt(), ver.getSpinCount()); byte[] blockKey = new byte[4]; LittleEndian.putInt(blockKey, 0, 0); byte[] finalHash = CryptoFunctions.generateKey(pwHash, hashAlgo, blockKey, hashAlgo.hashSize); byte x1[] = fillAndXor(finalHash, (byte) 0x36); byte x2[] = fillAndXor(finalHash, (byte) 0x5c); byte[] x3 = new byte[x1.length + x2.length]; System.arraycopy(x1, 0, x3, 0, x1.length); System.arraycopy(x2, 0, x3, x1.length, x2.length); byte[] key = Arrays.copyOf(x3, keySize); return new SecretKeySpec(key, ver.getCipherAlgorithm().jceId); }
protected static Cipher initCipherForBlock(Cipher cipher, int block, EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) throws GeneralSecurityException { EncryptionVerifier ver = encryptionInfo.getVerifier(); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte blockKey[] = new byte[4]; LittleEndian.putUInt(blockKey, 0, block); byte encKey[] = CryptoFunctions.generateKey(skey.getEncoded(), hashAlgo, blockKey, 16); SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); if (cipher == null) { EncryptionHeader em = encryptionInfo.getHeader(); cipher = CryptoFunctions.getCipher(key, em.getCipherAlgorithm(), null, null, encryptMode); } else { cipher.init(encryptMode, key); } return cipher; }
protected static Cipher initCipherForBlock(Cipher cipher, int block, EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) throws GeneralSecurityException { EncryptionVerifier ver = encryptionInfo.getVerifier(); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte blockKey[] = new byte[4]; LittleEndian.putUInt(blockKey, 0, block); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); hashAlg.update(skey.getEncoded()); byte encKey[] = hashAlg.digest(blockKey); EncryptionHeader header = encryptionInfo.getHeader(); int keyBits = header.getKeySize(); encKey = CryptoFunctions.getBlock0(encKey, keyBits / 8); if (keyBits == 40) { encKey = CryptoFunctions.getBlock0(encKey, 16); } SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); if (cipher == null) { cipher = CryptoFunctions.getCipher(key, header.getCipherAlgorithm(), null, null, encryptMode); } else { cipher.init(encryptMode, key); } return cipher; }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver, getKeySizeInBytes()); Cipher cipher = getCipher(skey); try { byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = cipher.doFinal(encryptedVerifier); setVerifier(verifier); MessageDigest sha1 = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm()); byte[] calcVerifierHash = sha1.digest(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte decryptedVerifierHash[] = cipher.doFinal(encryptedVerifierHash); // see 2.3.4.9 Password Verification (Standard Encryption) // ... The number of bytes used by the encrypted Verifier hash MUST be 32 ... // TODO: check and trim/pad the hashes to 32 byte[] verifierHash = Arrays.copyOf(decryptedVerifierHash, calcVerifierHash.length); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } else { return false; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver); try { Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = new byte[encryptedVerifier.length]; cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); setVerifier(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } return false; }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver); try { Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = new byte[encryptedVerifier.length]; cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); setVerifier(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } return false; }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); hashAlg.update(ver.getSalt()); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver) { if (password.length() > 255) { password = password.substring(0, 255); } HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte hash[] = hashAlg.digest(StringUtil.getToUnicodeLE(password)); byte salt[] = ver.getSalt(); hashAlg.reset(); for (int i = 0; i < 16; i++) { hashAlg.update(hash, 0, 5); hashAlg.update(salt); } hash = new byte[5]; System.arraycopy(hashAlg.digest(), 0, hash, 0, 5); return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId); }
protected static SecretKey generateSecretKey(String password, EncryptionVerifier ver, int keySize) { HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte pwHash[] = hashPassword(password, hashAlgo, ver.getSalt(), ver.getSpinCount()); byte[] blockKey = new byte[4]; LittleEndian.putInt(blockKey, 0, 0); byte[] finalHash = CryptoFunctions.generateKey(pwHash, hashAlgo, blockKey, hashAlgo.hashSize); byte x1[] = fillAndXor(finalHash, (byte) 0x36); byte x2[] = fillAndXor(finalHash, (byte) 0x5c); byte[] x3 = new byte[x1.length + x2.length]; System.arraycopy(x1, 0, x3, 0, x1.length); System.arraycopy(x2, 0, x3, x1.length, x2.length); byte[] key = Arrays.copyOf(x3, keySize); return new SecretKeySpec(key, ver.getCipherAlgorithm().jceId); }
protected static Cipher initCipherForBlock(Cipher cipher, int block, EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) throws GeneralSecurityException { EncryptionVerifier ver = encryptionInfo.getVerifier(); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte blockKey[] = new byte[4]; LittleEndian.putUInt(blockKey, 0, block); byte encKey[] = CryptoFunctions.generateKey(skey.getEncoded(), hashAlgo, blockKey, 16); SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); if (cipher == null) { EncryptionHeader em = encryptionInfo.getHeader(); cipher = CryptoFunctions.getCipher(key, em.getCipherAlgorithm(), null, null, encryptMode); } else { cipher.init(encryptMode, key); } return cipher; }
protected static Cipher initCipherForBlock(Cipher cipher, int block, EncryptionInfo encryptionInfo, SecretKey skey, int encryptMode) throws GeneralSecurityException { EncryptionVerifier ver = encryptionInfo.getVerifier(); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); byte blockKey[] = new byte[4]; LittleEndian.putUInt(blockKey, 0, block); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); hashAlg.update(skey.getEncoded()); byte encKey[] = hashAlg.digest(blockKey); EncryptionHeader header = encryptionInfo.getHeader(); int keyBits = header.getKeySize(); encKey = CryptoFunctions.getBlock0(encKey, keyBits / 8); if (keyBits == 40) { encKey = CryptoFunctions.getBlock0(encKey, 16); } SecretKey key = new SecretKeySpec(encKey, skey.getAlgorithm()); if (cipher == null) { cipher = CryptoFunctions.getCipher(key, header.getCipherAlgorithm(), null, null, encryptMode); } else { cipher.init(encryptMode, key); } return cipher; }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver, getKeySizeInBytes()); Cipher cipher = getCipher(skey); try { byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = cipher.doFinal(encryptedVerifier); setVerifier(verifier); MessageDigest sha1 = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm()); byte[] calcVerifierHash = sha1.digest(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte decryptedVerifierHash[] = cipher.doFinal(encryptedVerifierHash); // see 2.3.4.9 Password Verification (Standard Encryption) // ... The number of bytes used by the encrypted Verifier hash MUST be 32 ... // TODO: check and trim/pad the hashes to 32 byte[] verifierHash = Arrays.copyOf(decryptedVerifierHash, calcVerifierHash.length); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } else { return false; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver); try { Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = new byte[encryptedVerifier.length]; cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); setVerifier(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } return false; }
@Override public boolean verifyPassword(String password) { EncryptionVerifier ver = getEncryptionInfo().getVerifier(); SecretKey skey = generateSecretKey(password, ver); try { Cipher cipher = initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.DECRYPT_MODE); byte encryptedVerifier[] = ver.getEncryptedVerifier(); byte verifier[] = new byte[encryptedVerifier.length]; cipher.update(encryptedVerifier, 0, encryptedVerifier.length, verifier); setVerifier(verifier); byte encryptedVerifierHash[] = ver.getEncryptedVerifierHash(); byte verifierHash[] = cipher.doFinal(encryptedVerifierHash); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); if (Arrays.equals(calcVerifierHash, verifierHash)) { setSecretKey(skey); return true; } } catch (GeneralSecurityException e) { throw new EncryptedDocumentException(e); } return false; }