Beispiel #1
0
        /// <summary>
        /// Authority Key Identifier is an optional field.  If present, it should be the key identifier of the parent.
        /// Absence of the field is a warning.  If present, bad linkage is an error.
        /// </summary>
        /// <returns></returns>
        internal bool CheckAuthKeyIdentifierLinkage()
        {
            bool ok = true;

            // alias to root
            for (int j = 0; j < NumCerts - 1; j++)
            {
                var signer  = Certs[j + 1];
                var target  = Certs[j];
                var akiData = target.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
                if (akiData == null)
                {
                    Warning($"Certificate does not contain an Authority Key Identifier Extension: {target.SubjectDN.ToString()}");
                    continue;
                }
                if (akiData != null)
                {
                    var aki         = new AuthorityKeyIdentifierStructure(akiData);
                    var signerKeyId = new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(signer.GetPublicKey()));
                    if (!signerKeyId.Equals(aki))
                    {
                        Error($"Authority Key Identifier does not match signer for certificate with subject: {target.SubjectDN.ToString()}");
                        ok = false;
                    }
                }
            }
            return(ok);
        }
Beispiel #2
0
        public X509Certificate2 Build()
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            // The Certificate Generator
            var certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            certificateGenerator.SetIssuerDN(new X509Name(_issuerName ?? _subjectName));
            certificateGenerator.SetSubjectDN(new X509Name(_subjectName));

            // Authority Key Identifier
            if (_issuer != null)
            {
                var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(
                    DotNetUtilities.FromX509Certificate(_issuer));
                certificateGenerator.AddExtension(
                    X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
            }

            // Basic Constraints - certificate is allowed to be used as intermediate.
            certificateGenerator.AddExtension(
                X509Extensions.BasicConstraints.Id, true, new BasicConstraints(_intermediate));

            // Valid For
            certificateGenerator.SetNotBefore(_notBefore ?? DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(_notAfter ?? DateTime.UtcNow.Date.AddYears(2));

            // Subject Public Key
            var keyGenerationParameters = new KeyGenerationParameters(random, _keyStrength);
            var keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            var issuerKeyPair  = _issuerPrivateKey == null
                ? subjectKeyPair
                : DotNetUtilities.GetKeyPair(_issuerPrivateKey);

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Signature Algorithm
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);

            // selfsign certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // Merge into X509Certificate2
            return(new X509Certificate2(certificate.GetEncoded())
            {
                PrivateKey = ConvertToRsaPrivateKey(subjectKeyPair)
            });
        }
        static void SetuthorityKeyIdentifier(X509V3CertificateGenerator generator, AsymmetricKeyParameter issuerPublic)
        {
            //Authority Key Identifier
            var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(issuerPublic);

            generator.AddExtension(
                X509Extensions.AuthorityKeyIdentifier, false, authorityKeyIdentifier);
        }
Beispiel #4
0
        /// <summary>
        /// Adds the authority key identifier to the certificate being generated. This allows 2 leaf certificates with the same CN to be
        /// identified.
        /// </summary>
        /// <param name="issuingCA">The Certificate of the CA issuing this cert.</param>
        /// <returns></returns>
        public CertificateBuilder AddAKID(AsymmetricKeyParameter publicKey)
        {
            var akid = new AuthorityKeyIdentifierStructure(publicKey);

            certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, akid);
            logger.Debug($"[AUTHORITY KEY IDENTIFIER] {akid.ToString()}");
            return(this);
        }
        private static X509Certificate2 GenerateSSLCertificate(string subjectName, X509Certificate2 issuer)
        {
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            var keyPairGenerator = new RsaKeyPairGenerator();

            keyPairGenerator.Init(new KeyGenerationParameters(random, KEY_STRENGTH));

            var keyPair = keyPairGenerator.GenerateKeyPair();

            var certificateGenerator = new X509V3CertificateGenerator();

            var certName     = new X509Name($"CN={subjectName}");
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);
            certificateGenerator.SetSubjectDN(certName);
            certificateGenerator.SetIssuerDN(certName);
            certificateGenerator.SetNotAfter(DateTime.Now.AddYears(100));
            certificateGenerator.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
            certificateGenerator.SetPublicKey(keyPair.Public);

            var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(DotNetUtilities.FromX509Certificate(issuer));

            certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);

            certificateGenerator.AddExtension(X509Extensions.KeyUsage.Id, false,
                                              new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.KeyEncipherment | KeyUsage.DigitalSignature));

            GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.DnsName, "localhost"));

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);

            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false,
                                              new ExtendedKeyUsage(new List <DerObjectIdentifier> {
                new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
            }));

            var issuerKeyPair = issuer == null
                ? keyPair
                : DotNetUtilities.GetKeyPair(issuer.PrivateKey);

            var signatureFactory = new Asn1SignatureFactory(ALGORITHM, issuerKeyPair.Private, random);
            var newCert          = certificateGenerator.Generate(signatureFactory);

            return(new X509Certificate2(newCert.GetEncoded())
            {
                PrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)keyPair.Private)
            });
        }
