Search in sources :

Example 1 with HashAlgorithm

use of org.apache.poi.poifs.crypt.HashAlgorithm 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)

Example 2 with HashAlgorithm

use of org.apache.poi.poifs.crypt.HashAlgorithm in project poi by apache.

the class AgileDecryptor method verifyPassword.

/**
     * instead of a password, it's also possible to decrypt via certificate.
     * Warning: this code is experimental and hasn't been validated
     * 
     * @see <a href="http://social.msdn.microsoft.com/Forums/en-US/cc9092bb-0c82-4b5b-ae21-abf643bdb37c/agile-encryption-with-certificates">Agile encryption with certificates</a>
     *
     * @param keyPair
     * @param x509
     * @return true, when the data can be successfully decrypted with the given private key
     * @throws GeneralSecurityException
     */
public boolean verifyPassword(KeyPair keyPair, X509Certificate x509) throws GeneralSecurityException {
    AgileEncryptionVerifier ver = (AgileEncryptionVerifier) getEncryptionInfo().getVerifier();
    AgileEncryptionHeader header = (AgileEncryptionHeader) getEncryptionInfo().getHeader();
    HashAlgorithm hashAlgo = header.getHashAlgorithm();
    CipherAlgorithm cipherAlgo = header.getCipherAlgorithm();
    int blockSize = header.getBlockSize();
    AgileCertificateEntry ace = null;
    for (AgileCertificateEntry aceEntry : ver.getCertificates()) {
        if (x509.equals(aceEntry.x509)) {
            ace = aceEntry;
            break;
        }
    }
    if (ace == null) {
        return false;
    }
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
    byte[] keyspec = cipher.doFinal(ace.encryptedKey);
    SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.getCipherAlgorithm().jceId);
    Mac x509Hmac = CryptoFunctions.getMac(hashAlgo);
    x509Hmac.init(secretKey);
    byte[] certVerifier = x509Hmac.doFinal(ace.x509.getEncoded());
    byte[] vec = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityKeyBlock, blockSize);
    cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE);
    byte[] hmacKey = cipher.doFinal(header.getEncryptedHmacKey());
    hmacKey = getBlock0(hmacKey, hashAlgo.hashSize);
    vec = CryptoFunctions.generateIv(hashAlgo, header.getKeySalt(), kIntegrityValueBlock, blockSize);
    cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE);
    byte[] hmacValue = cipher.doFinal(header.getEncryptedHmacValue());
    hmacValue = getBlock0(hmacValue, hashAlgo.hashSize);
    if (Arrays.equals(ace.certVerifier, certVerifier)) {
        setSecretKey(secretKey);
        setIntegrityHmacKey(hmacKey);
        setIntegrityHmacValue(hmacValue);
        return true;
    } else {
        return false;
    }
}
Also used : CipherAlgorithm(org.apache.poi.poifs.crypt.CipherAlgorithm) AgileCertificateEntry(org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry) SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) CryptoFunctions.getCipher(org.apache.poi.poifs.crypt.CryptoFunctions.getCipher) Mac(javax.crypto.Mac) HashAlgorithm(org.apache.poi.poifs.crypt.HashAlgorithm)

Example 3 with HashAlgorithm

use of org.apache.poi.poifs.crypt.HashAlgorithm in project poi by apache.

the class XSSFPasswordHelper method validatePassword.

/**
     * Validates the password, i.e.
     * calculates the hash of the given password and compares it against the stored hash
     *
     * @param xobj the xmlbeans object which contains the password attributes
     * @param password the password, if null the method will always return false,
     *  even if there's no password set
     * @param prefix the prefix of the password attributes, may be null
     * 
     * @return true, if the hashes match
     */
