Manage X.509 Certificates and Certificate Stores (2024)


Manage Certificates and Certificate Stores
A digital certificate is a data structure that stores someone's personalinformation such as a name or email address, together with thisperson's public key. This data is signed by a certification authority (CA)who issued the certificate.

A certificate can exist in a file or certificate store in the system registry.

It is highly recommended that you install the CertMgr.exe application as it will make the debugging of certificate-related applications easier.CertMgr.exe is included in the Microsoft Platform SDK CD ROM.If you are running IE 5.0, CertMgr.exe is already installed on your machine.To invoke it, open IE 5.0, go to Tools/Internet Options, select the Content tab and clickthe "Certificates" button.

Opening a Certificate Store
Certificates stores are kept in the system registryunder the keys HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates andHKEY_CURRENT_USER\Software\Microsoft\SystemCertificates.

Each user has aMY certificate store which contains his/her personal certificates. The ROOT storecontains certificates of the most trusted certification authorities.The CA store contains less frequently used certification authorities.The AddressBook store contains other people's certificates.

In AspEncrypt, a certificate store is represented by the CryptoStore object.An instance of this object is created via CryptoManager's OpenStore method, as follows:

Set Store = CM.OpenStore("MY", False )

The OpenStore method accepts two arguments: the name of the store and a flag specifyingwhether the store is located under the HKEY_LOCAL_MACHINE (if set to True ) or HKEY_CURRENT_USER (if set to False) section of the system registry.The following rule of thumb applies in most cases: if you areusing AspEncrypt in a stand-alone application (suchas a VB program) you should specify False for the second parameter.If AspEncrypt is used from an ASP or ISAPI application, you should specify True.

If the store name passed as the first parameter does not exist, the method will create it.

In an ASP environment, if anonymous access is enabled, an attempt toopen a store will probably result in an Access Denied error. To avoid this error, impersonation of an admin account should be used, as follows:

<%
Set CM = Server.CreateObject("Persits.CryptoManager")
CM.LogonUser "domainname", "adminuser", "xxx"
Set Store = CM.OpenStore("MY", True)
%>

For the LogonUser method to work successfully, the current user must have the"Act as Part of Operating System" privilege.

Enumerating Certificates in a Store

The CryptoStore object has a property, Store.Certificates, which returns the collection of CryptoCert objects which represent certificates residing in this store. The following code snippetenumerates all certificates in the ROOT store of the HKLM sectionof the registry:

<%
Set CM = Server.CreateObject("Persits.CryptoManager")
CM.LogonUser "mydomain", "adminuser", "xxx"
Set Store = CM.OpenStore("ROOT", True)
For Each Cert in Store.Certificates
Response.Write Cert.Subject.Name & "<P>"
Next
%>

A more complete certificate store example can be foundin the file Samples\cert_stores\certs.asp of the installation.

Examining Certificates using CertMgr.exe

Run CertMgr.exe (included with IE 5.0 or available from Microsoft Platform SDK.) You will see a screensimilar to this:

Manage X.509 Certificates and Certificate Stores (3)

If you double-click on one of the certificates in the list, the certificate property sheet comes up:

Manage X.509 Certificates and Certificate Stores (4)

Obtaining an Instance of the CryptoCert Object
AspEncrypt provides the CryptoCert object to represent a certificate. Thereis a number of ways to obtain an instance of the CryptoCert object. We have already learned how to use the CryptoStore.Certificates collectionto enumerate all certificates in a store. The Certificates collectionalso allows you to obtain individual certificate objects as well.

Just like anyCOM collection, Store.Certificates supports a default Item property which accepts an integer or string index. The string index specifiesa certificate's serial number as displayed by the certificate property sheet shown above.For example, to obtain a CryptoCert object representing the Thawte Freemail Membercertificate shown on the screenshot above, we can say:

Set CM = Server.CreateObject("Persits.CryptoManager")
Set Store = CM.OpenStore("MY", False)
Set Cert = Store.Certificates.Item("012E 78") '
Paste Serial Number here

A certificate's serial number can simply be copies and pasted fromthe certificate property sheet. Since Certificates.Item is a default propertywe can omit the word Item. Also, this property ignores spaces in the index value, so the following code is acceptable as well:

...
Set Cert = Store.Certificates("012E78") '
No spaces is OK too

A CryptoCert object can also be created from a certificate stored in a file.There are two most commonly used file formats for storing certificates: DER-Encoded X.509 (.cer or .crt) and Cryptographic Message Syntax Standard PKCS #7 (.p7b).The DER-Encoded format can be in the binary or Base64-encoded form.

AspEncrypt imports a .cer file into a CryptoCert object using the CryptoManager.ImportCertFromFile method, as follows:

<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Cert = CM.ImportCertFromFile("d:\somecert.cer")
' Do something with the Cert object
%>

The ImportCertFromFile method automatically determines whether the fileis in a binary or Base64-encoded form.

To import a certificate in the PKCS#7 format, the CryptoManager.ImportStoreFromFile methodshould be used as a file in this format may contain several certificates at once.Once a CryptoStore object is created from the file, individual certificates can be obtainedfrom it using the Certificates collection as explained above. For example:

<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Store = CM.ImportStoreFromFile("d:\somecert.p7b")
Set Cert = Store.Certificates(1) '
We use an integer index here
' Do something with the Cert object
%>

There is also the PKCS#12 (also known as PFX) format for storing certificates togetherwith their respective private keys using password protection. See the section Support for PKCS#12 (a.k.a. PFX) Format below for details.

Accessing Client Certificates via ASP's Request.ClientCertificate
You may configure a virtual directory or the entire web site to accept (or require)client certificates. When trying to access such a resource, a userwill be prompted by the browser to select one of his client certificates.A certificate selected this way will be uploaded to the server and becomeavailable to server-side ASP script via the Request.ClientCertificate collection.

AspEncrypt 1.1 is capable of capturing the Request.ClientCertificate information and save into a file or import it into a CryptoCert object.This is done with the help of the CryptoBlob object as follows:

<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Blob = CM.CreateBlob
Blob.Binary = Request.ClientCertificate("Certificate")
If Len(Blob.Hex) > 0 Then
Set Cert = CM.ImportCertFromBlob(Blob)
' Do something with the Cert object
Else
Response.Write "No certificate received."
End
%>

Starting with Windows 2003 and IIS 6.0, due to changes in the format of data returned by Request.ClientCertificate,the direct assignment of the certificate information to Blob.Binary should be replacedby a two-step process via a temporary variable, as shown below.Otherwise, the error ASN1 bad tag value met will be generated.

<%
...
Set Blob = CM.CreateBlob
Temp = Request.ClientCertificate("Certificate")
Blob.Binary = Temp
...
%>

Browsing the Issuer and Subject Properties
Some CryptoCert properties such as Cert.Version, Cert.SerialNumber, Cert.NotAfter, Cert.NotBefore, etc.are fairly self-explanatory. Others do deserve our attention.

The Issuer and Subject properties return CryptoNameobjects which contain information about the issuer authorityand the entity to whom the certificate is being issued, respectively.The CryptoName object has a default Item property which accepts an optionalindex argument. For the Thawte certificate shown above the expression Cert.Issuer.Item(or simply Cert.Issuer as Item is the default property) returns the following string:

C=ZA
S=Western Cape
L=Durbanville
O=Thawte Consulting
OU=Thawte PF RSA IK 1998.9.16 17:55
CN=Thawte Personal Freemail RSA Issuer 1998.9.16

The expression Cert.Subject returns the following string:

CN=Thawte Freemail Member
E=persits@vni.net

You can see that a certificate's Subject and Issuer properties consistof several tagged components separated by a CR/LF sequence. The most common ones are CN (common name), E (email), O (organization), OU (organizational unit),L (locale), S (state), and C (country).The CryptoName object allows you to obtain individual components of a nameby specifying the appropriate tag as Item's argument. For example, the expressionCert.Issuer("CN") returns

Thawte Personal Freemail RSA Issuer 1998.9.16

The CryptoName object also provides the property Name, whichlooks for the components CN, OU, O, and E in this orderand returns the first one found.