Beispiel #6
0
        public static string GetAuthorityKeyIdentifierFromCertificate(X509Certificate certificate)
        {
            Asn1OctetString authorityKeyIdentifierValue =
                certificate.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);

            if (authorityKeyIdentifierValue != null)
            {
                byte[] val = new AuthorityKeyIdentifierStructure(authorityKeyIdentifierValue).GetKeyIdentifier();
                if (val != null)
                {
                    return(Hex.ToHexString(new BigInteger(val).ToByteArray()));
                }
            }
            return(null);
        }
        private static X509Certificate2 GenerateCACertificate(string rootName, X509Certificate2 issuer = null)
        {
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            var certificateGenerator = new X509V3CertificateGenerator();

            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            certificateGenerator.SetIssuerDN(new X509Name($"CN={rootName}"));
            certificateGenerator.SetSubjectDN(new X509Name($"CN={rootName}"));

            if (issuer != null)
            {
                var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(
                    DotNetUtilities.FromX509Certificate(issuer));
                certificateGenerator.AddExtension(
                    X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
            }

            certificateGenerator.AddExtension(
                X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true));

            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date.AddHours(-12));
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(100));

            var keyGenerationParameters = new KeyGenerationParameters(random, KEY_STRENGTH);
            var keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            var issuerKeyPair  = issuer == null
                ? subjectKeyPair
                : DotNetUtilities.GetKeyPair(issuer.PrivateKey);

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            var signatureFactory = new Asn1SignatureFactory(ALGORITHM, issuerKeyPair.Private, random);
            var certificate      = certificateGenerator.Generate(signatureFactory);

            return(new X509Certificate2(certificate.GetEncoded())
            {
                PrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private)
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="domains"></param>
        /// <param name="subjectPublic"></param>
        /// <param name="validFrom"></param>
        /// <param name="validTo"></param>
        /// <param name="issuerName"></param>
        /// <param name="issuerPublic"></param>
        /// <param name="issuerPrivate"></param>
        /// <param name="CA_PathLengthConstraint">If non-null, the certificate will be marked as a certificate authority with the specified path length constraint (0 to allow no child certificate authorities, 1 to allow 1, etc).</param>
        /// <returns></returns>
        private static X509Certificate GenerateCertificate(string[] domains, AsymmetricKeyParameter subjectPublic, DateTime validFrom, DateTime validTo, string issuerName, AsymmetricKeyParameter issuerPublic, AsymmetricKeyParameter issuerPrivate, int?CA_PathLengthConstraint)
        {
            ISignatureFactory signatureFactory;

            if (issuerPrivate is ECPrivateKeyParameters)
            {
                signatureFactory = new Asn1SignatureFactory(
                    X9ObjectIdentifiers.ECDsaWithSha256.ToString(),
                    issuerPrivate);
            }
            else
            {
                signatureFactory = new Asn1SignatureFactory(
                    PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(),
                    issuerPrivate);
            }

            X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();

            certGenerator.SetIssuerDN(new X509Name("CN=" + issuerName));
            certGenerator.SetSubjectDN(new X509Name("CN=" + domains[0]));
            certGenerator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
            certGenerator.SetNotBefore(validFrom);
            certGenerator.SetNotAfter(validTo);
            certGenerator.SetPublicKey(subjectPublic);

            if (issuerPublic != null)
            {
                AuthorityKeyIdentifierStructure akis = new AuthorityKeyIdentifierStructure(issuerPublic);
                certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, akis);
            }
            if (CA_PathLengthConstraint != null && CA_PathLengthConstraint >= 0)
            {
                X509Extension extension = new X509Extension(true, new DerOctetString(new BasicConstraints(CA_PathLengthConstraint.Value)));
                certGenerator.AddExtension(X509Extensions.BasicConstraints, extension.IsCritical, extension.GetParsedValue());
            }

            // Add SANs (Subject Alternative Names)
            GeneralName[] names          = domains.Select(domain => new GeneralName(GeneralName.DnsName, domain)).ToArray();
            GeneralNames  subjectAltName = new GeneralNames(names);

            certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);

            return(certGenerator.Generate(signatureFactory));
        }
