简体   繁体   English

使用特定的私钥生成证书

[英]Use Specific Private Key to Generate Certificate

I am working with bouncy castle and I want to generate a specific private key instead of the random key generated. 我正在与充气城堡合作,我想生成一个特定的私钥,而不是生成的随机密钥。

I want to provide my own private key but the code keeps generating random keys. 我想提供自己的私钥,但是代码不断生成随机密钥。 is there a way to specify the exact private key to use in bouncy castle? 有没有一种方法可以指定在弹性城堡中使用的确切私钥?

My Code is as Below. 我的代码如下。 When i check the generated certificate's public key, i get different values all the time. 当我检查生成的证书的公钥时,我总是得到不同的值。 I need the value i specified. 我需要指定的值。

In main 在主要

 var cb = new X509CertBuilder(suppliers, "CN=MandarinAS, OU=Scheme42, O=MandarinAS, C=GB",
                    CertStrength.Bits1024);


                   var cert = cb.MakeCertificate(pwd, "CN=Mandarin, OU=CustomerId, OU=Scheme42, O=OrgX, C=GB", 1,keypair);

                    File.WriteAllBytes("Cert.pfx", cert.Export(X509ContentType.Pkcs12, pwd));


                File.WriteAllBytes("Cert.cer", cert.Export(X509ContentType.Cert, pwd));
    var store = new X509Store(storeLocation);
                store.Open(OpenFlags.ReadOnly);

                var myCertificate = new X509Certificate2("Cert.pfx", "password");
                if (myCertificate.PrivateKey !

= null)
            {
                store.Close();

            }
//here i debug and compare the public key values myCertificate is always changing

X509CertBuilder.cs X509CertBuilder.cs

public class X509CertBuilder
    {
        private const string SignatureAlgorithm = "SHA1WithRSA";
        private readonly int _strength;
        private readonly CryptoApiRandomGenerator _randomGenerator = new CryptoApiRandomGenerator();
        private readonly X509V3CertificateGenerator _certificateGenerator = new X509V3CertificateGenerator();
        private readonly SecureRandom _random;
        private readonly X509Name _issuer;
        private readonly GeneralName[] _generalNames;

        public X509CertBuilder(string[] validWithDomainNames, string issuer, CertStrength certStrength)
        {
            _random = new SecureRandom(_randomGenerator);
            _issuer = new X509Name(issuer);
            _strength = (int) certStrength;

            _generalNames = new GeneralName[validWithDomainNames.Length];
            for (var t = 0; t < validWithDomainNames.Length; t++)
            {
                _generalNames[t] = new GeneralName(new X509Name(validWithDomainNames[t]));
            }
        }

        public X509Certificate2 MakeCertificate(string password, string issuedToDomainName, int validYears, AsymmetricCipherKeyPair mykey=null)
        {
            _certificateGenerator.Reset();

            _certificateGenerator.SetSignatureAlgorithm(SignatureAlgorithm);
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue),
                _random);
            _certificateGenerator.SetSerialNumber(serialNumber);

            _certificateGenerator.SetSubjectDN(new X509Name(issuedToDomainName));
            _certificateGenerator.SetIssuerDN(_issuer);

            var subjectAlternativeNames = new Asn1Encodable[_generalNames.Length + 1];
            // first subject alternative name is the same as the subject
            subjectAlternativeNames[0] = new GeneralName(new X509Name(issuedToDomainName));
            for (var t = 1; t <= _generalNames.Length; t++)
            {
                subjectAlternativeNames[t] = _generalNames[t - 1];
            }
            var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
            _certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false,
                subjectAlternativeNamesExtension);

            _certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            _certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(validYears));
            var keyGenerationParameters = new KeyGenerationParameters(_random, _strength);

            var keyPairGenerator = new RsaKeyPairGenerator();


            keyPairGenerator.Init(keyGenerationParameters);
            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            _certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            //Previouse auto key
            //var issuerKeyPair = subjectKeyPair;

            //My mykey
            var issuerKeyPair = mykey;
            var certificate = _certificateGenerator.Generate(issuerKeyPair.Private,_random);


            var store = new Pkcs12Store();
            var friendlyName = certificate.SubjectDN.ToString();
            var certificateEntry = new X509CertificateEntry(certificate);
            store.SetCertificateEntry(friendlyName, certificateEntry);
            store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(issuerKeyPair.Private), new[] {certificateEntry});

            using (var stream = new MemoryStream())
            {
                store.Save(stream, password.ToCharArray(), _random);
                return new X509Certificate2(stream.ToArray(), password,
                    X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            }
        }
    }

