Java BouncyCastle ECC密钥和自签名证书

几个小时以来,我一直在寻找一个用于创建椭圆曲线(EC)密钥和自签名证书的Java示例。 到目前为止,我只发现了片段和示例,其中许多都不起作用。

更新:

我在这里取得了一些进展,这是我的代码,对于任何可能发现它有用的人来说! 只需要弄清楚如何自我签名吧!

import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; import java.security.*; /** * A simple example showing generation and verification of a PKCS#10 request. */ public class genECKeyExample { private static final String BC = BouncyCastleProvider.PROVIDER_NAME; public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // Create an eliptic curve key ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime192v1"); KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC"); g.initialize(ecSpec, new SecureRandom()); KeyPair pair = g.generateKeyPair(); System.out.println(pemUtils.toPem(pair.getPrivate())); System.out.println(pemUtils.toPem(pair.getPublic())); ContentSigner signer = new JcaContentSignerBuilder("SHA1withECDSA").setProvider(BC).build(pair.getPrivate()); PKCS10CertificationRequestBuilder reqBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=XXX"), pair.getPublic()); PKCS10CertificationRequest req = reqBuilder.build(signer); ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(BC).build(pair.getPublic()); // System.out.println(verifier); req = new PKCS10CertificationRequest(req.getEncoded()); System.out.println(pemUtils.toPem(req)); pemUtils.toFile("csr.pem", pemUtils.toPem(req)); pemUtils.toFile("pkey.pem", pemUtils.toPem(pair.getPrivate())); } } 

这是我最接近但没有创建CSR或证书。 此外,它似乎不允许选择不同的键大小(我认为它们是曲线)。 有没有人可以分享一些他们可以分享的例子?

  import org.bouncycastle.openssl.PEMWriter; import java.io.StringWriter; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.SecureRandom; import java.security.Security; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import javax.crypto.KeyAgreement; public class X509CertificateGenerator { public static void main(String[] args) throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "BC"); EllipticCurve curve = new EllipticCurve(new ECFieldFp(new BigInteger( "fffffffffffffffffffffffffffffffeffffffffffffffff", 16)), new BigInteger( "fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger( "fffffffffffffffffffffffffffffffefffffffffffffffc", 16)); ECParameterSpec ecSpec = new ECParameterSpec(curve, new ECPoint(new BigInteger( "fffffffffffffffffffffffffffffffefffffffffffffffc", 16), new BigInteger( "fffffffffffffffffffffffffffffffefffffffffffffffc", 16)), new BigInteger( "fffffffffffffffffffffffffffffffefffffffffffffffc", 16), 1); keyGen.initialize(ecSpec, new SecureRandom()); KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "BC"); KeyPair aPair = keyGen.generateKeyPair(); KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDH", "BC"); KeyPair bPair = keyGen.generateKeyPair(); aKeyAgree.init(aPair.getPrivate()); bKeyAgree.init(bPair.getPrivate()); aKeyAgree.doPhase(bPair.getPublic(), true); bKeyAgree.doPhase(aPair.getPublic(), true); MessageDigest hash = MessageDigest.getInstance("SHA1", "BC"); System.out.println(new String(hash.digest(aKeyAgree.generateSecret()))); System.out.println(new String(hash.digest(bKeyAgree.generateSecret()))); System.out.println(aPair.getPrivate()); StringWriter pemWrtPublic = new StringWriter(); PEMWriter pubkey = new PEMWriter(pemWrtPublic); pubkey.writeObject(aPair.getPublic()); pubkey.flush(); String pemPublicKey = pemWrtPublic.toString(); System.out.println(pemPublicKey); StringWriter pemWrtPrivate = new StringWriter(); PEMWriter privkey = new PEMWriter(pemWrtPrivate); privkey.writeObject(aPair.getPrivate()); privkey.flush(); String pemPrivateKey = pemWrtPrivate.toString(); System.out.println(pemPrivateKey); } } 

我设法按照这些步骤以编程方式创建CSR(假设您有一个存储在密钥库中的X509证书):

 X509Certificate generatedCertificate = (X509Certificate)getKeystore().getCertificate(r.keystoreAlias); PrivateKey privateRequestKey = (PrivateKey)getKeystore().getKey("alias", "password".toCharArray()); Signature signature = Signature.getInstance("MD5WithRSA"); signature.initSign(privateRequestKey); X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); //possibly less or more of these, depending on your needs x500NameBld.addRDN(BCStyle.C, "country"); x500NameBld.addRDN(BCStyle.O, "ORG"); x500NameBld.addRDN(BCStyle.E, "email"); x500NameBld.addRDN(BCStyle.CN, "SubjectName"); x500NameBld.addRDN(BCStyle.SN, "12345678"); X500Name subject = x500NameBld.build(); PKCS10CertificationRequest req = new PKCS10CertificationRequest("MD5WithRSA",X509Name.getInstance(subject),generatedCertificate.getPublicKey(),new DERSet(),privateRequestKey); 

请注意,此代码适用于“常规”密钥对,但适用于所有公共/私人密钥对。