Beispiel #9
0
        /// <summary>
        /// Create a self signed certificate with bouncy castle.
        /// </summary>
        public static X509Certificate2 GenerateCertificate(
            string subjectName,
            Action <X509V3CertificateGenerator> modifyGenerator,
            string signatureAlgorithm = "SHA256WITHRSA",
            int publicKeyLength       = 2048,
            ChainCertificateRequest chainCertificateRequest = null)
        {
            if (string.IsNullOrEmpty(subjectName))
            {
                subjectName = "NuGetTest";
            }

            var random  = new SecureRandom();
            var keyPair = GenerateKeyPair(publicKeyLength);

            // Create cert
            var subjectDN = $"CN={subjectName}";
            var certGen   = new X509V3CertificateGenerator();

            certGen.SetSubjectDN(new X509Name(subjectDN));

            // default to new key pair
            var issuerPrivateKey = keyPair.Private;
            var keyUsage         = KeyUsage.DigitalSignature;
            var issuerDN         = chainCertificateRequest?.IssuerDN ?? subjectDN;

            certGen.SetIssuerDN(new X509Name(issuerDN));

#if IS_DESKTOP
            if (chainCertificateRequest != null)
            {
                if (chainCertificateRequest.Issuer != null)
                {
                    // for a certificate with an issuer assign Authority Key Identifier
                    var issuer   = chainCertificateRequest?.Issuer;
                    var bcIssuer = DotNetUtilities.FromX509Certificate(issuer);
                    var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(bcIssuer);
                    issuerPrivateKey = DotNetUtilities.GetKeyPair(issuer.PrivateKey).Private;
                    certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
                }

                if (chainCertificateRequest.ConfigureCrl)
                {
                    // for a certificate in a chain create CRL distribution point extension
                    var crlServerUri  = $"{chainCertificateRequest.CrlServerBaseUri}{issuerDN}.crl";
                    var generalName   = new Org.BouncyCastle.Asn1.X509.GeneralName(Org.BouncyCastle.Asn1.X509.GeneralName.UniformResourceIdentifier, new DerIA5String(crlServerUri));
                    var distPointName = new DistributionPointName(new GeneralNames(generalName));
                    var distPoint     = new DistributionPoint(distPointName, null, null);

                    certGen.AddExtension(X509Extensions.CrlDistributionPoints, critical: false, extensionValue: new DerSequence(distPoint));
                }

                if (chainCertificateRequest.IsCA)
                {
                    // update key usage with CA cert sign and crl sign attributes
                    keyUsage |= KeyUsage.CrlSign | KeyUsage.KeyCertSign;
                }
            }
#endif
            certGen.SetNotAfter(DateTime.UtcNow.Add(TimeSpan.FromHours(1)));
            certGen.SetNotBefore(DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)));
            certGen.SetPublicKey(keyPair.Public);

            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
            certGen.SetSerialNumber(serialNumber);

            var subjectKeyIdentifier = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public));
            certGen.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier);

            certGen.AddExtension(X509Extensions.KeyUsage.Id, false, new KeyUsage(keyUsage));
            certGen.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(chainCertificateRequest?.IsCA ?? false));

            // Allow changes
            modifyGenerator?.Invoke(certGen);

            var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey, random);
            var certificate      = certGen.Generate(signatureFactory);
            var certResult       = new X509Certificate2(certificate.GetEncoded());

#if IS_DESKTOP
            certResult.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters);
