Search in sources :

Example 1 with EncryptedDocumentException

use of org.apache.poi.EncryptedDocumentException in project poi by apache.

the class FilePassRecord method serialize.

@SuppressWarnings("resource")
@Override
public void serialize(LittleEndianOutput out) {
    out.writeShort(encryptionType);
    byte[] data = new byte[1024];
    // NOSONAR
    LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0);
    switch(encryptionInfo.getEncryptionMode()) {
        case xor:
            ((XOREncryptionHeader) encryptionInfo.getHeader()).write(bos);
            ((XOREncryptionVerifier) encryptionInfo.getVerifier()).write(bos);
            break;
        case binaryRC4:
            out.writeShort(encryptionInfo.getVersionMajor());
            out.writeShort(encryptionInfo.getVersionMinor());
            ((BinaryRC4EncryptionHeader) encryptionInfo.getHeader()).write(bos);
            ((BinaryRC4EncryptionVerifier) encryptionInfo.getVerifier()).write(bos);
            break;
        case cryptoAPI:
            out.writeShort(encryptionInfo.getVersionMajor());
            out.writeShort(encryptionInfo.getVersionMinor());
            out.writeInt(encryptionInfo.getEncryptionFlags());
            ((CryptoAPIEncryptionHeader) encryptionInfo.getHeader()).write(bos);
            ((CryptoAPIEncryptionVerifier) encryptionInfo.getVerifier()).write(bos);
            break;
        default:
            throw new EncryptedDocumentException("not supported");
    }
    out.write(data, 0, bos.getWriteIndex());
}
Also used : CryptoAPIEncryptionVerifier(org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionVerifier) LittleEndianByteArrayOutputStream(org.apache.poi.util.LittleEndianByteArrayOutputStream) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) CryptoAPIEncryptionHeader(org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionHeader) XOREncryptionHeader(org.apache.poi.poifs.crypt.xor.XOREncryptionHeader) BinaryRC4EncryptionVerifier(org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4EncryptionVerifier) XOREncryptionVerifier(org.apache.poi.poifs.crypt.xor.XOREncryptionVerifier) BinaryRC4EncryptionHeader(org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4EncryptionHeader)

Example 2 with EncryptedDocumentException

use of org.apache.poi.EncryptedDocumentException in project poi by apache.

the class StandardDecryptor method verifyPassword.

@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);
    }
}
Also used : EncryptionVerifier(org.apache.poi.poifs.crypt.EncryptionVerifier) SecretKey(javax.crypto.SecretKey) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) GeneralSecurityException(java.security.GeneralSecurityException) Cipher(javax.crypto.Cipher) MessageDigest(java.security.MessageDigest)

Example 3 with EncryptedDocumentException

use of org.apache.poi.EncryptedDocumentException in project poi by apache.

the class CryptoAPIDocumentInputStream method read.

@Override
public synchronized int read() {
    int ch = super.read();
    if (ch == -1) {
        return -1;
    }
    oneByte[0] = (byte) ch;
    try {
        cipher.update(oneByte, 0, 1, oneByte);
    } catch (ShortBufferException e) {
        throw new EncryptedDocumentException(e);
    }
    return oneByte[0];
}
Also used : EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) ShortBufferException(javax.crypto.ShortBufferException)

Example 4 with EncryptedDocumentException

use of org.apache.poi.EncryptedDocumentException in project poi by apache.

the class SlideShowFactory method createSlideShow.

