java - 读取 CA 证书私钥以签署证书

标签 java security ssl x509certificate

我有如下要求:

  1. 创建一个自签名(比如 CA 证书)并保存证书和私钥 到文件
  2. 加载 CA 证书(在步骤 1 中创建)及其私钥
  3. 创造一个结局 使用加载的 CA 证书和私钥签名的证书 第 2 步

我的私钥存储在如下文件中:

public static void writePrivateKey(PrivateKey privateKey, OutputStream os) throws IOException
  {
    BufferedOutputStream bos = new BufferedOutputStream(os);
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
            privateKey.getEncoded());
    bos.write(pkcs8EncodedKeySpec.getEncoded());
    bos.close();
  }

我的私钥加载回来如下:

 public PrivateKey loadPrivatekey(InputStream privateKeyInputStream)
          throws InvalidKeySpecException, NoSuchAlgorithmException, IOException
  {
    return KeyFactory.getInstance(algorithamForCreatingAndLoadingKeys)
            .generatePrivate(new PKCS8EncodedKeySpec(IOUtils.toByteArray(privateKeyInputStream)));
  }

我将我的算法定义为 RSA

 private String algorithamForCreatingAndLoadingKeys = "RSA";

我正在如下签署我的证书:

 private static X509CertImpl buildAndSignCert(X509CertInfo certInfo, PrivateKey privateKey)
          throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
          NoSuchProviderException, SignatureException, IOException
  {
    X509CertImpl cert = new X509CertImpl(certInfo);
    String algorithm = "SHA1withRSA";
    // Sign the cert to identify the algorithm that's used.
    cert.sign(privateKey, algorithm);
    // Update the algorith, and resign.
    certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM,
            cert.get(X509CertImpl.SIG_ALG));
    X509CertImpl newCert = new X509CertImpl(certInfo);
    newCert.sign(privateKey, algorithm);
    return newCert;
  } 

问题:如果我创建 CA 证书和结束证书没有保存和加载 key 文件我能够很好地验证结束证书:

C:\Workspace.....\src\main\resources>openssl verify -CAfile ca.pem end.pem

end.pem: OK

但是如果我保存并加载 key 文件并验证,我会得到以下错误,这清楚地表明我的最终证书没有用我的 ca 证书正确签名

C:\Workspace.....\src\main\resources>openssl verify -CAfile ca.pem end.pem

end.pem: C = AU, L = ABC, CN = XYZ

error 20 at 0 depth lookup:unable to get local issuer certificate

所以,我得出的结论是,我保存和加载私钥是有问题的。

任何人都可以帮助我在保存和读取私钥时做错了什么吗?

非常感谢。

最佳答案

我上面发布的所有代码都是正确和准确的,可以创建和读取私钥文件

我发现问题出在加载创建的 CA 证书本身(而不是私钥),当我们生成 X509 证书时的一些方式如下:

CertificateFactory f = CertificateFactory.getInstance("X.509");
    X509Certificate loadedCaCert = (X509Certificate) f
            .generateCertificate(CertificateGenerator.class.getResourceAsStream("/ca.pem"));

它从上面生成的 X509Certificate 生成的序列号与我在创建 CA 证书时传递的序列号不同(这是另一个问题,但无论如何都没有涉及到这个线程)并且当我们将这个序列号传递给订阅者时证书来识别其父 CA 以获取链接其失败的证书。

谢谢

关于java - 读取 CA 证书私钥以签署证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34214806/

相关文章:

sql - 在数据库中存储一个大哈希而不是用户/密码

iphone - iPhone 上的同步 SSL 证书处理

java - spring boot web绑定(bind)时如何拦截错误信息?

java - 找不到符号 - 方法 add(E)

java - 从 Android 中的 Listview Adapter 访问 Activity 中的 TextView

security - 在移动网络应用程序中混合安全和不安全的内容

android - KeyPairGeneratorSpec 弃用

未加载 SSL 证书和容器启动

ssl - 不需要的 nginx 重定向到 https

JavaFx 从数据帧创建图表