#endif

            return(certResult);
        }
 /// <summary>
 /// Initializes an AuthorityKeyIdentifier from an <see cref="AsymmetricKeyParameter"/>
 /// </summary>
 /// <param name="publicKey"><see cref="AsymmetricKeyParameter"/></param>
 public AuthorityKeyIdentifier(AsymmetricKeyParameter publicKey)
 {
     this.X509AuthorityKeyIdentifierStructure = new AuthorityKeyIdentifierStructure(publicKey);
 }
 /// <summary>
 /// Initializes a AuthorityKeyIdentifier from an <see cref="X509Certificate2"/>
 /// </summary>
 /// <param name="ca"><see cref="X509Certificate2"/></param>
 public AuthorityKeyIdentifier(X509Certificate2 ca)
 {
     Org.BouncyCastle.X509.X509Certificate x509Cert = DotNetUtilities.FromX509Certificate(ca);
     this.X509AuthorityKeyIdentifierStructure = new AuthorityKeyIdentifierStructure(x509Cert);
 }
Beispiel #12
0
        /// <summary>
        /// Builds the certificate depending on the parameters
        /// </summary>
        /// <returns>X509Certificate2 from the chosen parameters</returns>
        public X509Certificate2 Build()
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            // The Certificate Generator
            var certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            if (_signatureAlgorithm < 0 || (int)_signatureAlgorithm >= PKCS15SignatureAlgorithmList.Length)
            {
                _signatureAlgorithm = PKCS15SignatureAlgorithm.SHA256WITHRSA;
            }

            // Add SAN Extension
            if (_SubjectAlternativeName != null)
            {
                certificateGenerator.AddExtension
                (
                    X509Extensions.SubjectAlternativeName,
                    false,
                    SubjectAlternativeNamesToGeneralNames(_SubjectAlternativeName)
                );
            }

            // Issuer and Subject Name
            if (_DistinguishedName == null)
            {
                certificateGenerator.SetIssuerDN(new X509Name(_issuerName ?? _subjectName));
                certificateGenerator.SetSubjectDN(new X509Name(_subjectName));
            }
            else
            {
                if (_issuerName != null && _issuerName.Length > 0)
                {
                    certificateGenerator.SetIssuerDN(new X509Name(_issuerName));
                }
                else
                {
                    certificateGenerator.SetIssuerDN(DistinguishedNamesToX509Name(_DistinguishedName));
                }
                certificateGenerator.SetSubjectDN(DistinguishedNamesToX509Name(_DistinguishedName));
            }

            // Authority Key Identifier
            if (_issuer != null)
            {
                var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(
                    DotNetUtilities.FromX509Certificate(_issuer)
                    );
                certificateGenerator.AddExtension(
                    X509Extensions.AuthorityKeyIdentifier.Id,
                    false,
                    authorityKeyIdentifier
                    );
            }

            // Basic Constraints - certificate is allowed to be used as intermediate.
            certificateGenerator.AddExtension(
                X509Extensions.BasicConstraints.Id, true, new BasicConstraints(_intermediate));

            // Key intended purpose constrain
            if (_keyPurpose.Length > 0)
            {
                ArrayList kpList = new ArrayList();
                for (int i = 0; i < _keyPurpose.Length; i++)
                {
                    kpList.Add(new DerObjectIdentifier(_keyPurpose[i]));
                }
                IEnumerable kp = kpList;
                certificateGenerator.AddExtension(
                    X509Extensions.ExtendedKeyUsage.Id,
                    _criticalKeyPurpose,
                    new ExtendedKeyUsage(kp)
                    );
            }

            // Key usage
            if (_keyUsage > 0)
            {
                certificateGenerator.AddExtension(
                    X509Extensions.KeyUsage.Id,
                    _criticalKeyUsage,
                    new KeyUsage(_keyUsage)
                    );
            }

            // Valid For
            certificateGenerator.SetNotBefore(_notBefore ?? DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(_notAfter ?? DateTime.UtcNow.Date.AddYears(2));

            // Subject Public Key
            var keyGenerationParameters = new KeyGenerationParameters(random, _keyStrength);
            var keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            var issuerKeyPair  = _issuerPrivateKey == null
                ? subjectKeyPair
                : DotNetUtilities.GetKeyPair(_issuerPrivateKey);

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // self-sign certificate
            ISignatureFactory signatureFactory = new Asn1SignatureFactory(PKCS15SignatureAlgorithmList[(int)_signatureAlgorithm], issuerKeyPair.Private, random);
            var certificate = certificateGenerator.Generate(signatureFactory);

            // merge into X509Certificate2
            if (_friendlyName != null)
            {
                return(new X509Certificate2(certificate.GetEncoded())
                {
                    PrivateKey = ConvertToRsaPrivateKey(subjectKeyPair),
                    FriendlyName = _friendlyName
                });
            }
            return(new X509Certificate2(certificate.GetEncoded())
            {
                PrivateKey = ConvertToRsaPrivateKey(subjectKeyPair)
            });
        }
Beispiel #13
0
        /// <summary>
        ///
        /// </summary>
        /// <remarks>Based on <see cref="http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx"/></remarks>
        /// <param name="subjectName"></param>
        /// <returns></returns>
        public static void GenerateCertificate(string subjectName, DateTime expireOnUtc, byte[] issuingCertificate, string issuingCertificatePassword, out string password, out byte[] cerData, out byte[] pkcs12Data)
        {
            AsymmetricKeyParameter caPrivateKey;
            var caCert = ReadCertificateFromBytes(issuingCertificate, issuingCertificatePassword, out caPrivateKey);

            var caAuth    = new AuthorityKeyIdentifierStructure(caCert);
            var authKeyId = new AuthorityKeyIdentifier(caAuth.GetKeyIdentifier());

            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            var chars  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-()#$%^&@+=!";
            var rnd    = new Random();
            var result = new string(
                Enumerable.Repeat(chars, 15)
                .Select(s => s[rnd.Next(s.Length)])
                .ToArray());

            password = result;

            var gen      = new X509V3CertificateGenerator();
            var certName = new X509Name("CN=" + subjectName);
            var serialNo = BigInteger.ProbablePrime(120, random);

            gen.SetSerialNumber(serialNo);
            gen.SetSubjectDN(certName);
            gen.SetIssuerDN(caCert.IssuerDN);

            // gen.SetIssuerUniqueID(caCert.IssuerUniqueID.GetBytes())

            gen.SetNotAfter(expireOnUtc);
            gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
            gen.SetSignatureAlgorithm("SHA256WithRSA"); //("MD5WithRSA");

            var kpgen = new RsaKeyPairGenerator();

            kpgen.Init(new KeyGenerationParameters(random, 2048)); // new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            var subjectKeyPair = kpgen.GenerateKeyPair();

            gen.SetPublicKey(subjectKeyPair.Public);

            //gen.AddExtension(
            //    X509Extensions.ExtendedKeyUsage.Id,
            //    false,
            //    new ExtendedKeyUsage(new KeyPurposeID[] { KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPCodeSigning }));

            //1.3.6.1.5.5.7.3.1 = server authentication
            //1.3.6.1.5.5.7.3.2 = client authentication
            //1.3.6.1.5.5.7.3.3 = code signing

            var certificate = gen.Generate(caPrivateKey);

            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = X509CertificateHelper.GetCertificate(certificate.GetEncoded(), null, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);
            var seq  = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("Malformed sequence in RSA private key.");
            }

            var rsa = new RsaPrivateKeyStructure(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rsaparams);
            CspParameters cspParameters = new CspParameters();

            cspParameters.KeyContainerName = Guid.NewGuid().ToString(); // "MyKeyContainer";
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(2048, cspParameters);

            rsaKey.ImportParameters(rsaParameters);

            x509.PrivateKey = rsaKey;
            cerData         = x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert);
            pkcs12Data      = x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, password);
        }
