在Java中格式化OpenSSL的RSA密钥

背景

使用命令在Linux上使用OpenSSL生成RSA密钥,

openssl genrsa -out mykey.pem 1024

创建了以下内容:

 "-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQChs9Fepy5FgeL0gNJ8GHcKRHsYnM2Kkw19zwydDQNyh2hrHWV2 B11wpLFp8d0imcl2Wjb0oV/AxOhb3unQgNzs66LVuXJwS8icp3oIJZtExs6tkxzE s5mnU68wMeCYtJqHIZOmNblVWvpJMLNAwAVi3oLfnzDDbzjnDapm8M21nQIDAQAB AoGAZ11P1+acUHgvwMXcRtFIvvp5iYkqZouL00EYOghIjNx75gTbh7A7jbbpZeTi y6xsuMgAWy4QzGPSeG+tHMhS7+dYQNPuKSv5KtK3V7ubXz/I3ZN1etRVecA56QNw 7HKv6b7srolt08kogGIwpbbfl/mhfJHnv4Jeqd5lNMnK4e0CQQDWFZo4h22OlSaH ZGd3i4rwLrA0Ux5bkdh7YH0uEeE/nGzpVs1DPhsN8UCyq9LAiKYLlXeeCvwurKwo OgKlUCkzAkEAwVy2KignoRInFTAaYH8PQRfD835q+oC0Iu21BF68ne06U6wu+wWk bWiYxTOOb+TGZfA1vA6OAvGVGoXs1bHF7wJBAItGiop0MKYuCl7Sxy1SrxUKir+/ w2Q3QesiHs41+6Byl7hGLEuuv9MWPM0AU5/GRqAKoUNESkPjOi0BcG8z81kCQGGn OvCreugjzM0skAWv5bpQEExGyixdF5yURFlCpytzBYQAb3Gi9dmze4QMd6EW/wO4 fsrM5vehnlXY0TVTJM0CQQCMPVhub8LSo7T/lCzypvb/cgxJfyITRKcM2asrXud5 r27kbzsXqYum4huHqyFkb3pZammsYA/z89HchylfrD4U -----END RSA PRIVATE KEY-----" 

Java 6下的以下代码,

 KeyPairGenerator keyGen = null; try { keyGen = KeyPairGenerator.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } KeyPair pair = keyGen.generateKeyPair(); privateKey = new Base64Encoder().encode(pair.getPrivate().getEncoded()); publicKey = new Base64Encoder().encode(pair.getPublic().getEncoded());` 

输出以下内容:

 "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIsJlqFOP+jPyYvrGwh+dff30a3p uHysMfHYi1MyNSFCsT/2QbOc/k9U/X28WRCMeFwEEnReLULXA9Ywox8GycI/ApMX+DjKBrrLDbpr ATLiu9+NMK4VSytKFI87P07HAni3RkiO4rFNEINVQ7t38ZmHavuXHjMkLEAK4dyLQO9NAgMBAAEC gYBN/jv0EmwBUgYSKflJI39TcT263B+0N/fwXXOSYNiy5rF9WstyUP/LSrbEAJLJmLKvk00y391t 4CVz0ma+sdUdAPlS7Nmx9f3BThGOGcDmpjVo1y4e1afWtyu66ba/XDeuf7q5Y/h/pr20/gXl9Gz2 yefQrzU9xXGKZhE/lxJ2IQJBAMELpeAal+Fa+u0InGrowVmV+lge8RZqKRfCDzPPna465E5Qcekb J0ShsarP5lnUfrNH5g8GLaDGQwYE/UoIpPkCQQC4YRfck5uMlI1K3F9YC3XvmFAJnf9YexoPfNSu dznOD4rxlwzW/5daPOR0jjlyIRDH/QuUoPIIEn1mt3dnz7X1AkBZciozgl7pPhySA7FmH96mwcUz W3LdrebIaVRd707iUctDNibxmXFCbaFCwf27laf3LdM9FuHBYtvfSCSMTyERAkEAlNAQsUAVmKZB T72D2o0Nd/7oAosaD7DzvLJU+idSaWUUEJ+IhnKuFu/0t7oe1WWopLEwypoIHsnFmsTTQ99ajQJA Scwh3P3RTN4F6Jz1SxRSe6L729xI8xkbco5EsMq5v5BZeoGynqdPUUZdAPcaO2k5UagaSejvzgna 8xIqR7elVQ==" "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLCZahTj/oz8mL6xsIfnX399Gt6bh8rDHx2ItT MjUhQrE/9kGznP5PVP19vFkQjHhcBBJ0Xi1C1wPWMKMfBsnCPwKTF/g4yga6yw26awEy4rvfjTCu FUsrShSPOz9OxwJ4t0ZIjuKxTRCDVUO7d/GZh2r7lx4zJCxACuHci0DvTQIDAQAB" 

问题

  1. 如何在通过Java代码创建的私钥和公钥周围放置“armor”?

  2. 为什么通过Java代码生成的密钥的每一行都比OpenSSL生成的那些更长?

  3. 这有什么不同吗? 其他团队正在使用的工具之一在使用上面提到的Java代码生成的私钥签名消息时失败。 但是,它工作正常,该工具使用OpenSSL生成的私钥。

  4. 有没有办法可以用Java导出兼容的密钥?

OpenSSL私钥采用非标准格式,而Java代码正在创建标准的PKCS-#8编码私钥。

OpenSSL可以将标准密钥格式转换为非标准格式。 您可以编写Java代码来执行相同的操作,但它需要一些第三方库,并且ASN.1的良好知识也有帮助。

要将PKCS#8密钥转换为OpenSSL格式,请使用OpenSSL的pkcs8实用程序。

 openssl pkcs8 -nocrypt -inform der < pvt.der > pvt.pem 

要将存储为DER编码的SubjectPublicKeyInfo的RSA密钥转换为PEM格式,请使用OpenSSL的rsa实用程序。

 openssl rsa -pubin -inform der < pub.der > pub.pem 

这假设私钥以“二进制”(DER)格式存储,而不是以Base-64编码。 用于创建和存储此类键的Java代码如下所示:

 KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); KeyPair pair = gen.generateKeyPair(); FileOutputStream ospvt = new FileOutputStream("pvt.der"); try { ospvt.write(pair.getPrivate().getEncoded()); ospvt.flush(); } finally { ospvt.close(); } FileOutputStream ospub = new FileOutputStream("pub.der"); try { ospub.write(pair.getPublic().getEncoded()); ospub.flush(); } finally { ospub.close(); }