protected static byte[] fillAndXor(byte hash[], byte fillByte) { byte[] buff = new byte[64]; Arrays.fill(buff, fillByte); for (int i=0; i<hash.length; i++) { buff[i] = (byte) (buff[i] ^ hash[i]); } MessageDigest sha1 = CryptoFunctions.getMessageDigest(HashAlgorithm.sha1); return sha1.digest(buff); }
/** * <p><cite>2.3.4.12 Initialization Vector Generation (Agile Encryption)</cite></p> * * <p>Initialization vectors are used in all cases for agile encryption. An initialization vector MUST be * generated by using the following method, where H() is a hash function that MUST be the same as * specified in section 2.3.4.11 and a plus sign (+) represents concatenation:</p> * <ul> * <li>If a blockKey is provided, let IV be a hash of the KeySalt and the following value:<br> * {@code blockKey: IV = H(KeySalt + blockKey)}</li> * <li>If a blockKey is not provided, let IV be equal to the following value:<br> * {@code KeySalt:IV = KeySalt}</li> * <li>If the number of bytes in the value of IV is less than the the value of the blockSize attribute * corresponding to the cipherAlgorithm attribute, pad the array of bytes by appending 0x36 until * the array is blockSize bytes. If the array of bytes is larger than blockSize bytes, truncate the * array to blockSize bytes.</li> * </ul> **/ public static byte[] generateIv(HashAlgorithm hashAlgorithm, byte[] salt, byte[] blockKey, int blockSize) { byte iv[] = salt; if (blockKey != null) { MessageDigest hashAlgo = getMessageDigest(hashAlgorithm); hashAlgo.update(salt); iv = hashAlgo.digest(blockKey); } return getBlock36(iv, blockSize); }
/** * <p><cite>2.3.4.11 Encryption Key Generation (Agile Encryption)</cite></p> * * <p>The final hash data that is used for an encryption key is then generated by using the following * method:</p> * * <pre>H_final = H(H_n + blockKey)</pre> * * <p>where blockKey represents an array of bytes used to prevent two different blocks from encrypting * to the same cipher text.</p> * * <p>If the size of the resulting H_final is smaller than that of PasswordKeyEncryptor.keyBits, the key * MUST be padded by appending bytes with a value of 0x36. If the hash value is larger in size than * PasswordKeyEncryptor.keyBits, the key is obtained by truncating the hash value.</p> * * @param passwordHash * @param hashAlgorithm * @param blockKey * @param keySize * @return intermediate key */ public static byte[] generateKey(byte[] passwordHash, HashAlgorithm hashAlgorithm, byte[] blockKey, int keySize) { MessageDigest hashAlgo = getMessageDigest(hashAlgorithm); hashAlgo.update(passwordHash); byte[] key = hashAlgo.digest(blockKey); return getBlock36(key, keySize); }
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); }
public void init() throws GeneralSecurityException { if (isMSCapi(key)) { // see https://stackoverflow.com/questions/39196145 for problems with SunMSCAPI // and why we can't sign the calculated digest throw new EncryptedDocumentException( "Windows keystore entries can't be signed with the "+algo+" hash. Please "+ "use one digest algorithm of sha1 / sha256 / sha384 / sha512."); } md = CryptoFunctions.getMessageDigest(algo); }
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); }
MessageDigest hashAlg = getMessageDigest(hashAlgorithm);
/** * Gives back the JAXB DigestAlgAndValue data structure. * * @param digestAlgAndValue the parent for the new digest element * @param data the data to be digested * @param digestAlgo the digest algorithm */ protected static void setDigestAlgAndValue( DigestAlgAndValueType digestAlgAndValue, byte[] data, HashAlgorithm digestAlgo) { DigestMethodType digestMethod = digestAlgAndValue.addNewDigestMethod(); digestMethod.setAlgorithm(SignatureConfig.getDigestMethodUri(digestAlgo)); MessageDigest messageDigest = CryptoFunctions.getMessageDigest(digestAlgo); byte[] digestValue = messageDigest.digest(data); digestAlgAndValue.setDigestValue(digestValue); }
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); 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, 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 void confirmPassword(String password, byte keySpec[], byte keySalt[], byte verifier[], byte verifierSalt[], byte integritySalt[]) { assert(verifier != null && verifierSalt != null); CryptoAPIEncryptionVerifier ver = (CryptoAPIEncryptionVerifier)getEncryptionInfo().getVerifier(); ver.setSalt(verifierSalt); SecretKey skey = CryptoAPIDecryptor.generateSecretKey(password, ver); setSecretKey(skey); try { Cipher cipher = initCipherForBlock(null, 0); byte encryptedVerifier[] = new byte[verifier.length]; cipher.update(verifier, 0, verifier.length, encryptedVerifier); ver.setEncryptedVerifier(encryptedVerifier); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash); ver.setEncryptedVerifierHash(encryptedVerifierHash); } catch (GeneralSecurityException e) { throw new EncryptedDocumentException("Password confirmation failed", e); } }
@Override public void confirmPassword(String password, byte keySpec[], byte keySalt[], byte verifier[], byte verifierSalt[], byte integritySalt[]) { BinaryRC4EncryptionVerifier ver = (BinaryRC4EncryptionVerifier)getEncryptionInfo().getVerifier(); ver.setSalt(verifierSalt); SecretKey skey = BinaryRC4Decryptor.generateSecretKey(password, ver); setSecretKey(skey); try { Cipher cipher = BinaryRC4Decryptor.initCipherForBlock(null, 0, getEncryptionInfo(), skey, Cipher.ENCRYPT_MODE); byte encryptedVerifier[] = new byte[16]; cipher.update(verifier, 0, 16, encryptedVerifier); ver.setEncryptedVerifier(encryptedVerifier); HashAlgorithm hashAlgo = ver.getHashAlgorithm(); MessageDigest hashAlg = CryptoFunctions.getMessageDigest(hashAlgo); byte calcVerifierHash[] = hashAlg.digest(verifier); byte encryptedVerifierHash[] = cipher.doFinal(calcVerifierHash); ver.setEncryptedVerifierHash(encryptedVerifierHash); } catch (GeneralSecurityException e) { throw new EncryptedDocumentException("Password confirmation failed", e); } }
MessageDigest hashAlgo = CryptoFunctions.getMessageDigest(ver.getHashAlgorithm()); byte calcVerifierHash[] = hashAlgo.digest(verifier);
throws Exception { MessageDigest messageDigest = CryptoFunctions.getMessageDigest(signatureConfig.getTspDigestAlgo()); byte[] digest = messageDigest.digest(data);
MessageDigest hashMD = getMessageDigest(ver.getHashAlgorithm()); byte[] hashedVerifier = hashMD.digest(verifier); byte encryptedVerifierHash[] = hashInput(ver, pwHash, kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE);
MessageDigest hashMD = getMessageDigest(ver.getHashAlgorithm()); byte[] verifierHash = hashMD.digest(verfierInputEnc);
/** * Compute 16-byte checksum of this picture using MD5 algorithm. */ public static byte[] getChecksum(byte[] data) { MessageDigest md5 = CryptoFunctions.getMessageDigest(HashAlgorithm.md5); md5.update(data); return md5.digest(); }
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); }