Beispiel #14
0
        /// <summary>
        ///
        /// </summary>
        /// <remarks>Based on <see cref="http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx"/></remarks>
        /// <param name="subjectName"></param>
        /// <returns></returns>
        public static void GenerateCertificate(string subjectName, long serialNumber, DateTime expireOn, System.Security.Cryptography.X509Certificates.X509Certificate2 issuingCertificate, out string thumbprint, out string pemPrivateKey, out string pemPublicCert, out byte[] publicCert, out byte[] pkcs12Data, out string password)
        {
            AsymmetricKeyParameter caPrivateKey;
            var caCert = ReadCertificateFromX509Certificate2(issuingCertificate, out caPrivateKey);

            var caAuth    = new AuthorityKeyIdentifierStructure(caCert);
            var authKeyId = new AuthorityKeyIdentifier(caAuth.GetKeyIdentifier());

            // ---------------------------

            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

            var gen = new X509V3CertificateGenerator();

            // var certName = new X509Name("CN=" + subjectName);

            var list = new Dictionary <string, string>();

            AddItems(list, "CN", subjectName);
            AddItems(list, "O", "JFM Concepts, LLC");
            AddItems(list, "OU", "VDP Web");
            //var simpleCertName = GetItemString(list);
            //var certNameLight = new X509Name(simpleCertName);

            list.Add("L", "Boulder");
            list.Add("ST", "Colorado");
            list.Add("C", "US");
            var subjectFull = GetItemString(list);
            var certName    = new X509Name(subjectFull);


            BigInteger serialNo;

            if (serialNumber == 0)
            {
                serialNo = BigInteger.ProbablePrime(120, random);
            }
            else
            {
                serialNo = BigInteger.ValueOf(serialNumber);
            }
            gen.SetSerialNumber(serialNo);
            gen.SetSubjectDN(certName);

            gen.SetIssuerDN(caCert.IssuerDN);

            var issuerPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(caCert.GetPublicKey());
            var issuerGeneralNames  = new GeneralNames(new GeneralName(caCert.IssuerDN));
            var issuerSerialNumber  = caCert.SerialNumber;

            var authorityKeyIdentifier = new AuthorityKeyIdentifier(issuerPublicKeyInfo, issuerGeneralNames, issuerSerialNumber);

            gen.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, true, authorityKeyIdentifier);

            // gen.SetIssuerUniqueID(caCert.IssuerUniqueID.GetBytes())

            gen.SetNotAfter(expireOn);
            gen.SetNotBefore(DateTime.Now.AddHours(-2));
            gen.SetSignatureAlgorithm("SHA256WithRSA"); //("MD5WithRSA");

            var kpgen = new RsaKeyPairGenerator();

            kpgen.Init(new KeyGenerationParameters(random, 2048)); // new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            var subjectKeyPair = kpgen.GenerateKeyPair();

            gen.SetPublicKey(subjectKeyPair.Public);

            gen.AddExtension(
                X509Extensions.ExtendedKeyUsage.Id,
                false,
                new ExtendedKeyUsage(new KeyPurposeID[] { KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPCodeSigning }));

            //1.3.6.1.5.5.7.3.1 = server authentication
            //1.3.6.1.5.5.7.3.2 = client authentication
            //1.3.6.1.5.5.7.3.3 = code signing

            var certificate = gen.Generate(caPrivateKey);

            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
            var seq  = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("Malformed sequence in RSA private key.");
            }

            var rsa = new RsaPrivateKeyStructure(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            //-------------

            //RsaPrivateCrtKeyParameters rsaparams = (RsaPrivateCrtKeyParameters)subjectKeyPair.Private;
            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rsaparams);
            CspParameters cspParameters = new CspParameters();

            cspParameters.KeyContainerName = Guid.NewGuid().ToString(); // "MyKeyContainer";
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(2048, cspParameters);

            rsaKey.ImportParameters(rsaParameters);

            // ------------

            x509.PrivateKey = rsaKey; // DotNetUtilities.ToRSA(rsaparams);

            // Generating Random Numbers
            var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-()#$%^&@+=!";
            var rnd   = new Random();

            password = new string(
                Enumerable.Repeat(chars, 15)
                .Select(s => s[rnd.Next(s.Length)])
                .ToArray());
            thumbprint = x509.Thumbprint.ToLower();
            publicCert = x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert);

            var privateKeyPem       = new StringBuilder();
            var privateKeyPemWriter = new PemWriter(new StringWriter(privateKeyPem));

            privateKeyPemWriter.WriteObject(certificate);
            privateKeyPemWriter.WriteObject(subjectKeyPair.Private);
            privateKeyPemWriter.Writer.Flush();
            pemPrivateKey = privateKeyPem.ToString();

            var publicKeyPem       = new StringBuilder();
            var utf8WithoutBom     = new System.Text.UTF8Encoding(false);
            var publicKeyPemWriter = new PemWriter(new StringWriterWithEncoding(publicKeyPem, utf8WithoutBom));

            publicKeyPemWriter.WriteObject(certificate);
            publicKeyPemWriter.Writer.Flush();
            pemPublicCert = publicKeyPem.ToString();
            pemPublicCert = pemPublicCert.Replace(Environment.NewLine, "\n"); //only use newline and not returns

            pkcs12Data = x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pfx, password);
        }