【问题标题】:RSA keys transformation for Java - clarification needed?Java 的 RSA 密钥转换 - 需要澄清吗?
【发布时间】:2013-09-22 06:43:26
【问题描述】:

我阅读了一些关于将密钥从 PEM 转换为 DER 以便 Java 可以读取它们的已知问题,然后我跑到了 this article。完成后,一切正常 - 生成带有openssl 的 RSA 密钥对,密钥加载正常,用公钥加密的内容用私钥成功解码。

现在,这是不清楚的部分。
不久前,我在设置 OpenVPN 服务器时使用 Easy-RSA 实用程序生成了 PKI。在这里,创建了一个自签名证书。输出文件,其中包括:

server.csr ------ // 证书请求
server.key ------// 私钥
server.crt -------//自签名证书/公钥/不管这是什么..?

仅供参考,easy-RSA is documented(页面底部是解释的脚本,我们可以看到过程中实际使用的openssl命令)。

所以,我在这些文件上尝试了上述逻辑,使用server.key 作为我的私钥文件,server.crt 作为我的公钥文件,之前都已转换为 Java 可读的 DER 格式:

openssl pkcs8 -topk8 -inform PEM -outform DER -in server.key -out server_private_key.der -nocrypt openssl x509 -inform PEM -outform DER -text -in server.crt -out server.der

私钥,并不奇怪,工作正常,即它在 Java 中成功加载。
公钥(同样,可能并不奇怪)不会加载,但我不知道原因,因为我对所有这些事情并不熟悉。我的猜测是这与正在签署的证书有关,我想知道在这些情况下如何处理。我得到以下异常:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException:IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
  at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
  at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
  at aes.utils.KeyReaderUtil.getPublicKeyFromFile(KeyReaderUtil.java:57)
  at aes.utils.Main.main(Main.java:69)
Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data
isn't an object ID (tag = -96)
  at sun.security.x509.X509Key.decode(X509Key.java:380)
  at sun.security.x509.X509Key.decode(X509Key.java:386)
  at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
  at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
  at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
  ... 3 more

此外,当我从现有的server.key 私钥文件中“导出”公钥时,就像这样(如上一篇文章):

openssl rsa -in server.key -pubout -outform DER -out server_public_key.der

一切都恢复正常了。

所以,我的问题是:什么是正确的方法,为什么server.crt 不会作为公钥加载?

【问题讨论】:

    标签: java encryption openssl rsa public-key-encryption


    【解决方案1】:

    您链接的文章中的 Java 代码需要一个公钥文件,而不是您在 server.crt 中拥有的 X509 证书。

    X509 证书包含公钥以及通过签名绑定到该密钥的身份信息。

    从Java的X509Certificate documentation,你可以找到这段代码:

     InputStream inStream = null;
     try {
         inStream = new FileInputStream("fileName-of-cert");
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
     } finally {
         if (inStream != null) {
             inStream.close();
         }
     }
    

    一旦你有了一个 X509 证书对象,你就可以像这样轻松获得 PublicKey:

    PublicKey myPubKey = cert.getPublicKey();
    

    【讨论】:

    • 是的,就是这样。唯一的事情是 - 我必须从文件中删除证书信息,只留下 DER 编码的数据段。感谢您的澄清和示例!
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2018-07-16
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2011-11-09
    相关资源
    最近更新 更多