两个不同的私钥

时间:2015-04-13 17:14:35

标签: java x509certificate keystore private-key

我正在尝试进行数字签名,然后验证AuthnRequest。 我使用以下命令生成了私钥和公钥证书:

openssl genrsa -out privatekey.pem 2048
openssl req -new -x509 -key privatekey.pem -out publickey.cer -days 365
openssl pkcs12 -export -out public_privatekey.pfx -inkey privatekey.pem -in publickey.cer

通过以下命令将PFX转换为JKS:

keytool -importkeystore -srckeystore public_privatekey.pfx -srcstoretype pkcs12 
-destkeystore clientcert.jks -deststoretype JKS

我正在使用以下java代码访问该私钥条目和公钥证书:

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystoreFile), "dps123!@#".toCharArray());

KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("1", new KeyStore.PasswordProtection("dps123!@#".toCharArray()));
java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) keyEntry.getCertificate();

我必须通过以下方式将私钥值打印到控制台:

String key = Base64.encode(keyEntry.getPrivateKey().getEncoded());
System.out.println(key);

当我比较String“key”的内容和“privatekey.pem”文件中的内容时,两者都不同。这是我没有正确理解的东西,或者在代码中获取私钥值有问题吗?

3 个答案:

答案 0 :(得分:3)

私钥存储有多种格式。其中包括PKCS#1PKCS#8。它们在加密算法和ASN.1结构方面有所不同。此外,除了RSA之外,PKCS#8还支持其他关键算法。

例如,这是未加密的PKCS#8文件的第一个字节的ASN.1转储:

0000  4BE: SEQUENCE {
0004    1:   INTEGER 0
0007    D:   SEQUENCE {
0009    9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
         :       (PKCS #1)
0014    0:     NULL
         :     }
0016  4A8:   OCTET STRING, encapsulates {
001A  4A4:     SEQUENCE {
001E    1:       INTEGER 0
0021  101:       INTEGER    
         :         00 B3 17 E6 31 3C 36 24    ....1<6$

与PKCS#1格式相同的密钥(再次只有前几个字节,文件的其余部分基本上是原始密钥):

0000  4A4: SEQUENCE {
0004    1:   INTEGER 0
0007  101:   INTEGER    
         :     00 B3 17 E6 31 3C 36 24    ....1<6$

本网站包含两种格式的更详细说明: https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem

Java通常会生成PKCS#8格式,而OpenSSL支持这两种格式,并且可以在它们之间进行转换:https://www.openssl.org/docs/apps/pkcs8.html

KeyStore Explorer也可以生成,处理和转换这两种格式。

因此,如果您使用OpenSSL或KSE将privatekey.pem转换为PKCS#8,它应该看起来与System.out.println(key)的输出相同:

openssl pkcs8 -topk8 -in privatekey.pem -out privatekey.pkcs8 -nocrypt

答案 1 :(得分:1)

您的Java提供程序使用什么样的编码有点困难。此外,当您与&#34; privatekey.pem&#34;进行比较时文件,你如何获得内容?

我没有直接的解决方案,但有以下建议:

打印你的pem

> openssl -in privatekey.pem -outform <DER/PEM>

打印中的某处将是base64编码的私钥。

另外,请尝试检查您的JCE提供程序使用哪种编码。

答案 2 :(得分:0)

String key = Base64.getEncoder().encodeToString(keyEntry.getPrivateKey().getEncoded());