openssl der 文件导入 java 密钥库

openssl der files importing into java keystore

我用 openssl 创建了一个密钥对并希望它们导入到 java-keystore:

1) openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out my_privatekey.pem
2) openssl rsa -pubout -outform DER -in my_privatekey.pem -out mypublic_key.der
3) openssl pkcs8 -topk8 -nocrypt -outform DER -in my_privatekey.pem -out my_privatekey.der

首先,我创建了一个私钥(.pem 格式),然后我创建了一个 public 密钥,最后我将私钥转换为可以在 [=] 中使用的格式34=] (pkcs8).

现在,我想在我的 java 应用程序中以安全的方式使用这些密钥,所以我做了一些研究,解决方案似乎是使用 java-keystore。

但是,如果我是正确的,您不能将 public 密钥直接存储到密钥库中,因为您必须先创建一个证书:

将您的证书转换为 DER 格式:

openssl x509 -outform der -in certificate.pem -out certificate.der

导入密钥库

keytool -import -alias your-alias -keystore cacerts -file certificate.der

这让我想到了我的问题。是否可以在没有证书的情况下将私有密钥和 public 密钥导入密钥库?我不需要证书,因为我只想安全地存储我的密钥,因此它们受密码保护。

如果这不可能,您可以创建并签署自己的证书。 但是,证书可能会过期,所以一段时间后我必须始终更新它,或者我错了吗?

我与第三方共享这个 public 密钥(他们需要这个密钥来验证我用我的私钥签名的数据)并且我也从他们那里得到了一个 public 密钥,加密一些数据。所以我需要在最后存储 2 个 public 密钥(我的密钥和我收到的 public 密钥)。

我该怎么做? 我是否需要创建 2 个证书作为 hack,以便能够将它们存储到 java-keystore 中?

"keytool -importcert" 命令可以毫无问题地读取 PEM 和 DER 格式的证书。

keytool -importcert -file <openssl_crt.pem> -keystore <jks-file-name.jks> -storepass jkspass -alias <alias-name> -keypass <keypass>

keytool Importing Certificates in DER and PEM

旁白:仅对于密钥对,您不需要 genpkey 然后 pkcs8 -topk8 -nocrypt -outform dergenpkey ... -outform der (without -$cipher) 将创建 PKCS8-clear DER,JCE 直接支持的格式。就此而言,即使是 PKCS8-clear PEM 也可以通过剥离 header 和尾行并解码 base64 来轻松处理。对于 2010 年 1.0.0 之前的 OpenSSL 所需的 other 命令(genrsa;gendsa;ecparam -genkey),情况并非如此,这是您会发现很多错误建议的部分原因全世界都在谈论它。

java.security.KeyStore API 仅支持与证书链(可以是单个证书)一起存储 PrivateKey 值。它还支持存储一个单独的证书(以验证来自其他人的签名或向其他人加密数据)而不是一个单独的公钥。所以 是的,您必须创建(或以其他方式获得)证书

如果您不想要真实证书的安全功能,通常的惯例是创建一个 'self-signed' 证书 -- 一个遵循标准 X.509v3 格式并包含publickey,但由其 own 密钥(具体来说,与证书中的公钥匹配的私钥)而不是任何 CA 的密钥签名。 OpenSSL 可以通过多种方式做到这一点,例如通常推荐的

openssl genpkey ... -out priv.pem 
openssl req -new -key priv.pem -x509 ... -out cert.pem

或者您可以将密钥生成和证书创建与更简单的方法结合起来

openssl req -newkey rsa:2048 -keyout priv.pem -nodes -x509 ... -out cert.pem
# this doesn't support all the options of genpkey 
# but it does support the simple case you are using

也可以拆分 'req' 和 'sign' 步骤:

openssl genpkey ... -out priv.pem
openssl req -new -key priv.pem ... -out csr.pem
openssl x509 -req -in csr.pem -signkey priv.pem ... -out cert.pem
# or
openssl req -newkey rsa:2048 -keyout priv.pem ... -out csr.pem
openssl x509 -req -in csr.pem -signkey priv.pem ... -out cert.pem

然后您可以编写(简单的)代码来读入私钥和证书并创建一个 KeyStore 条目——如果您愿意(您可能会这样做)则可以保留。但是 keytool 不能直接这样做。您可以改为使用 openssl pkcs12 -export 将两个 OpenSSL 文件组合成一个 PKCS12 文件,即 password-encrypted 并且在当前支持的 Java 中可直接用作密钥库。对于非常旧的 Java,您可能需要使用 keytool -importkeystore -srcstoretype PKCS12 [-deststoretype JKS] ... 将 PKCS12 文件转换为 JKS 文件,这是您会发现被广泛复制的另一条建议。

或者,除非您需要 OpenSSL 文件用于其他用途,否则 keytool 可以一次完成所有工作;只需根据需要执行 keytool -genkeypair -keyalg rsa -keysize 2048 -keystore $file 以及 -validity-dname 等其他选项,它将生成密钥对 and 一个 self-signed 证书它并将带有 self-signed 证书的私钥存储在 password-protected 密钥库文件中。 (通过 j8 默认为 JKS,但您可以指定其他方式;j9+ 默认为 PKCS12。)

However, a certificate can be expired, so after some time I have to always renew it or am I wrong?

一段时间后,是的,但那个时间可能是几千年。我怀疑你和 third-party 届时都将不复存在,而且 Java 可能不再存在,因此 Java API 强加的要求将不再重要。请注意,在 32 位系统上的旧版本 OpenSSL - 今天很少见,组合更罕见 - 有时会受到 "Y2038" 问题的影响,现在只有 18 年后的未来 - 许多 今天使用的系统到那时可能已经过时,但不是全部。 Java 使用自己的时间戳格式,从未遇到过这个问题。

CA-issued 证书的生命周期通常要短得多,很少超过 1-2 年,有时甚至更短(例如,LetsEncrypt 为 90 天),但这不是证书规范和代码中固有的。

Do I need to create 2 certificates as a hack, in order to be able to store them into the java-keystore?

是的。确切地说,您当然需要为自己的密钥创建一个(虚拟)证书。对于对方的密钥,如果 他们 创建(虚拟)证书会更容易。您不能为他们创建 self-signed 证书,因为您没有他们的私钥——或者至少您不应该拥有。您 可以 创建一个稍微复杂的结构,您可以在其中创建一个虚拟 CA 并使用它为他们签署证书,然后导入并使用。如果需要的话我会扩展,但这正如我所说的更复杂,而许多常用工具的设置让他们可以很容易地做到这一点。