首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与BouncyCastle签署企业社会责任

与BouncyCastle签署企业社会责任
EN

Stack Overflow用户
提问于 2016-02-18 17:36:34
回答 1查看 1.4K关注 0票数 0

在过去的几天里,我一直在寻找我的问题的解决方案,但什么也找不到。我在我的代码中遗漏了一些东西,但我找不出是什么:(不知何故,当我签署我的PKCS#10时,链就断了。

基本上我有一个服务器和一个客户端。我想让客户端向服务器发送CSR,服务器对其进行签名,这样它们就可以通信了。现在,我确实为客户端设置了一个带有BouncyCastle的PKCS#12,并且在代码中为服务器设置了一个RootCertificate (同样使用BouncyCastle,在我的理解中,它只是一个扩展名为能够签署证书的PKCS#12 ),它看起来像这样:

代码语言:javascript
复制
Provider BC = new BouncyCastleProvider();
Security.addProvider(BC);
//create KeyPair
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
kpGen.initialize(2048, new SecureRandom());
pair = kpGen.generateKeyPair();
//building groundbase for certificate
X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
builder.addRDN(BCStyle.CN, commonName);
builder.addRDN(BCStyle.OU, organizationalUnit);
builder.addRDN(BCStyle.O, organization);
builder.addRDN(BCStyle.L, city);
builder.addRDN(BCStyle.ST, state);
builder.addRDN(BCStyle.C, country);
Date notBefore = new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24); //Yesterday
Date notAfter = new Date(System.currentTimeMillis() +  1000L * 365L * 24L * 60L * 60L); //in a year
BigInteger serial = BigInteger.valueOf(new SecureRandom().nextLong());
//creating a self-signed certificate from information in builder
X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(),
serial, notBefore, notAfter, builder.build(), pair.getPublic());

//The next line will make the difference between a Certificate and a Ca Certificate
certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));

ContentSigner sigGen = new JcaContentSignerBuilder(").setProvider(BC).build(pair.getPrivate());
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));

现在我为客户端创建了一个CSR (客户端密钥库在第一个位置有刚刚创建的PKCS#12 ):

代码语言:javascript
复制
String alias = keystore.aliases().nextElement();
X509Certificate cert = (X509Certificate) keystore.getCertificate(alias);
X500Name x500name = new JcaX509CertificateHolder(cert).getSubject();
//builder for the PKCS10
PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(x500name, cert.getPublicKey());
//algorithm identifier
DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
DefaultDigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
AlgorithmIdentifier sigAlgId = sigAlgFinder.find("SHA512WithRSA");
digAlgFinder.find(sigAlgId);
//content Signer
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA512WithRSA");
//and build the Cert
ContentSigner signer = contentSignerBuilder.build((PrivateKey) keystore.getKey(alias, password));
PKCS10CertificationRequest req = requestBuilder.build(signer);
JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req.getEncoded()).setProvider("BC");

我通过网络发送这个编码的JcaPKCS10CertificationRequest。服务器得到它,并创建他的CA证书,现在必须签署PKCS#10,但我在这里遗漏了一些东西,因为他没有包括链。他正在创建的证书包含有关颁发者和BasicConstraints的信息,但证书路径仅包括客户端证书,而不包括服务器的证书,因此它是不可信的,因为链已断开。

这就是我要做的(服务器密钥库将CA证书放在位置0,CSR是JcaPKCS10CertificationRequest):

代码语言:javascript
复制
String alias = keystore.aliases().nextElement();
// PKCS#12 Root Certificate
X509Certificate cert = (X509Certificate) keystore.getCertificate(alias);
// generated Serial
BigInteger serial = BigInteger.valueOf(new SecureRandom().nextLong());
//identify algorithm
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA512WithRSA");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find( sigAlgId );

JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(cert, serial, cert.getNotBefore(), cert.getNotAfter(),
            CSR.getSubject(), CSR.getPublicKey());
certGen.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(cert));

certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false));
certGen.addExtension(Extension.subjectKeyIdentifier, true, extUtils.createSubjectKeyIdentifier(inputCSR.getPublicKey()));
certGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.nonRepudiation));
ContentSigner signer = new JcaContentSignerBuilder(sigAlgName).setProvider("BC").build((PrivateKey)keystore.getKey(alias, password));
X509CertificateHolder holder = certGen.build(signer);
X509Certificate signedCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder);
signedCert.verify(cert.getPublicKey());
JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(new File("cer.cer")));
pemWriter.writeObject(signedCert);
pemWriter.writeObject(cert);
pemWriter.close();

现在,正如我所说的,生成的文件"cer.cer“中没有链。如何添加链条?然后,我可以将该signedCert发送回客户端并在ssl握手中使用它吗?

EN

回答 1

Stack Overflow用户

发布于 2016-06-23 14:01:22

为了添加链条,这对我很有效

X509CertificateHolder holder = certGen.build(signer);之后

代码语言:javascript
复制
  byte[] certencoded = holder.toASN1Structure().getEncoded();
  ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").build(caPrivateKkey);
  CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
  generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(signer, cacert));
  generator.addCertificate(new X509CertificateHolder(certencoded));
  generator.addCertificate(new X509CertificateHolder(cacert.getEncoded()));
  CMSTypedData content = new CMSProcessableByteArray(certencoded);
  CMSSignedData signeddata = generator.generate(content, true);

  byte certificateP7b[] = signedData.getEncoded();

使用此代码,您将获得一个PCKS#7格式的完整链证书。如果您更喜欢使用X509格式

代码语言:javascript
复制
public static List<X509Certificate> p7BToX509(byte signedCert[]) throws CertificateException{
    ByteArrayInputStream is = new ByteArrayInputStream( signedCert);
    CertificateFactory cf = CertificateFactory.getInstance( "X.509" );

    ArrayList<X509Certificate> certificates = new ArrayList<X509Certificate>();
    Iterator i = cf.generateCertificates( is ).iterator();
    while ( i.hasNext() ){
       X509Certificate c = (X509Certificate)i.next();
       certificates.add(c);

    }
    return certificates;

}

这是公共证书。在您的客户端中,您应该拥有私钥。这些都是您需要执行的元素和ssl握手

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35477679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档