public static boolean validatePassword(XmlObject xobj, String password, String prefix) {
    // TODO: is "velvetSweatshop" the default password?
    if (password == null)
        return false;
    XmlCursor cur = xobj.newCursor();
    String xorHashVal = cur.getAttributeText(getAttrName(prefix, "password"));
    String algoName = cur.getAttributeText(getAttrName(prefix, "algorithmName"));
    String hashVal = cur.getAttributeText(getAttrName(prefix, "hashValue"));
    String saltVal = cur.getAttributeText(getAttrName(prefix, "saltValue"));
    String spinCount = cur.getAttributeText(getAttrName(prefix, "spinCount"));
    cur.dispose();
    if (xorHashVal != null) {
        int hash1 = Integer.parseInt(xorHashVal, 16);
        int hash2 = CryptoFunctions.createXorVerifier1(password);
        return hash1 == hash2;
    } else {
        if (hashVal == null || algoName == null || saltVal == null || spinCount == null) {
            return false;
        }
        byte[] hash1 = DatatypeConverter.parseBase64Binary(hashVal);
        HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName);
        byte[] salt = DatatypeConverter.parseBase64Binary(saltVal);
        int spinCnt = Integer.parseInt(spinCount);
        byte[] hash2 = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false);
        return Arrays.equals(hash1, hash2);
    }
}
Also used : XmlCursor(org.apache.xmlbeans.XmlCursor) HashAlgorithm(org.apache.poi.poifs.crypt.HashAlgorithm)

Example 4 with HashAlgorithm

use of org.apache.poi.poifs.crypt.HashAlgorithm in project poi by apache.

the class StandardDecryptor method generateSecretKey.

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);
    SecretKey skey = new SecretKeySpec(key, ver.getCipherAlgorithm().jceId);
    return skey;
}
Also used : SecretKey(javax.crypto.SecretKey) SecretKeySpec(javax.crypto.spec.SecretKeySpec) HashAlgorithm(org.apache.poi.poifs.crypt.HashAlgorithm)

Example 5 with HashAlgorithm

use of org.apache.poi.poifs.crypt.HashAlgorithm in project poi by apache.

the class AgileDecryptor method hashInput.

/* package */
static byte[] hashInput(AgileEncryptionVerifier ver, byte[] pwHash, byte[] blockKey, byte[] inputKey, int cipherMode) {
    CipherAlgorithm cipherAlgo = ver.getCipherAlgorithm();
    ChainingMode chainMode = ver.getChainingMode();
    int keySize = ver.getKeySize() / 8;
    int blockSize = ver.getBlockSize();
    HashAlgorithm hashAlgo = ver.getHashAlgorithm();
    byte[] intermedKey = generateKey(pwHash, hashAlgo, blockKey, keySize);
    SecretKey skey = new SecretKeySpec(intermedKey, cipherAlgo.jceId);
    byte[] iv = generateIv(hashAlgo, ver.getSalt(), null, blockSize);
    Cipher cipher = getCipher(skey, cipherAlgo, chainMode, iv, cipherMode);
    byte[] hashFinal;
    try {
        inputKey = getBlock0(inputKey, getNextBlockSize(inputKey.length, blockSize));
        hashFinal = cipher.doFinal(inputKey);
        return hashFinal;
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
}
Also used : CipherAlgorithm(org.apache.poi.poifs.crypt.CipherAlgorithm) SecretKey(javax.crypto.SecretKey) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) ChainingMode(org.apache.poi.poifs.crypt.ChainingMode) SecretKeySpec(javax.crypto.spec.SecretKeySpec) GeneralSecurityException(java.security.GeneralSecurityException) Cipher(javax.crypto.Cipher) CryptoFunctions.getCipher(org.apache.poi.poifs.crypt.CryptoFunctions.getCipher) HashAlgorithm(org.apache.poi.poifs.crypt.HashAlgorithm)

Aggregations

HashAlgorithm (org.apache.poi.poifs.crypt.HashAlgorithm)11 SecretKey (javax.crypto.SecretKey)7 Cipher (javax.crypto.Cipher)6 SecretKeySpec (javax.crypto.spec.SecretKeySpec)6 MessageDigest (java.security.MessageDigest)5 GeneralSecurityException (java.security.GeneralSecurityException)4 EncryptedDocumentException (org.apache.poi.EncryptedDocumentException)4 CryptoFunctions.getCipher (org.apache.poi.poifs.crypt.CryptoFunctions.getCipher)3 Mac (javax.crypto.Mac)2 CipherAlgorithm (org.apache.poi.poifs.crypt.CipherAlgorithm)2 EncryptionVerifier (org.apache.poi.poifs.crypt.EncryptionVerifier)2 STHashAlgorithm (com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm)1 FileInputStream (java.io.FileInputStream)1 InputStream (java.io.InputStream)1 BigInteger (java.math.BigInteger)1 ChainingMode (org.apache.poi.poifs.crypt.ChainingMode)1 EncryptionHeader (org.apache.poi.poifs.crypt.EncryptionHeader)1 AgileCertificateEntry (org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry)1 XmlCursor (org.apache.xmlbeans.XmlCursor)1