A PKCS#12 key storage is a password protected key container that associates keys and X.509 certificates with aliases – often the Thumbprint of the certificate. A common file name extension used is .p12 or .pfx.
+----------+----------------+ | Alias 1 | Certificate 1 | | | Key 1 | +---------------------------+ | Alias 2 | Certificate 2 | +---------------------------+ | Alias 3 | Key 3 | |----------+----------------+
In OpenSSL Library for .NET the class DidiSoft.OpenSsl.PfxStore represents a PKCS#12 store. The samples below demonstrate its usage.
Table of contents
Create empty
To create an empty PKCS#12 store we just use the empty parameter constructor:
PfxStore store = new PfxStore(); |
Load
In order to load an existing .pfx or .p12 store file we must know its protection password in advance:
PfxStore store = PfxStore.Load("mystore.pfx", "my password"); |
If the provided password is wrong a DidiSoft.OpenSsl.Exceptions.WrongPasswordException will be thrown.
Save
Saving the PKCS#12 store requires a protection password to be specified. This is also the way to change the password – by saving it with the new one.
store.Save("myca.pfx", "my ca password"); |
Add Entries
There are basically two main types of entries that you will be adding to a PKCS#12 key store: X509 Certificates and private keys. Each entry added to the key storage is associated with an alias (like a key in a Hash table). Usually the alias can be anything, but by default in the methods where you can omit the alias, the library will put the certificates CN (common name) property.
For example:
using DidiSoft.OpenSsl; using DidiSoft.OpenSsl.Rsa; using DidiSoft.OpenSsl.X509; class PfxInsertItemsDemo { public void Demo() { var rsa = new OpenSslRsa(); var kp = rsa.GenerateRsaKeyPair(KeyLength.Length1024); var props = new X509Name() { CN = "test" }; var cert = Certificate.CreateSelfSignedCertificate(kp.Public, kp.Private, props); var pfxStore = new PfxStore(); pfxStore.AddCertificate(cert); pfxStore.AddPrivateKey(kp.Private); pfxStore.Save("myPublicPrivateKey.pfx", "somePassword"); } } |
In the example code block above both, the certificate and its private key will be inserted under the alias with value cert.Subject.CommonName like:
pfxStore.AddCertificate(cert.Subject.CommonName, cert); pfxStore.AddPrivateKey(cert.Subject.CommonName, kp.Private); |
List of Entries
List of Aliases
The list of aliases contained inside the key store can be retrieved with:
string[] aliases = store.GetAliases(); |
or traverse aliases one by one with:
1 2 3 4 | for (int i = 0; i < store.AliasesCount; i++) { Console.WriteLine(store.GetAlias(i)); } |
For each alias we can get the corresponding certificate or private key with:
DidiSoft.OpenSsl.X509Certificate cert = store.GetCertificate(alias); DidiSoft.OpenSsl.PrivateKey key = store.GetPrivateKey(alias); |
List of Certificates and keys
We can also get only the Certificates:
DidiSoft.OpenSsl.X509.Certificate[] certificates = store.GetCertificates(); |
or only the private keys:
DidiSoft.OpenSsl.PrivateKey[] certificates = store.GetPrivateKeys(); |
X509Certificate2 from key and Certificate
In times when need to create quickly a System.Security.Cryptography.X509Certificates.X509Certificate2 instance from a certificate and private key we can use the static method PfxStore.CreateX509Certificate2 like:
DidiSoft.OpenSsl.KeyPair key = DidiSoft.OpenSsl.KeyPair.GenerateKeyPair(KeyAlgorithm.Rsa, KeyLength.Length1024); DidiSoft.OpenSsl.X509.Certificate cert = Certificate.CreateSelfSignedCertificate(key.Public, key.Private, new X509Name(){CN = "MyCN"}); X509Certificate2 crt = DidiSoft.OpenSsl.PfxStore.CreateX509Certificate2(cert, key.Private, "my password"); |
Summary
This article introduced the PfxStore class, a key container for private keys and X.509 certificates. This storage is especially useful for protecting a Certificate Authority private key and its certificate.