protected static SlideShow<?, ?> createSlideShow(String factoryClass, Object[] args) throws IOException, EncryptedDocumentException {
    try {
        Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(factoryClass);
        Class<?>[] argsClz = new Class<?>[args.length];
        int i = 0;
        for (Object o : args) {
            Class<?> c = o.getClass();
            if (Boolean.class.isAssignableFrom(c)) {
                c = boolean.class;
            } else if (InputStream.class.isAssignableFrom(c)) {
                c = InputStream.class;
            }
            argsClz[i++] = c;
        }
        Method m = clazz.getMethod("createSlideShow", argsClz);
        return (SlideShow<?, ?>) m.invoke(null, args);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof IOException) {
            throw (IOException) t;
        } else if (t instanceof EncryptedDocumentException) {
            throw (EncryptedDocumentException) t;
        } else if (t instanceof OldFileFormatException) {
            throw (OldFileFormatException) t;
        } else {
            throw new IOException(t);
        }
    } catch (Exception e) {
        throw new IOException(e);
    }
}
Also used : EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) PushbackInputStream(java.io.PushbackInputStream) InputStream(java.io.InputStream) OldFileFormatException(org.apache.poi.OldFileFormatException) Method(java.lang.reflect.Method) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) OfficeXmlFileException(org.apache.poi.poifs.filesystem.OfficeXmlFileException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) InvocationTargetException(java.lang.reflect.InvocationTargetException) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) OldFileFormatException(org.apache.poi.OldFileFormatException)

Example 5 with EncryptedDocumentException

use of org.apache.poi.EncryptedDocumentException in project poi by apache.

the class AgileEncryptor method confirmPassword.