Edit : Incorrectly answered for Java. 编辑 :Java错误回答。 The BouncyCastle C# API is not easily accessed online, but I believe what you are looking for is X509CertificateParser BouncyCastle C#API很难在线访问,但是我相信您正在寻找的是X509CertificateParser


If you have the public key in DER format, you can simply pass the encoded byte[] to java.security.cert.CertificateFactory.generateCertificate() and you will get the proper X509Certificate as a result. 如果您具有DER格式的公钥,则只需将编码的byte[]传递给java.security.cert.CertificateFactory.generateCertificate() ,结果将得到正确的X509Certificate

    private static X509Certificate formX509Certificate(byte[] encodedCertificate) throws CertificateException {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            ByteArrayInputStream bais = new ByteArrayInputStream(encodedCertificate);
            return (X509Certificate) cf.generateCertificate(bais);
        } catch (CertificateException e) {
            logger.error("Error converting the certificate", e);
            throw e;
        }
    }

Your calls to X509CertBuilder are generating a new certificate with a new key pair every time. 您对X509CertBuilder调用每次都会生成带有新密钥对的新证书。 If you already have the key pair generated (either from Java code or OpenSSL, etc.) just use the encoded certificate value to build the certificate object. 如果您已经生成了密钥对(通过Java代码或OpenSSL等生成),则只需使用编码的证书值来构建证书对象。

If you just have the key pair values but the public key is not formed into a certificate, use SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()); 如果仅具有密钥对值,但公共密钥未形成证书,则使用SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()); .

/**
     * Generates a self-signed {@link X509Certificate} suitable for use as a Certificate Authority.
     *
     * @param keyPair                 the {@link KeyPair} to generate the {@link X509Certificate} for
     * @param dn                      the distinguished name to user for the {@link X509Certificate}
     * @param signingAlgorithm        the signing algorithm to use for the {@link X509Certificate}
     * @param certificateDurationDays the duration in days for which the {@link X509Certificate} should be valid
     * @return a self-signed {@link X509Certificate} suitable for use as a Certificate Authority
     * @throws CertificateException      if there is an generating the new certificate
     */
    public static X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn, String signingAlgorithm, int certificateDurationDays)
            throws CertificateException {
        try {
            ContentSigner sigGen = new JcaContentSignerBuilder(signingAlgorithm).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(keyPair.getPrivate());
            SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
            Date startDate = new Date();
            Date endDate = new Date(startDate.getTime() + TimeUnit.DAYS.toMillis(certificateDurationDays));

            X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
                    reverseX500Name(new X500Name(dn)),
                    getUniqueSerialNumber(),
                    startDate, endDate,
                    reverseX500Name(new X500Name(dn)),
                    subPubKeyInfo);

            // Set certificate extensions
            // (1) digitalSignature extension
            certBuilder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment
                    | KeyUsage.keyAgreement | KeyUsage.nonRepudiation | KeyUsage.cRLSign | KeyUsage.keyCertSign));

            certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));

            certBuilder.addExtension(Extension.subjectKeyIdentifier, false, new JcaX509ExtensionUtils().createSubjectKeyIdentifier(keyPair.getPublic()));

            certBuilder.addExtension(Extension.authorityKeyIdentifier, false, new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(keyPair.getPublic()));

            // (2) extendedKeyUsage extension
            certBuilder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth}));

            // Sign the certificate
            X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
            return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);
        } catch (CertIOException | NoSuchAlgorithmException | OperatorCreationException e) {
            throw new CertificateException(e);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM