我无法将带有2048位密钥的证书添加到Bouncy Castle KeyStore。我使用UnlimitedJCEPolicyJDK7.zip更新了我的JCE版本,包括JRE和JDK安全文件夹。下面的代码表示错误位置。我正在使用bcprov-jdk15on-149,但尝试了bcprov-jdk15on-157,结果相同。关于对称加密问题有很多帖子,但PKE上的帖子较少。我正在运行Windows 10 Pro,JRE 7,JDK 1.7.0_51。我很感激任何建议。
char[] testPass = "changeit".toCharArray();
String testAlias = "express";
// -----------------------------------------------------------------
// Open source TrustStore and extract certificate and key
FileInputStream jksFis = new FileInputStream("G:\\testSrc.jks");
KeyStore jksKS = KeyStore.getInstance(KeyStore.getDefaultType());
jksKS.load(jksFis, testPass);
PrivateKey jksPK = (PrivateKey) jksKS.getKey(testAlias,testPass);
RSAKey rsaKey = (RSAKey)jksPK;
int rsaKeyLen = rsaKey.getModulus().bitLength();
System.out.printf("Key length is %d\n",rsaKeyLen); // 2048
X509Certificate[] jksCerts = new X509Certificate[1];
jksCerts[0] = (X509Certificate) jksKS.getCertificate(testAlias);
// -----------------------------------------------------------------
// Create new default type keystore and add certificate and key.
KeyStore jksDest = KeyStore.getInstance(KeyStore.getDefaultType());
jksDest.load(null,null);
jksDest.setKeyEntry(testAlias, jksPK, testPass, jksCerts);
FileOutputStream jfos = new FileOutputStream("G:\\testDest.jks");
jksDest.store(jfos, testPass);
jfos.close();
// -----------------------------------------------------------------
// Create Bouncy Castle KeyStore and add certificate and key
Security.addProvider(new BouncyCastleProvider());
KeyStore bksKS = KeyStore.getInstance("PKCS12","BC");
bksKS.load(null,null);
bksKS.setKeyEntry(testAlias, jksPK, testPass, jksCerts);
FileOutputStream bksFos = new FileOutputStream("G:\\testDest.bks");
// -----------------------------------------------------------------
// Next line gives this error:
// java.io.IOException: exception encrypting data -
// java.security.InvalidKeyException: Illegal key size
bksKS.store(bksFos, testPass); // This is the error line.
// Error on previous line.
答案 0 :(得分:0)
安装JCE更新的过程看起来非常简单,因此我对I版本使用的一个假设可能是错误的。正如Omikron在其有用的评论中所指出的那样,无论如何都不应该重要。他确实让我朝着正确的方向前进,这导致了解决方案。我在下面发布修改后的代码。我不确定为什么默认密钥库类型首先起作用,而且充气城堡没有。也许熟悉bouncycastle的人会分享他们的想法。与此同时,我也想看看它是否适用于Android。
public static void main(String[] args) {
try{
// -----------------------------------------------------------------
// Anonymous recommendation I found here:
// http://suhothayan.blogspot.com/2012/05/how-to-install-java-cryptography.html
// This fixed my problem.
try {
Field field = Class.forName("javax.crypto.JceSecurity").
getDeclaredField("isRestricted");
field.setAccessible(true);
field.set(null, java.lang.Boolean.FALSE);
} catch (Exception ex) {
ex.printStackTrace();
}
// -----------------------------------------------------------------
// Check recommended by Omikron, who was correct: I assume I didn't
// install the JCE properly because it prints 128 for the max
// key allowd key length.
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
System.out.printf("max key len: %d\n",maxKeyLen);
// -----------------------------------------------------------------
char[] testPass = "changeit".toCharArray();
String testAlias = "express";
// -----------------------------------------------------------------
// Open source TrustStore and extract certificate and key
FileInputStream jksFis = new FileInputStream("G:\\testSrc.jks");
KeyStore jksKS = KeyStore.getInstance(KeyStore.getDefaultType());
jksKS.load(jksFis, testPass);
PrivateKey jksPK = (PrivateKey) jksKS.getKey(testAlias,testPass);
RSAKey rsaKey = (RSAKey)jksPK;
int rsaKeyLen = rsaKey.getModulus().bitLength();
System.out.printf("JKS key length is %d\n",rsaKeyLen); // 2048
X509Certificate[] jksCerts = new X509Certificate[1];
jksCerts[0] = (X509Certificate) jksKS.getCertificate(testAlias);
// -----------------------------------------------------------------
// Create new default type keystore and add certificate and key.
KeyStore jksDest = KeyStore.getInstance(KeyStore.getDefaultType());
jksDest.load(null,null);
jksDest.setKeyEntry(testAlias, jksPK, testPass, jksCerts);
FileOutputStream jfos = new FileOutputStream("G:\\testDest.jks");
jksDest.store(jfos, testPass);
jfos.close();
// -----------------------------------------------------------------
// Create Bouncy Castle KeyStore and add certificate and key
Security.addProvider(new BouncyCastleProvider());
KeyStore bksKS = KeyStore.getInstance("PKCS12","BC");
bksKS.load(null,null);
bksKS.setKeyEntry(testAlias, jksPK, testPass, jksCerts);
FileOutputStream bksFos = new FileOutputStream("G:\\testDest.bks");
bksKS.store(bksFos, testPass);
bksFos.close();
// -------------------------
// Open file and check key length:
bksKS = KeyStore.getInstance("PKCS12","BC");
FileInputStream bksFis = new FileInputStream("G:\\testDest.bks");
bksKS.load(bksFis, testPass);
PrivateKey bpk = (PrivateKey) bksKS.getKey(testAlias,testPass);
rsaKey = (RSAKey)bpk;
rsaKeyLen = rsaKey.getModulus().bitLength();
System.out.printf("BKS key length is %d\n",rsaKeyLen); // 2048
X509Certificate bkCert = (X509Certificate) bksKS.getCertificate(testAlias);
System.out.printf("Issuer name: %s", bkCert.getIssuerDN().getName());
}catch(Exception e){
e.printStackTrace();
}
}