Create certificate with Subject Alternative name programmatically.

ameenfusion
ameenfusion used Ask the Experts™
on
Hi Experts,

I want  to create certificate with .Net code and would like to add subject alternative name to it.

I want to use this certificate in production environment and distribute it to clients.

(not using makecert). I would appreciate if you could give me code using

system.security.cryptography namespace.

Thanks.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2011

Commented:
Top Expert 2011

Commented:
by the way it's mono implementation
you can get all code and change some using

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
Top Expert 2011

Commented:
see also antoher ways to do it
Creating a Self-Signed SSL Certificate without a mess of makecert.exe (using SSL Diagnostics Tool)
http://tcle.wordpress.com/2008/05/20/creating-a-self-signed-ssl-certificate-without-a-mess-of-makecertexe-using-ssl-diagnostics-tool/

Author

Commented:
Thank you very much for your quick response.this code is used to geenrate a certificate with subject and validity with password but my requirement is to add Subject Altenative name(SAN) to the certificate. So my question is How can I add SAN code t o the existing code of creating a certificate?
Hi Experts,

I am pleased to inform that I have generated the certificate using Bouncy Castle C# API and I would like to share the solution here.
private static readonly char[] passwd = "hello".ToCharArray();
       
        private static AsymmetricCipherKeyPair GenerateKeys(int keySize)
        {
            var gen = new RsaKeyPairGenerator();
            var secureRandom = new SecureRandom();
            var keyGenParam = new KeyGenerationParameters(secureRandom, keySize);
            gen.Init(keyGenParam);
            return gen.GenerateKeyPair();
        }
        private static byte[] GetSignature(string plainText, RsaKeyParameters privateKey)
        {
            var encoder = new ASCIIEncoding();
            var inputData = encoder.GetBytes(plainText);

            var signer = SignerUtilities.GetSigner("SHA1WithRSAEncryption");
            signer.Init(true, privateKey);
            signer.BlockUpdate(inputData, 0, inputData.Length);

            return signer.GenerateSignature();
        }
             

        private static bool VerifySignature(RsaKeyParameters publicKey, string plainText, byte[] signature)
        {
            var encoder = new ASCIIEncoding();
            var inputData = encoder.GetBytes(plainText);
            var signer = SignerUtilities.GetSigner("SHA384WithRSAEncryption");
            signer.Init(false, publicKey);
            signer.BlockUpdate(inputData, 0, inputData.Length);
            return signer.VerifySignature(signature);
        }
        public void GenerateX509Certificate()
        {
            RsaKeyParameters publicKey;
            RsaKeyParameters privateKey;
            byte[] Signature;
            string publicKeyModulas, publicKeyExponent, privateKeyModulas, privateKeyExponent, signatureString;
           
            var key = GenerateKeys(4096);

             publicKey = (RsaKeyParameters)(key.Public);
             privateKey = (RsaKeyParameters)(key.Private);
             //get public key
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
             byte[] serializedPublic = publicKeyInfo.ToAsn1Object().GetDerEncoded();
                string pk=Convert.ToBase64String(serializedPublic);
                StreamWriter sw = new StreamWriter("C:\\Users\\path_to_private_key_directory\\myPkey.txt");
                sw.Write(pk);
                sw.Close();
            string xmlLicense = "XML License"; //Unencrypyed                

            Signature = GetSignature(xmlLicense, privateKey);
            #region Setting the required values
            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
            certGen.SetIssuerDN(new X509Name("Give IIssuer details here"));
            certGen.SetSubjectDN(new X509Name("C=GB"));
            certGen.SetSerialNumber(BigInteger.One);
            certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1));
            certGen.SetNotAfter(DateTime.UtcNow.AddDays(30));
            certGen.SetPublicKey(publicKey);
            certGen.SetSignatureAlgorithm("SHA1WithRSAEncryption");
            #endregion
         
            #region Adding Extensions
            certGen.AddExtension(
                X509Extensions.SubjectKeyIdentifier,
                false,
                new SubjectKeyIdentifierStructure(publicKey));
           GeneralNames issuerAltName=new GeneralNames(new GeneralName(new X509Name("C=GB")));
           certGen.AddExtension(X509Extensions.IssuerAlternativeName, false, issuerAltName);
            Asn1EncodableVector vector = new Asn1EncodableVector();
            vector.Add(new GeneralName(new X509Name("C=GB")));
            vector.Add(new GeneralName(new X509Name("C=GB,O=K")));
           
            Asn1Sequence seq = new DerSequence(vector);
            GeneralNames subjectAltName = GeneralNames.GetInstance(seq);                
            certGen.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);                
             X509Extensions ex = new X509Extensions(order, extensions);
                     
            #endregion

            X509Certificate cert = certGen.Generate(privateKey);
            cert.CheckValidity(DateTime.UtcNow);
            cert.Verify(publicKey);
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);
            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            store.SetKeyEntry("Test Key", new AsymmetricKeyEntry(privateKey), new X509CertificateEntry[] { certEntry });
            FileStream fOut = File.Create("BouncyCertificate.p12");
            store.Save(fOut, passwd, new SecureRandom());
            fOut.Close();
This code will programmatically generate a certificate and will add Subject Alternative Name to the Certificate.
Many Thanks.
             

Author

Commented:
This certificate is generated programmatically and it includes Subject Alternative name which was my requirement.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial