Browse Source

Support more hashing formats for OOXML protected documents, for bug #55544

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1522074 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_10_FINAL
Nick Burch 10 years ago
parent
commit
5adfec1810

+ 24
- 8
src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java View File

import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;


/** /**
* @author Maxim Valyanskiy
* @author Gary King
* Reads and processes OOXML Encryption Headers
* The constants are largely based on ZIP constants.
*/ */
public class EncryptionHeader { public class EncryptionHeader {
public static final int ALGORITHM_RC4 = 0x6801; public static final int ALGORITHM_RC4 = 0x6801;
public static final int ALGORITHM_AES_192 = 0x660F; public static final int ALGORITHM_AES_192 = 0x660F;
public static final int ALGORITHM_AES_256 = 0x6610; public static final int ALGORITHM_AES_256 = 0x6610;


public static final int HASH_NONE = 0x0000;
public static final int HASH_SHA1 = 0x8004; public static final int HASH_SHA1 = 0x8004;
public static final int HASH_SHA256 = 0x800C;
public static final int HASH_SHA384 = 0x800D;
public static final int HASH_SHA512 = 0x800E;


public static final int PROVIDER_RC4 = 1; public static final int PROVIDER_RC4 = 1;
public static final int PROVIDER_AES = 0x18; public static final int PROVIDER_AES = 0x18;
else if (blockSize == 32) else if (blockSize == 32)
algorithm = ALGORITHM_AES_256; algorithm = ALGORITHM_AES_256;
else else
throw new EncryptedDocumentException("Unsupported key length");
throw new EncryptedDocumentException("Unsupported key length " + blockSize);
} else { } else {
throw new EncryptedDocumentException("Unsupported cipher");
throw new EncryptedDocumentException("Unsupported cipher " + cipher);
} }


String chaining = keyData.getNamedItem("cipherChaining").getNodeValue(); String chaining = keyData.getNamedItem("cipherChaining").getNodeValue();
else if ("ChainingModeCFB".equals(chaining)) else if ("ChainingModeCFB".equals(chaining))
cipherMode = MODE_CFB; cipherMode = MODE_CFB;
else else
throw new EncryptedDocumentException("Unsupported chaining mode");
throw new EncryptedDocumentException("Unsupported chaining mode " + chaining);


String hashAlg = keyData.getNamedItem("hashAlgorithm").getNodeValue(); String hashAlg = keyData.getNamedItem("hashAlgorithm").getNodeValue();
int hashSize = Integer.parseInt(keyData.getNamedItem("hashSize") int hashSize = Integer.parseInt(keyData.getNamedItem("hashSize")
.getNodeValue()); .getNodeValue());


if ("SHA1".equals(hashAlg) && hashSize == 20)
if ("SHA1".equals(hashAlg) && hashSize == 20) {
hashAlgorithm = HASH_SHA1; hashAlgorithm = HASH_SHA1;
else
throw new EncryptedDocumentException("Unsupported hash algorithm");
}
else if ("SHA256".equals(hashAlg) && hashSize == 32) {
hashAlgorithm = HASH_SHA256;
}
else if ("SHA384".equals(hashAlg) && hashSize == 64) {
hashAlgorithm = HASH_SHA384;
}
else if ("SHA512".equals(hashAlg) && hashSize == 64) {
hashAlgorithm = HASH_SHA512;
}
else {
throw new EncryptedDocumentException("Unsupported hash algorithm: " +
hashAlg + " @ " + hashSize + " bytes");
}


String salt = keyData.getNamedItem("saltValue").getNodeValue(); String salt = keyData.getNamedItem("saltValue").getNodeValue();
int saltLength = Integer.parseInt(keyData.getNamedItem("saltSize") int saltLength = Integer.parseInt(keyData.getNamedItem("saltSize")

+ 16
- 1
src/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java View File

assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm()); assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm());
assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm()); assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm());
assertEquals(128, info.getHeader().getKeySize()); assertEquals(128, info.getHeader().getKeySize());
assertEquals(32, info.getVerifier().getVerifierHash().length);
assertEquals(EncryptionHeader.PROVIDER_AES, info.getHeader().getProviderType()); assertEquals(EncryptionHeader.PROVIDER_AES, info.getHeader().getProviderType());
assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName()); assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName());
}
public void testEncryptionInfoSHA512() throws Exception {
POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_sha512.xlsx"));


assertEquals(32, info.getVerifier().getVerifierHash().length);
EncryptionInfo info = new EncryptionInfo(fs);

assertEquals(4, info.getVersionMajor());
assertEquals(4, info.getVersionMinor());

assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm());
assertEquals(EncryptionHeader.HASH_SHA512, info.getHeader().getHashAlgorithm());
assertEquals(256, info.getHeader().getKeySize());
assertEquals(64, info.getVerifier().getVerifierHash().length);
assertEquals(EncryptionHeader.PROVIDER_AES, info.getHeader().getProviderType());
// assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName());
} }
} }

test-data/openxml4j/EncryptedSHA512.xlsx → test-data/poifs/protected_sha512.xlsx View File


Loading…
Cancel
Save