@Override
public void confirmPassword(String password, byte[] keySpec, byte[] keySalt, byte[] verifier, byte[] verifierSalt, byte[] integritySalt) {
    AgileEncryptionVerifier ver = (AgileEncryptionVerifier) getEncryptionInfo().getVerifier();
    AgileEncryptionHeader header = (AgileEncryptionHeader) getEncryptionInfo().getHeader();
    ver.setSalt(verifierSalt);
    header.setKeySalt(keySalt);
    int blockSize = header.getBlockSize();
    pwHash = hashPassword(password, ver.getHashAlgorithm(), verifierSalt, ver.getSpinCount());
    /**
         * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps:
         * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize
         *    attribute.
         * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
         *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
         *    consisting of the following bytes: 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, and 0x79.
         * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
         *    attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
         *    integral multiple of blockSize bytes, pad the array with 0x00 to the next integral multiple of
         *    blockSize bytes.
         * 4. Use base64 to encode the result of step 3.
         */
    byte[] encryptedVerifier = hashInput(ver, pwHash, kVerifierInputBlock, verifier, Cipher.ENCRYPT_MODE);
    ver.setEncryptedVerifier(encryptedVerifier);
    /**
         * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps:
         * 1. Obtain the hash value of the random array of bytes generated in step 1 of the steps for
         *    encryptedVerifierHashInput.
         * 2. Generate an encryption key as specified in section 2.3.4.11 by using the user-supplied password,
         *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
         *    consisting of the following bytes: 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, and 0x4e.
         * 3. Encrypt the hash value obtained in step 1 by using the binary form of the saltValue attribute as
         *    an initialization vector as specified in section 2.3.4.12. If hashSize is not an integral multiple of
         *    blockSize bytes, pad the hash value with 0x00 to an integral multiple of blockSize bytes.
         * 4. Use base64 to encode the result of step 3.
         */
    MessageDigest hashMD = getMessageDigest(ver.getHashAlgorithm());
    byte[] hashedVerifier = hashMD.digest(verifier);
    byte[] encryptedVerifierHash = hashInput(ver, pwHash, kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE);
    ver.setEncryptedVerifierHash(encryptedVerifierHash);
    /**
         * encryptedKeyValue: This attribute MUST be generated by using the following steps:
         * 1. Generate a random array of bytes that is the same size as specified by the
         *    Encryptor.KeyData.keyBits attribute of the parent element.
         * 2. Generate an encryption key as specified in section 2.3.4.11, using the user-supplied password,
         *    the binary byte array used to create the saltValue attribute, and a blockKey byte array
         *    consisting of the following bytes: 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, and 0xd6.
         * 3. Encrypt the random array of bytes generated in step 1 by using the binary form of the saltValue
         *    attribute as an initialization vector as specified in section 2.3.4.12. If the array of bytes is not an
         *    integral multiple of blockSize bytes, pad the array with 0x00 to an integral multiple of
         *    blockSize bytes.
         * 4. Use base64 to encode the result of step 3.
         */
    byte[] encryptedKey = hashInput(ver, pwHash, kCryptoKeyBlock, keySpec, Cipher.ENCRYPT_MODE);
    ver.setEncryptedKey(encryptedKey);
    SecretKey secretKey = new SecretKeySpec(keySpec, header.getCipherAlgorithm().jceId);
    setSecretKey(secretKey);
    /*
         * 2.3.4.14 DataIntegrity Generation (Agile Encryption)
         * 
         * The DataIntegrity element contained within an Encryption element MUST be generated by using
         * the following steps:
         * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor
         *    contained within the KeyEncryptors sequence. Use this key for encryption operations in the
         *    remaining steps of this section.
         * 2. Generate a random array of bytes, known as Salt, of the same length as the value of the
         *    KeyData.hashSize attribute.
         * 3. Encrypt the random array of bytes generated in step 2 by using the binary form of the
         *    KeyData.saltValue attribute and a blockKey byte array consisting of the following bytes:
         *    0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, and 0xf6 used to form an initialization vector as
         *    specified in section 2.3.4.12. If the array of bytes is not an integral multiple of blockSize
         *    bytes, pad the array with 0x00 to the next integral multiple of blockSize bytes.
         * 4. Assign the encryptedHmacKey attribute to the base64-encoded form of the result of step 3.
         * 5. 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.
         * 6. 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.
         * 7.  Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6. 
         */
    this.integritySalt = integritySalt.clone();
    try {
        byte[] vec = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityKeyBlock, header.getBlockSize());
        Cipher cipher = getCipher(secretKey, header.getCipherAlgorithm(), header.getChainingMode(), vec, Cipher.ENCRYPT_MODE);
        byte[] hmacKey = getBlock0(this.integritySalt, getNextBlockSize(this.integritySalt.length, blockSize));
        byte[] encryptedHmacKey = cipher.doFinal(hmacKey);
        header.setEncryptedHmacKey(encryptedHmacKey);
        cipher = Cipher.getInstance("RSA");
        for (AgileCertificateEntry ace : ver.getCertificates()) {
            cipher.init(Cipher.ENCRYPT_MODE, ace.x509.getPublicKey());
            ace.encryptedKey = cipher.doFinal(getSecretKey().getEncoded());
            Mac x509Hmac = CryptoFunctions.getMac(header.getHashAlgorithm());
            x509Hmac.init(getSecretKey());
            ace.certVerifier = x509Hmac.doFinal(ace.x509.getEncoded());
        }
    } catch (GeneralSecurityException e) {
        throw new EncryptedDocumentException(e);
    }
}
Also used : AgileCertificateEntry(org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier.AgileCertificateEntry) SecretKey(javax.crypto.SecretKey) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) GeneralSecurityException(java.security.GeneralSecurityException) Cipher(javax.crypto.Cipher) CryptoFunctions.getCipher(org.apache.poi.poifs.crypt.CryptoFunctions.getCipher) MessageDigest(java.security.MessageDigest) CryptoFunctions.getMessageDigest(org.apache.poi.poifs.crypt.CryptoFunctions.getMessageDigest) Mac(javax.crypto.Mac)

Aggregations

EncryptedDocumentException (org.apache.poi.EncryptedDocumentException)33 GeneralSecurityException (java.security.GeneralSecurityException)16 Cipher (javax.crypto.Cipher)10 SecretKey (javax.crypto.SecretKey)9 MessageDigest (java.security.MessageDigest)8 IOException (java.io.IOException)6 HashAlgorithm (org.apache.poi.poifs.crypt.HashAlgorithm)4 LittleEndianByteArrayOutputStream (org.apache.poi.util.LittleEndianByteArrayOutputStream)4 Test (org.junit.Test)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 FileNotFoundException (java.io.FileNotFoundException)2 DigestException (java.security.DigestException)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 NavigableMap (java.util.NavigableMap)2 NoSuchElementException (java.util.NoSuchElementException)2 TreeMap (java.util.TreeMap)2 SecretKeySpec (javax.crypto.spec.SecretKeySpec)2 PersistPtrHolder (org.apache.poi.hslf.record.PersistPtrHolder)2 PositionDependentRecord (org.apache.poi.hslf.record.PositionDependentRecord)2