Rebex Security
XTS-AES and other handy security classes for .NET
Download 30-day free trial Buy from $199More .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...