Rebex Security
XTS-AES and other handy security classes for .NET
Download 30-day free trial Buy from $99More .NET libraries
-
Rebex SFTP
.NET SFTP client
-
Rebex SSH Shell
.NET SSH Shell
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
X.509 certificates
On this page:
Issuing self-signed (or root CA) certificates
To issue a self-signed root CA certificate, use CertificateIssuer
class:
// prepare certificate info var info = new CertificateInfo(); // specify certificate validity range info.EffectiveDate = DateTime.Now.AddDays(-1); info.ExpirationDate = info.EffectiveDate.AddYears(10); // specify certificate subject (becomes an issuer as well for self-signed certificates) info.Subject = new DistinguishedName("CN=Custom CA, E=self@example.org"); // specify certificate usage for a CA certificate info.Usage = KeyUses.DigitalSignature | KeyUses.KeyCertSign | KeyUses.CrlSign; // sets a unique serial number info.SetSerialNumber(Guid.NewGuid().ToByteArray()); // use SHA-256 signature algorithm info.SignatureHashAlgorithm = HashingAlgorithmId.SHA256; // generate a 2048-bit RSA key for the certificate PrivateKeyInfo privateKey; using (var alg = new AsymmetricKeyAlgorithm()) { alg.GenerateKey(AsymmetricKeyAlgorithmId.RSA, 2048); privateKey = alg.GetPrivateKey(); } // create the self-signed certificate Certificate certificate = CertificateIssuer.Issue(info, privateKey); // associate the private key with the certificate certificate.Associate(privateKey); // save the certificate along with its private key to an encrypted PFX/P12 file // (make sure to keep this in a secure location) certificate.Save("cacert.pfx", CertificateFormat.Pfx, "password"); // save the certificate (without the private key) to a file certificate.Save("cacert.cer", CertificateFormat.Base64Der);
The same approach can be used to issue self-signed user certificates - just specify the appropriate usage and e-mail address:
// specify certificate subject info.Subject = new DistinguishedName("CN=Self-signed Certificate, E=someone@example.org"); // set mail address for a client certificate info.MailAddress = "someone@example.org"; // specify certificate usage for a client or server certificate info.Usage = KeyUses.DigitalSignature | KeyUses.KeyEncipherment | KeyUses.DataEncipherment; // specify certificate extended usage for a client certificate info.SetExtendedUsage(ExtendedUsageOids.ClientAuthentication, ExtendedUsageOids.EmailProtection);
Issuing certificate signed by a custom CA
It's easily possible to implement a simple custom root certification authority (CA) that can issue and sign certificates:
// load the CA certificate (or retrieve it from store) Certificate ca = Certificate.LoadPfx("cacert.pfx", "password"); // prepare certificate info var info = new CertificateInfo(); // specify certificate validity range info.EffectiveDate = DateTime.Now.AddDays(-1); info.ExpirationDate = info.EffectiveDate.AddYears(1); // specify certificate subject for a client certificate info.Subject = new DistinguishedName("CN=Sample Certificate, E=someone@example.org"); // set mail address for a client certificate info.MailAddress = "someone@example.org"; // specify certificate usage for a client certificate info.Usage = KeyUses.DigitalSignature | KeyUses.KeyEncipherment | KeyUses.DataEncipherment; // specify certificate extended usage for a client certificate info.SetExtendedUsage(ExtendedUsageOids.ClientAuthentication, ExtendedUsageOids.EmailProtection); // sets a unique serial number info.SetSerialNumber(Guid.NewGuid().ToByteArray()); // use SHA-256 signature algorithm info.SignatureHashAlgorithm = HashingAlgorithmId.SHA256; // add CRL distribution points (optional) //info.CrlDistributionPoints.Add(new CrlDistributionPoint("http://example.org/crl/TestRootCA.crl")); // generate a 2048-bit RSA key for the certificate PrivateKeyInfo privateKey; using (var alg = new AsymmetricKeyAlgorithm()) { alg.GenerateKey(AsymmetricKeyAlgorithmId.RSA, 2048); privateKey = alg.GetPrivateKey(); } // create the certificate signed by the CA certificate PublicKeyInfo publicKey = privateKey.GetPublicKey(); Certificate certificate = CertificateIssuer.Issue(ca, info, publicKey); // associate the private key with the certificate certificate.Associate(privateKey); // save the certificate along with its private key to an encrypted PFX/P12 file // (make sure to keep this in a secure location) certificate.Save("mycert.pfx", CertificateFormat.Pfx, "password"); // save the certificate (without the private key) to a file certificate.Save("mycert.cer", CertificateFormat.Base64Der);
The same approach can be used to issue server certificates - just specify appropriate usage and host names:
// specify certificate subject info.Subject = new DistinguishedName("CN=example.org, E=someone@example.org"); // specify server hostnames info.SetAlternativeHostnames("example.org", "www.example.org"); // specify certificate usage for a server certificate info.Usage = KeyUses.DigitalSignature | KeyUses.KeyEncipherment | KeyUses.DataEncipherment; // specify certificate extended usage for a server certificate info.SetExtendedUsage(ExtendedUsageOids.ServerAuthentication);
Issuing CRL for a custom CA
To issue a certificate revocation list (CRL) for your custom CA, use the following code:
// load the CA certificate (or retrieve it from store) Certificate ca = Certificate.LoadPfx("cacert.pfx", "password"); // get a list of revoked certificates (to be provided by custom code) IEnumerable<Certificate> revokedCertificates = GetRevokedCertificates(); // specify CRL validity info var listInfo = new RevocationListInfo(); listInfo.ThisUpdate = DateTime.Now.AddDays(-1); listInfo.NextUpdate = listInfo.ThisUpdate.AddMonths(1); // construct revoked certificate info collection var revokedCollection = new RevokedCertificateCollection(); foreach (var cert in revokedCertificates) { revokedCollection.Add(new RevokedCertificate(cert.GetSerialNumber(), DateTime.Now, RevocationReason.Unspecified)); } // issue the certificate revocation list (CRL) CertificateRevocationList crl = CertificateIssuer.IssueRevocationList(ca, SignatureHashAlgorithm.SHA256, listInfo, revokedCollection); // save the CRL // (the result should be published to desired location such as "http://yoursite.com/crl/TestRootCA.crl") File.WriteAllBytes("TestRootCA.crl", crl.ToArray());
Adding certificates to store
To add a certificate to user's certificate store, use CertificateStore
object's Add
method:
// load a user certificate certificate with associated private key, // add the certificate to current user's certificate store // and add the key to current user's key store Certificate certificate = Certificate.LoadDer("mycert.cer"); using (CertificateStore store = new CertificateStore(CertificateStoreName.My, CertificateStoreLocation.CurrentUser)) { store.Add(certificate); } // load the public part of a CA certificate // and add it current user's trusted root certification authority store // (beware - this will make it trusted by other Windows applications as well) Certificate ca = Certificate.LoadDer("cacert.cer"); using (CertificateStore store = new CertificateStore(CertificateStoreName.Root, CertificateStoreLocation.CurrentUser)) { // this will present a dialog asking for confirmation store.Add(ca); }
Back to feature list...