自签名X509证书与Java中的Bouncy Castle

我需要在Java中创建一个带有Bouncy Castle的自签名X509证书,但我尝试包含的每个类都已弃用。 我怎么解决这个问题? 是否还有其他课程要包括在内? 谢谢

使用Bouncycastle最新版本 – 1.55

@Bewusstsein更新答案。 在本答案(2017年5月11日)中,最新版本中不推荐使用bouncycastle类。 如果您使用的是最新版本(1.55)或相对最新版本:

public static Certificate selfSign(KeyPair keyPair, String subjectDN) throws OperatorCreationException, CertificateException, IOException { Provider bcProvider = new BouncyCastleProvider(); Security.addProvider(bcProvider); long now = System.currentTimeMillis(); Date startDate = new Date(now); X500Name dnName = new X500Name(subjectDN); BigInteger certSerialNumber = new BigInteger(Long.toString(now)); // <-- Using the current timestamp as the certificate serial number Calendar calendar = Calendar.getInstance(); calendar.setTime(startDate); calendar.add(Calendar.YEAR, 1); // <-- 1 Yr validity Date endDate = calendar.getTime(); String signatureAlgorithm = "SHA256WithRSA"; // <-- Use appropriate signature algorithm based on your keyPair algorithm. ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate()); JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(dnName, certSerialNumber, startDate, endDate, dnName, keyPair.getPublic()); // Extensions -------------------------- // Basic Constraints BasicConstraints basicConstraints = new BasicConstraints(true); // <-- true for CA, false for EndEntity certBuilder.addExtension(new ASN1ObjectIdentifier("2.5.29.19"), true, basicConstraints); // Basic Constraints is usually marked as critical. // ------------------------------------- return new JcaX509CertificateConverter().setProvider(bcProvider).getCertificate(certBuilder.build(contentSigner)); } 

请注意:此答案使用具有11个CVE的旧版本库。

这是我正在使用的(使用BouncyCastle v1.38):

 import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.security.SignatureException; import java.util.Date; import javax.security.auth.x500.X500Principal; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.x509.X509V3CertificateGenerator; public class BouncyCastle { public static void main(String[] args) throws CertificateEncodingException, InvalidKeyException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { X509Certificate selfSignedX509Certificate = new BouncyCastle().generateSelfSignedX509Certificate(); System.out.println(selfSignedX509Certificate); } public X509Certificate generateSelfSignedX509Certificate() throws CertificateEncodingException, InvalidKeyException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { addBouncyCastleAsSecurityProvider(); // generate a key pair KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC"); keyPairGenerator.initialize(4096, new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // build a certificate generator X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); X500Principal dnName = new X500Principal("cn=example"); // add some options certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); certGen.setSubjectDN(new X509Name("dc=name")); certGen.setIssuerDN(dnName); // use the same // yesterday certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)); // in 2 years certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000)); certGen.setPublicKey(keyPair.getPublic()); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping)); // finally, sign the certificate with the private key of the same KeyPair X509Certificate cert = certGen.generate(keyPair.getPrivate(), "BC"); return cert; } public void addBouncyCastleAsSecurityProvider() { Security.addProvider(new BouncyCastleProvider()); } } 

对于certGen.generate(keyPair.getPrivate(), "BC"); 要工作,必须将BouncyCastle添加为安全提供程序。

我确认它适用于这个maven依赖:

  org.bouncycastle bcprov-jdk16 1.38  

这是一个完整的自签名ECDSA证书生成器,可在客户端和服务器端创建可在TLS连接中使用的证书。 它是用BouncyCastle 1.57测试的。 类似的代码可用于创建RSA证书。

 SecureRandom random = new SecureRandom(); // create keypair KeyPairGenerator keypairGen = KeyPairGenerator.getInstance("EC"); keypairGen.initialize(256, random); KeyPair keypair = keypairGen.generateKeyPair(); // fill in certificate fields X500Name subject = new X500NameBuilder(BCStyle.INSTANCE) .addRDN(BCStyle.CN, "stackoverflow.com") .build(); byte[] id = new byte[20]; random.nextBytes(id); BigInteger serial = new BigInteger(160, random); X509v3CertificateBuilder certificate = new JcaX509v3CertificateBuilder( subject, serial, Date.from(LocalDate.of(2000, 1, 1).atStartOfDay(ZoneOffset.UTC).toInstant()), Date.from(LocalDate.of(2035, 1, 1).atStartOfDay(ZoneOffset.UTC).toInstant()), subject, keypair.getPublic()); certificate.addExtension(Extension.subjectKeyIdentifier, false, id); certificate.addExtension(Extension.authorityKeyIdentifier, false, id); BasicConstraints constraints = new BasicConstraints(true); certificate.addExtension( Extension.basicConstraints, true, constraints.getEncoded()); KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.digitalSignature); certificate.addExtension(Extension.keyUsage, false, usage.getEncoded()); ExtendedKeyUsage usageEx = new ExtendedKeyUsage(new KeyPurposeId[] { KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth }); certificate.addExtension( Extension.extendedKeyUsage, false, usageEx.getEncoded()); // build BouncyCastle certificate ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA") .build(keypair.getPrivate()); X509CertificateHolder holder = certificate.build(signer); // convert to JRE certificate JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); converter.setProvider(new BouncyCastleProvider()); X509Certificate x509 = converter.getCertificate(holder); // serialize in DER format byte[] serialized = x509.getEncoded();