2017-06-17 28 views
0

我无法添加带有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。我会很感激任何建议。InvalidKeyException:非法密钥大小保存BouncyCastle但不是默认提供程序公钥

 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. 
+1

的RSA密钥长度是不是这里的问题,也被用于密钥库的加密在Java 7 RSA密钥长度,但对称密钥没有限制,而这些都是为JKS和PKCS12不同。只是为了确保:在你的代码中添加一个支票来实现无限的强度策略,像这样:https://stackoverflow.com/a/11541337/2672392 – Omikron

+0

非常感谢,Omikron。我跟随你的链接,并在我的回答下面的问题的结果更改发布到代码。 – Will

回答

0

安装JCE更新的过程看起来非常简单,所以我对我使用的版本的一些假设可能是错误的。正如Omikron在他有用的评论中指出的那样,它不应该是无关紧要的。他的确让我朝着正确的方向前进,从而导致了解决方案。我在下面发布修改后的代码。我不确定为什么默认的keystore类型在第一位工作,而弹性城堡没有。也许有人熟悉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(); 
    } 
}