JCE policy fix

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1553342 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
kiwiwings 2013-12-25 01:04:29 +00:00
parent 82958a11cb
commit 3a36da330a
6 changed files with 43 additions and 5 deletions

View File

@ -22,12 +22,14 @@ import java.security.GeneralSecurityException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.Provider; import java.security.Provider;
import java.security.Security; import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays; import java.util.Arrays;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -188,8 +190,13 @@ public class CryptoFunctions {
if (vec == null) { if (vec == null) {
cipher.init(cipherMode, key); cipher.init(cipherMode, key);
} else { } else {
IvParameterSpec iv = new IvParameterSpec(vec); AlgorithmParameterSpec aps;
cipher.init(cipherMode, key, iv); if (cipherAlgorithm == CipherAlgorithm.rc2) {
aps = new RC2ParameterSpec(key.getEncoded().length*8, vec);
} else {
aps = new IvParameterSpec(vec);
}
cipher.init(cipherMode, key, aps);
} }
return cipher; return cipher;
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {

View File

@ -29,12 +29,14 @@ import java.security.GeneralSecurityException;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays; import java.util.Arrays;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
@ -383,7 +385,14 @@ public class AgileDecryptor extends Decryptor {
LittleEndian.putInt(blockKey, 0, index); LittleEndian.putInt(blockKey, 0, index);
EncryptionHeader header = info.getHeader(); EncryptionHeader header = info.getHeader();
byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, getBlockSizeInBytes()); byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, getBlockSizeInBytes());
_cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), new IvParameterSpec(iv)); AlgorithmParameterSpec aps;
if (header.getCipherAlgorithm() == CipherAlgorithm.rc2) {
aps = new RC2ParameterSpec(getSecretKey().getEncoded().length*8, iv);
} else {
aps = new IvParameterSpec(iv);
}
_cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), aps);
if (_lastIndex != index) if (_lastIndex != index)
_stream.skip((index - _lastIndex) << 12); _stream.skip((index - _lastIndex) << 12);

View File

@ -41,6 +41,7 @@ import java.security.GeneralSecurityException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -49,9 +50,11 @@ import javax.crypto.Cipher;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import org.apache.poi.EncryptedDocumentException; import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.CipherAlgorithm;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.DataSpaceMapUtils; import org.apache.poi.poifs.crypt.DataSpaceMapUtils;
import org.apache.poi.poifs.crypt.EncryptionHeader; import org.apache.poi.poifs.crypt.EncryptionHeader;
@ -315,7 +318,14 @@ public class AgileEncryptor extends Encryptor {
LittleEndian.putInt(blockKey, 0, index); LittleEndian.putInt(blockKey, 0, index);
byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, blockSize); byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, blockSize);
try { try {
_cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), new IvParameterSpec(iv)); AlgorithmParameterSpec aps;
if (header.getCipherAlgorithm() == CipherAlgorithm.rc2) {
aps = new RC2ParameterSpec(getSecretKey().getEncoded().length*8, iv);
} else {
aps = new IvParameterSpec(iv);
}
_cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), aps);
int ciLen = _cipher.doFinal(_chunk, 0, posInChunk, _chunk); int ciLen = _cipher.doFinal(_chunk, 0, posInChunk, _chunk);
out.write(_chunk, 0, ciLen); out.write(_chunk, 0, ciLen);
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {

View File

@ -28,9 +28,12 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import javax.crypto.Cipher;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.junit.Assume;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -77,6 +80,9 @@ public class TestAgileEncryptionParameters {
@Test @Test
public void testAgileEncryptionModes() throws Exception { public void testAgileEncryptionModes() throws Exception {
int maxKeyLen = Cipher.getMaxAllowedKeyLength(ca.jceId);
Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files", maxKeyLen >= ca.defaultKeySize);
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
POIFSFileSystem fsEnc = new POIFSFileSystem(); POIFSFileSystem fsEnc = new POIFSFileSystem();

View File

@ -157,7 +157,7 @@ public class TestCertificateEncryption {
@Test @Test
public void testCertificateEncryption() throws Exception { public void testCertificateEncryption() throws Exception {
POIFSFileSystem fs = new POIFSFileSystem(); POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha1, -1, -1, ChainingMode.cbc); EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile, CipherAlgorithm.aes128, HashAlgorithm.sha1, -1, -1, ChainingMode.cbc);
AgileEncryptionVerifier aev = (AgileEncryptionVerifier)info.getVerifier(); AgileEncryptionVerifier aev = (AgileEncryptionVerifier)info.getVerifier();
CertData certData = loadKeystore(); CertData certData = loadKeystore();
aev.addCertificate(certData.x509); aev.addCertificate(certData.x509);

View File

@ -30,6 +30,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Iterator; import java.util.Iterator;
import javax.crypto.Cipher;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader; import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader;
import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.DirectoryNode;
@ -39,11 +41,15 @@ import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.BoundedInputStream; import org.apache.poi.util.BoundedInputStream;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.junit.Assume;
import org.junit.Test; import org.junit.Test;
public class TestEncryptor { public class TestEncryptor {
@Test @Test
public void testAgileEncryption() throws Exception { public void testAgileEncryption() throws Exception {
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647);
File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-pass.docx"); File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-pass.docx");
String pass = "pass"; String pass = "pass";
NPOIFSFileSystem nfs = new NPOIFSFileSystem(file); NPOIFSFileSystem nfs = new NPOIFSFileSystem(file);