mirror of https://github.com/apache/poi.git
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
This commit is contained in:
parent
c0f9e375e0
commit
5adfec1810
|
@ -27,8 +27,8 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import org.apache.poi.EncryptedDocumentException;
|
import org.apache.poi.EncryptedDocumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Maxim Valyanskiy
|
* Reads and processes OOXML Encryption Headers
|
||||||
* @author Gary King
|
* 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;
|
||||||
|
@ -36,7 +36,11 @@ public class EncryptionHeader {
|
||||||
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;
|
||||||
|
@ -112,9 +116,9 @@ public class EncryptionHeader {
|
||||||
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();
|
||||||
|
@ -124,16 +128,28 @@ public class EncryptionHeader {
|
||||||
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")
|
||||||
|
|
|
@ -37,9 +37,24 @@ public class TestEncryptionInfo extends TestCase {
|
||||||
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());
|
||||||
|
}
|
||||||
|
|
||||||
assertEquals(32, info.getVerifier().getVerifierHash().length);
|
public void testEncryptionInfoSHA512() throws Exception {
|
||||||
|
POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_sha512.xlsx"));
|
||||||
|
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue