Search in sources :

Example 1 with CryptoFunctions.getCipher

use of org.apache.poi.poifs.crypt.CryptoFunctions.getCipher in project poi by apache.

the class AgileEncryptor method updateIntegrityHMAC.

/**
     * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), 
     * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. 
     * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be 
     * used as the message.
     * 
     * Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes:
     * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33.
     **/
protected void updateIntegrityHMAC(File tmpFile, int oleStreamSize) throws GeneralSecurityException, IOException {
    // as the integrity hmac needs to contain the StreamSize,
    // it's not possible to calculate it on-the-fly while buffering
    // TODO: add stream size parameter to getDataStream()
    AgileEncryptionHeader header = (AgileEncryptionHeader) getEncryptionInfo().getHeader();
    int blockSize = header.getBlockSize();
    HashAlgorithm hashAlgo = header.getHashAlgorithm();
    Mac integrityMD = CryptoFunctions.getMac(hashAlgo);
    byte[] hmacKey = getBlock0(this.integritySalt, getNextBlockSize(this.integritySalt.length, blockSize));
    integrityMD.init(new SecretKeySpec(hmacKey, hashAlgo.jceHmacId));
    byte[] buf = new byte[1024];
    LittleEndian.putLong(buf, 0, oleStreamSize);
    integrityMD.update(buf, 0, LittleEndianConsts.LONG_SIZE);
    InputStream fis = new FileInputStream(tmpFile);
    try {
        int readBytes;
        while ((readBytes = fis.read(buf)) != -1) {
            integrityMD.update(buf, 0, readBytes);
        }
    } finally {
        fis.close();
    }
    byte[] hmacValue = integrityMD.doFinal();
    byte[] hmacValueFilled = getBlock0(hmacValue, getNextBlockSize(hmacValue.length, blockSize));
    byte[] iv = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityValueBlock, blockSize);
    Cipher cipher = CryptoFunctions.getCipher(getSecretKey(), header.getCipherAlgorithm(), header.getChainingMode(), iv, Cipher.ENCRYPT_MODE);
    byte[] encryptedHmacValue = cipher.doFinal(hmacValueFilled);
    header.setEncryptedHmacValue(encryptedHmacValue);
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) Cipher(javax.crypto.Cipher) CryptoFunctions.getCipher(org.apache.poi.poifs.crypt.CryptoFunctions.getCipher) Mac(javax.crypto.Mac) FileInputStream(java.io.FileInputStream) STHashAlgorithm(com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm) HashAlgorithm(org.apache.poi.poifs.crypt.HashAlgorithm)

Aggregations

STHashAlgorithm (com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm)1 FileInputStream (java.io.FileInputStream)1 InputStream (java.io.InputStream)1 Cipher (javax.crypto.Cipher)1 Mac (javax.crypto.Mac)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 CryptoFunctions.getCipher (org.apache.poi.poifs.crypt.CryptoFunctions.getCipher)1 HashAlgorithm (org.apache.poi.poifs.crypt.HashAlgorithm)1