gpt4 book ai didi

java - 为 SSL 通信创建证书

转载 作者:太空宇宙 更新时间:2023-11-03 15:00:03 25 4
gpt4 key购买 nike

我正在开发一个分布式应用程序,该应用程序具有许多唯一标识的从属进程,这些从属进程将通过启用 SSL 的套接字与主应用程序通信。该应用程序是用 java 编写的。

我需要一些帮助来理解 SSLSockets,或者更确切地说,他们使用的证书。

我正在寻找的是可以告诉我是否已正确理解证书链的基本工作原理,但我也不会拒绝代码示例的人。

我想要这样一种设置,其中服务器本身具有 CA 签名证书,并且每个从服务器都将获得由主应用程序创建的自己的证书。

CA->Main server cert->Master SSL cert
CA->Main server cert->Slave SSL cert 1
CA->Main server cert->Slave SSL cert 2
CA->Main server cert->Slave SSL cert 3

第一个问题:这种证书链是解决问题的正确方式吗?我认为这是实现主从都具有唯一身份而无需 CA 签署每个证书的最简单方法。

第二个问题:我如何以编程方式在 Java 中创建 SSL 证书?我正在尝试在此处创建链中的最后一个证书,假设我现在已经拥有“主服务器证书”。到目前为止,我已经为证书生成了一个 key (类型是 RSA):

public KeyPair generateKeypair(String type, int bytes) 
throws NoSuchAlgorithmException{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(type);
keyPairGenerator.initialize(bytes);
return keyPairGenerator.generateKeyPair();
}

X509Principal issuer = PrincipalUtil.getSubjectX509Principal(serverCert);
SubjectPublicKeyInfo key
= SubjectPublicKeyInfo.getInstance(kpair.getPublic().getEncoded());
X509v3CertificateBuilder certGen
= new X509v3CertificateBuilder(
issuer,
BigInteger.valueOf(new SecureRandom().nextInt()),
before,
after,
subject,
key
);
AlgorithmIdentifier sigAlgId
= new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId
= new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);

我不认为将 serverCert 设置为颁发者就足以签署证书了吗?据我所知,我需要以某种方式用链中的下一个证书签署新证书,但我该怎么做呢?我是否使用 serverCert 的私钥签署证书,例如:

AsymmetricKeyParameter akp 
= PrivateKeyFactory.createKey(serverPrivateKey.getEncoded());
AlgorithmIdentifier sigAlgId
= new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId
= new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
ContentSigner sigGen
= new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(akp);

我还遗漏了任何其他步骤吗?

最佳答案

从技术角度来看,您的解决方案是正确的。但是不要忘记安全方面的考虑:谁可以申请证书,如何执行身份验证,如何将证书/私钥分发到服务器......

这些元素对于证书生成是必需的:

  • 主题名称
  • 发行人名称
  • 证书序列号
  • 主题公钥
  • 有效期(不早于,不晚于)

添加一些扩展也是一个好习惯:

  • 主题 key 标识符
  • 授权 key 标识符
  • 基本约束
  • key 用法
  • 扩展 key 用法

此代码片段概述了证书生成:

ContentSigner getCertSigner(PrivateKey issuerKey) {
AsymmetricKeyParameter akp = PrivateKeyFactory.createKey(issuerKey.getEncoded());
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
return new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(akp);
}

X509CertificateHolder generateCertificate(X509Certificate issuerCert, PrivateKey issuerKey, X500Name subject, PublicKey subjectKey, Date notBefore, Date notAfter) {
X509Principal issuerDN = PrincipalUtil.getSubjectX509Principal(issuerCert);
SubjectPublicKeyInfo key = SubjectPublicKeyInfo.getInstance(subjectKey.getEncoded());
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(issuerDN, BigInteger.valueOf(new SecureRandom().nextInt()), before, after, subject, key);

// Add authority key identifier
builder.addExtension(X509Extension.authorityKeyIdentifier, false, JcaX509ExtensionUtils.createAuthorityKeyIdentifier(issuerCert));

// Add subject key identifier
builder.addExtension(X509Extension.subjectKeyIdentifier, false, JcaX509ExtensionUtils.createSubjectKeyIdentifier(subjectKey));

// Add basic constraints
builder.addExtension(X509Extension.basicConstraints, true, new BasicConstraints(false));

// Add key usage
KeyUsage keyUsage = new KeyUsage(KeyUsage.keyEncipherment|KeyUsage.digitalSignature);
builder.addExtension(X509Extension.keyUsage, true, keyUsage);

// Add extended key usage
ExtendedKeyUsage extKeyUsage = new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth);
builder.addExtension(X509Extension.extendedKeyUsage, false, extKeyUsage);

return builder.build(getCertSigner(issuerKey));
}

更新:根据 Martin Nielsen 的评论修复了代码。

关于java - 为 SSL 通信创建证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23570919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com