Obtaining a Certificate's Private Key
Each of your personal certificates installed on your machine has a private key associated with it. This private key is stored in a key container in the system registryand can be obtained by opening the appropriate cryptographic context.This allows you to use your personal certificates to, say, generate digital signatures.Certificates from other people and certification authorities obviously don't have associated private keys (on your machine, that is).

The CryptoCert object provides a Boolean property, PrivateKeyExists,which returns True if this certificate has an associated private key on this machine.You can obtain the corresponding certificate context by calling the propertyPrivateKeyContext which returns an instance of the CryptoContext object.

The following code snipped was run against the Thawte certificate shown above:

' VB Code
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Store = CM.OpenStore("MY", False)
Set Cert = Store.Certificates("012E 78")
Set Context = Cert.PivateKeyContext
MsgBox Context.Container

The result was "Administrator". This means that the private key correspondingto this certificate is located under the key

HKEY_CURRENT_USER\Software\Microsoft\Cryptography\UserKeys\Administrator.

With AspEncrypt, you can also set the private key context of a certificateusing the Cert.SetPrivateKeyContext method. This method can be useful when issuing your own certificates. However, you should be careful withthis method as you may accidentally make a certificate point to the wrongprivate key, that is, not the private key this certificate's public key corresponds to.

The Underwater Rocks of CryptoAPI
AspEncrypt is based on the CryptoAPI. Under certain conditions, some CryptoAPIfunctions display warning messages, such as this one:

Manage X.509 Certificates and Certificate Stores (5)

Th conditions under which the CryptoAPI displays warning messages include,but are not limited to, the following:

  • An attempt to add a certificate to, or remove a certificate from, the HKEY_CURRENT_USER-based ROOT store.
  • An attempt to generate a signature with a private key createdwith the security flag set to USER_PROTECTED and stored in an HKEY_CURRENT_USER-based key container.
  • An attempt to decrypt an encrypted message with a private key createdwith the security flag set to USER_PROTECTED and stored in an HKEY_CURRENT_USER-based key container..
Performing these tasks with AspEncrypt in an ASP environment will resultin hanging up the web server. However, this is not the casefor stores and private keys located in the HKEY_LOCAL_MACHINE section of the registry.
Moving Certificates with their Private Keys to HKEY_LOCAL_MACHINE
When using AspEncrypt in an ASP environment to perform private key-relatedoperations such as generating signed mail messages, you should move thepersonal certificates you want to use from the HKEY_CURRENT_USER to HKEY_LOCAL_MACHINE section of the registry. This way you make these certificatesreadily available to your ASP application and remove the USER_PROTECTED flagfrom the corresponding private keys to avoid the "underwater rock" problem just described.

To facilitate the moving procedure, AspEncrypt provides a method, Cert.TransferToLocalMachine, which moves the certificate to the specified HKEY_LOCAL_MACHINE store together with its private key.

The following VB code snippet does the job:

Dim Cert As ICryptoCert
Dim Store As ICryptoStore
Set Store = CM.OpenStore("MY", False) '
Open MY store at HKCU
Set Cert = Store.Certificates("012E 78") '
Obtain my Thawte cert
Cert.TransferToLocalMachine "MY" '
Transfer to MY store at HKLM

The AspEncrypt installation includes CertMover.exe, a sample VB applicationwith the source code includedwhich you can use to transfer certificates from the HKCU to HKLM sectionsof the registry. This application can be found in the directory\Samples\cert_stores\CertMover of the installation.

For a private key to be movable (or otherwise exportable), it must have been created with the CRYPT_EXPORTABLE flag set. Otherwise, whenattempting to use the CertMover application, you will receive a Bad Key error message:

Manage X.509 Certificates and Certificate Stores (6)

The certificate enrollment proceduresimplemented by VeriSign and Thawte do not normallygive you the opportunity to specify the CRYPT_EXPORTABLE flagwhen your private key is being created. As a result, you cannotmove your certificate to HKEY_LOCAL_MACHINE, and you end up not being ableto use it for digital signing in an ASP environment.

Therefore, if you want to be able to send digitally signed mail from ASP,you must take the process of generating a private key and correspondingCertificate Request file into your own hands. The next section explains how to do it.

