SSL Certificates are everywhere and it has complex structure and headers. In this tip, I will make a brief introduction to X509 Certificate structure and headers. In addition to this, I will be explaining how to insert custom headers to a X509 Certificate.
General knowledge of Computer Science and programming experience will help for better understanding of the article.
Using the Code
1. X509 Certificate and Structure ?
In cryptography, X.509 is an ITU-T standard for a public key infrastructure (PKI) . X.509 contains, standard formats for public key certificates, certificate revocation lists, attribute certificates, and a certification path validation algorithm.
This information is given in the format shown below:
With version 3, another field is added to certificate called 'Extensions.'. Extensions brought some flexibility to the usage of the certificate. In other words, after version 3, we are able to customize the certificates. These extensions can be separated in 2 main groups; standard extensions and custom extensions.
1.1 Standard Extensions
Standard extensions are as listed below:
- Basic Constraints
- Key Usage
- Extended Key Usage
- Subject Key Identifier
- Authority Key Identifier
- Subject Alternative Name
- Issuer Alternative Name
- Authority Info Access
- CRL distribution points
- Issuing Distribution Point
- Certificate Policies
- Policy Constraints
- Inhibit Any Policy
- Name Constraints
- OCSO No Check
P.S 1: In Certificates, notation of the certificate data is arranged according to ANS1 (Abstract Syntax Notations One) format.
P.S 2: Data inside the certificates are encoded using DER or PER. These are common encoding rules to make efficient transportation of the data on the wire. In other words, ASN1 specifies the format of the data and DER or PER encodes the data in the certificate.
1.2 Custom Extensions
If standard extensions are not enough to solve our problem, we are able to define custom extensions which is explain at the end of the tip.
2- How to Create X509 Certificate with Standard Extensions?
X509 Certificate can be generated using OpenSSL. Extensions are defined in the openssl.cfg file. To add extension to the certificate, first we need to modify this config file. According to the config file, certificate will be created using some code.
To edit openssl.cfg file which is located under "C:\OpenSSL-Win64\bin" default directory, open it via your favorite editor. Add the following
string under to
[v3_req] without quotation:
"keyUsage = nonRepudiation, digitalSignature, keyEncipherment"
Save and exit.
To create X509 certificate with respect to this configuration file, open a command window and write the standard code for certificate generation as follows:
A- Generate a server key:
genrsa -des3 -out server.key 1024
B- Create certificate signing request:
req -new -key server.key -out server.csr -config openssl.cfg
C- Copy key to somewhere temporarily.
copy server.key server.key.org
D- Remove the passphrase:
rsa -in server.key.org -out server.key
E- Generate your certificate with standard extensions:
x509 -req -days 365 -in server.csr -signkey server.key
-out server.crt -extensions v3_req -extfile openssl.cfg
Now, open your certificate, go to details and you will see the
keyUsage extension in your certificate.
3- How to Create X509 Certificate with Custom Extensions?
openssl configuration file again (openssl.cfg) and add the followings under the
[v3_req] and save.
188.8.131.522=critical,ASN1:UTF8String:My custom extension's value
184.108.40.2062=ASN1:UTF8String:My custom extension's value
Repeat the steps; a,b,c,d and e. After that open your certificate, go to details and you will see a extension named "220.127.116.112" and its value. "18.104.22.1682" is the oid (object identifier) of the object.
P.S: To parse this certificate on the client side:
public static bool ValidateServerCertificate
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
var cert = (X509Certificate2)certificate;
foreach (X509Extension ext in cert.Extensions)
AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData);
- http://en.wikipedia.org/wiki/X.509 (26/10/14 )
- http://msdn.microsoft.com/en-us/library/windows/desktop/bb540819(v=vs.85).aspx (26/10/14)