Java BouncyCastle ECC密钥和自签名证书

时间:2014-03-09 20:34:13

标签: java cryptography bouncycastle

我已经在互联网上搜索了几个小时,寻找创建椭圆曲线(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);
     }
 }     

1 个答案:

答案 0 :(得分:0)

我设法按照这些步骤以编程方式创建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);

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