java - Java 的 RSA key 转换 - 需要澄清吗?

标签 java encryption openssl rsa public-key-encryption

我读了一些关于将 key 从 PEM 转换为 DER 以便 Java 可以读取它们的已知问题的信息,我运行了 this article 。完成后,效果正常 - 使用 openssl 生成 RSA key 对, key 加载正常,并且使用公钥加密的内容可以使用私钥成功解码。

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

server.csr ------ // certificate request
server.key ------// private key
server.crt -------// self-signed certificate/public-key/whatever this is..?

仅供引用,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 代码需要公钥文件,而不是 X509 证书,这是您在 server.crt 中拥有的内容。

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

来自 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();

关于java - Java 的 RSA key 转换 - 需要澄清吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18856431/

相关文章:

java - Struts 2 表单标签中的多个提交按钮

java - GUI 选择和键入文件名之间的 FileChooser 差异

.net-core - 如何将正确的 libssl 版本包含到 yocto-build 中以运行 .net-core 应用程序?

java - JAVA中使用RSA公钥和私钥进行加密和解密

java - 如何根据网络服务器中的php部分在android java中进行WSSE身份验证实现?

c++ - 带 SSL 的简单 gSoap 服务器和客户端

c++ - 带有 openSSL 的 libwebsocket 服务器不接受连接

java - 如何在JPA中生成sql?

java - 字符串哈希表实现

javascript - 在公共(public)存储库中隐藏 key