Obtaining a "Friendly" Certificate from VeriSign™
We have provided an on-line Web page which contains everything you need to
  • create a private key with the CRYPT_EXPORTABLE flag set;
  • generate a certificate request file (CRF) necessary to apply for a certificate from a certification authority;
  • send the CRF to VeriSign™ in order to obtain a client certificate which youwill be able to use for digital signing in the ASP environment;
  • install the certificate received from VeriSign.
This page uses the Microsoft XEnroll ActiveX control andclient-side VB script, so it requires Internet Explorer 4.0+.

This page is available on the AspEncrypt.com web site atwww.aspencrypt.com/get_cert.htm.Follow the step-by-step instructions to obtain a certificate whichyou will be able to move to the HKEY_LOCAL_MACHINE section of the registryand use it to generate digitally signed mail. Secure mail is our next topic.

Support for PKCS#12 (a.k.a. PFX) Format
Starting with version 2.0, AspEncrypt supports a special file formatthat stores certificates together with their private keys.Private key information in such a file is protected with a password. This file formatis known as PKCS#12, or Personal Information Exchange (PFX).PFX files usually have the extensions .pfx or .p12.

Thanks to AspEncrypt's support for PFX format, you no longer need to gothrough the trouble of moving a certificate to the HKEY_LOCAL_MACHINEsection of the registry to get hold of its private key. All you need to dois export your certificate into a PFX file and place this file on the serverwhere AspEncrypt can access it.

To export a certificate from your personal certificate store into a PFX file,open IE or Netscape and bring up the list of your personal certificates. Selecta certificate and choose "Export". IE will ask you whether you want to exportthe private key with the certificate, and you should say "Yes." Netscapealways exports the certificate's private key. You willalso be asked to specify a password that will be used to encrypt your certificate's privatekey information. You will be using this password in your code to open the PFX file.

To retrieve a certificate from a PFX file with AspEncrypt, use themethod CM.OpenStoreFromPFX which returns a CryptoStore objectrepresenting all certificates contained in the PFX file, as follows:

...
CM.RevertToSelf
Set Store = CM.OpenStoreFromPFX("c:\path\file.pfx", "password")
Set Cert = Store.Certificates(1)
' do something with the certificate

IMPORTANT: The method OpenStoreFromPFXuses an undocumented CryptoAPI function PFXImportCertStorefrom the library Crypt32.dll. For this method to work under IIS 5.0, you mustcall CM.RevertToSelf prior to calling OpenStoreFromPFX, and yourvirtual directory's Application Protection option must be set to Low.Otherwise you will receive the error

Persits.CryptoManager.1 (0x800A0055)
The system cannot find the file specified.

A sample PFX file persits.pfx containing a test certificatecan be found in the folder \Samples\cert_store of the AspEncryptinstallation. The code sample http://localhost/aspencrypt/cert_stores/sign_pfx.aspcomputes a digital signature of a text string using a private keyresiding in this PFX file.

Manage X.509 Certificates and Certificate Stores (9)
Manage X.509 Certificates and Certificate Stores (10)
Manage X.509 Certificates and Certificate Stores (11)Search this SiteManage X.509 Certificates and Certificate Stores (12)
Manage X.509 Certificates and Certificate Stores (13)
Manage X.509 Certificates and Certificate Stores (14)Manage X.509 Certificates and Certificate Stores (15)
Manage X.509 Certificates and Certificate Stores (16)
Manage X.509 Certificates and Certificate Stores (2024)
Top Articles
Latest Posts
Article information

Author: Dean Jakubowski Ret

Last Updated:

Views: 5665

Rating: 5 / 5 (50 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Dean Jakubowski Ret

Birthday: 1996-05-10

Address: Apt. 425 4346 Santiago Islands, Shariside, AK 38830-1874

Phone: +96313309894162

Job: Legacy Sales Designer

Hobby: Baseball, Wood carving, Candle making, Jigsaw puzzles, Lacemaking, Parkour, Drawing

Introduction: My name is Dean Jakubowski Ret, I am a enthusiastic, friendly, homely, handsome, zealous, brainy, elegant person who loves writing and wants to share my knowledge and understanding with you.