用Bouncy Castle解密PEM私有(RSA)密钥

时间:2015-07-29 16:48:13

标签: java encryption bouncycastle pem jce

目标:从加密的PEM文件中提取RSA私钥。私钥将用于以编程方式签署证书。

环境:Java 8和Bouncy Castle 1.52

使用Bouncy Castle PEMParser(导致PKCSException)

    //Register BC as a crypto provider
    Security.addProvider(new BouncyCastleProvider());

    //Get file handle
    String caPrivateKeyFname = "cakey.pem";
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(caPrivateKeyFname);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    //Load and parse PEM object
    PEMParser pemRd = new PEMParser(new InputStreamReader(fis));
    Object objectInPemFile = pemRd.readObject();

    //I do not know why BC loads the file as a PKCS8 object. OpenSSL does not recognize it as such.
    PKCS8EncryptedPrivateKeyInfo keyInfo = (PKCS8EncryptedPrivateKeyInfo) objectInPemFile;

    //Decrypt the private key
    String pwd = "secret";
    InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(pwd.toCharArray());

    //Next statement raises an exception.
    PrivateKeyInfo privateKeyInfo = keyInfo.decryptPrivateKeyInfo(pkcs8Prov);
Exception in thread "main" org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: Illegal key size
    at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)
    at org.codice.ddf.certificate.SignedCertificate.main(SignedCertificate.java:67)
Caused by: org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.13 not available: Illegal key size
    at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder$1.get(Unknown Source)
    ... 2 more
Caused by: java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1060)
    at javax.crypto.Cipher.implInit(Cipher.java:809)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
    at javax.crypto.Cipher.init(Cipher.java:1539)
    at javax.crypto.Cipher.init(Cipher.java:1470)
    ... 3 more  

*更新*

openssl asn1parse -in cakey.pem

  

PBES2

     

PBKDF2

     

DES-EDE3-CBC

如果我理解正确,DES密钥长度为64位,因此3DES是192位密钥。 但是,Java策略将DES密钥的长度限制为56位,因此3DES的最大密钥长度为168位。

切换管辖区政策文件对我来说不是一个选择。我认为有一种方法可以使用Bouncy Castle解密PKCS8加密私钥,但解决方案比将提供程序设置为BC更复杂。

有人能指出我的示例或提供一些参考代码吗?

(感谢dave_thompson_085的帮助)。

1 个答案:

答案 0 :(得分:2)

是的,以“----- BEGIN ENCRYPTED PRIVATE KEY -----”开头的文件是PEM格式的PKCS#8加密私钥。我不知道为什么你的评论说“OpenSSL不承认它”; openssl rsa成功读取它的事实证明OpenSSL确实能够识别它。

BC PKCSException只是一个包装;您的实际问题java.security.InvalidKeyException: Illegal key size。如果您尝试在JRE中使用优于128位对称加密或(如此处)解密,并且具有默认的Sun-now-Oracle加密策略(限制为128位对称),则会发生这种情况。我打赌你openssl asn1parse <cakey.pem使用PBES2(带有一些参数)和PBKD2aes-192-cbc显示使用aes-256-cbc加密的文件的一美元。

http://www.oracle.com/technetwork/java/javase/downloads/index.html的“其他资源”部分下载“...(JCE) Unlimited Strength Jurisdiction政策文件 for JDK / JRE 8”,然后解压并放置两个*您正在使用的JRE的JREHOME / lib / security目录中的policy.jar文件。 (假设你不受美国制裁,因为你在朝鲜,伊朗或叙利亚政府等)。