22

我必须将 pem 格式的证书转换为 java 密钥库。

在 Windows 服务器上将此与 tomcat 一起使用

我有这些文件:

  • cert_request.csr

    -----BEGIN CERTIFICATE REQUEST-----
    ...
    -----END CERTIFICATE REQUEST-----
    
  • cert_public_key.pem

    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    
  • cert_private_key.pem

    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ...
    -----END ENCRYPTED PRIVATE KEY-----
    
  • 证书.txt

    contains an 16 digit key
    

我尝试合并 pem 文件(通过将两个文件链接在一起)并使用 openssl 将其转换为

  • .der 文件并使用 keytool 将其导入新的密钥库
  • 与 .p12 相同
  • 直接导入密钥库

我也试图改变

    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ...
    -----END ENCRYPTED PRIVATE KEY-----

进入

    -----BEGIN RSA PRIVATE KEY-----
    ...
    -----END RSA PRIVATE KEY-----

并尝试了上面的3种方法

我该怎么做才能获得工作证书?

编辑:

我将 cert_public_key.pem 和 cert_private_key.pem 组合到 cert_comb.pem

    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ...
    -----END ENCRYPTED PRIVATE KEY-----
4

2 回答 2

42

您不清楚您组合了哪些文件,但使用 openssl 将证书和私钥组合到 PKCS#12 应该可以:

cat cert_public_key.pem cert_private_key.pem >combined.pem
openssl pkcs12 -export -in combined.pem -out cert.p12

或即时但(更新:)私钥必须是第一个:

cat cert_private_key.pem cert_public_key.pem | openssl pkcs12 -export -out cert.p12 

如果您的证书需要任何链式证书——当你提交 CSR 并且他们颁发了证书时,CA 应该告诉你这一点——现在最容易也包括它(他们)。

然后 (1)一些Java 程序实际上可以直接使用 pkcs12 作为密钥库,但是 (2) 如果您需要或更喜欢 JKS 使用 keytool:

keytool -importkeystore -srckeystore cert.p12 -srcstoretype pkcs12 -destkeystore cert.jks 

如果您关心生成的 JKS 中的别名,最容易在转换后修复它。

另外:仅更改加密 PEM 中的标签并不会对其进行解密,将标签从通用 PKCS#8 更改为 RSA 实际上也不会更改要匹配的数据(它们有所不同,尽管只有一点点不同)。如果您确实想要一个带有解密私钥的单独 PEM 文件:

openssl pkey -in encryptedpk8 -out clearpk8.pem # 1.0.0 up
openssl pkcs8 -in encryptedpk8 -out clearpk8.pem # 1.0.0 up 
openssl pkcs8 -topk8 -nocrypt -in encryptedpk8 -out clearpk8.pem # below 1.0.0
openssl rsa -in encryptedpk8 -out clearrsa.pem
于 2014-03-10T11:15:59.300 回答
1

第一个问题:你只有一个证书请求?不是真正的证书?它需要签名,您可以自行签名或由外部方签名。

如果您有实际的证书,您可以使用它来解析私钥文件和证书文件:

// parse the private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // might not be RSA
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(byteArray);
PrivateKey privateKey = keyFactory.generatePrivate(spec);

// parse cert
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = factory.generateCertificate(certInputStream);

// add it to the keystore
store.setKeyEntry(alias, privateKey, password, new X509Certificate[] { cert });

更新

据我所知,命令行 keytool 不支持任何高级选项,例如签署 csr。即使是标准的 java 也不支持这个,你需要一个像充气城堡这样的外部库。这并不容易。例如:

JcaPKCS10CertificationRequest pkcs10 = new JcaPKCS10CertificationRequest(csrBytes);
X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
        issuer,
        generateSerialId(),
        new Date(),
        until,
        subject,
        pkcs10.getPublicKey()
);

X509CertificateHolder holder = builder.build(getContentSigner(privateKey, type));
X509Certificate cert = getCertificate(holder);

...

ContentSigner getContentSigner(PrivateKey privateKey) {
    AsymmetricKeyParameter keyParameter = PrivateKeyFactory.createKey(privateKey.getEncoded());
    AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WITHRSA"); // or what you want
    AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
    return new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(keyParameter);
}
于 2014-03-10T09:47:32.687 回答