You are not logged in. Log in now?

Show a Story

Creating User Certificates with OpenSSL

After rebuilding my own little CA (hooray me being lazy and MD5 being kind of broken by now) and recreating a bunch of server certificates, I decided to try my hands on user certificates for things like Mumble. The basic creation is not so terribly difficult once you have a CA in place, however a small detail turned out to be rather annoying: how do I get the mail address into the certificate?

Here is a rather low-level way of creating user certificates, answering the age-old-question about the mail address, and a quick glance at packing your certificate, key, and certification chain into one handy PKCS bundle. It's all built on a very simple root CA, and you may want to use stronger digest algorithms and maybe longer or stronger algorithms like elliptic curve cryptography or SHA2.

If you need to handle more than a few certificates, you may also want to take a look at tools like TinyCA to keep the typing at a minimum.

Creating the User Certificate

If you went through tutorials on running your own CA like for example this one, then you probably have some commands at your disposal by now, and just go for it:

$ openssl req -new -nodes -out name-req.pem \
> -keyout private/name-key.pem -days 365 -config ./openssl.conf
Generating a 1024 bit RSA private key
........................................++++++
..++++++
writing new private key to 'private/name-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Organization Name (company) [My Company]:
Organizational Unit Name (department, division) []:User
Email Address []:f@example.org
Locality Name (city, district) [My Town]:
State or Province Name (full name) [State or Providence]:
Country Name (2 letter code) [US]:
Common Name (hostname, IP, or your name) []:Fing User

Nothing bad so far. So let us take a look at the result:

$ openssl req -noout -text -in name-req.pem
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: O=My Company, OU=User/emailAddress=f@example.org, L=My Town, ST=State or Providence, C=US, CN=Fing User
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:d6:6b:97:c4:2c:e2:51:c4:2e:8f:96:c6:30:86:
                    0c:7c:ed:04:71:c8:78:1d:d9:5a:ee:05:d1:e3:60:
                    bf:f6:2e:fd:bf:b6:44:24:57:cd:48:f2:33:97:93:
                    ee:80:4f:5c:ab:00:73:36:85:e5:8e:6b:3e:99:f8:
                    0d:5b:58:11:4f:40:64:14:d1:0b:29:43:bc:30:7c:
                    4a:e4:96:90:ba:89:92:8d:0c:a7:2e:85:c6:35:40:
                    49:df:eb:34:94:06:c0:cf:dd:5a:77:3d:38:6e:45:
                    80:fb:70:6e:b2:85:c1:f2:9a:29:14:d7:16:0c:bf:
                    05:5e:6e:4d:93:67:a2:7e:71
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                B6:5D:45:50:EE:41:CA:52:97:A7:96:91:58:F6:9F:4C:70:22:FB:AA
    Signature Algorithm: md5WithRSAEncryption
        91:0c:7c:a3:ff:15:18:62:ba:b8:30:f7:a1:17:20:fa:50:24:
        dc:9a:54:27:ca:25:32:de:0d:f0:bd:0e:e0:a7:ec:60:6c:96:
        2d:ff:8d:94:45:1f:97:27:99:f9:85:15:47:db:c9:6e:93:9d:
        8a:28:61:29:56:68:18:2d:ed:a1:d1:0e:68:ee:da:6b:93:40:
        b1:94:27:42:ba:08:30:f6:56:e3:2a:98:7e:31:b2:4d:7b:20:
        22:a7:bb:05:99:f9:0c:f0:f6:0b:75:73:06:f1:6c:b8:a1:e3:
        9f:4f:64:88:14:56:b7:0c:37:ca:44:66:3e:26:36:a2:59:14:
        84:d8

That still looks good, we have a mail address and everything in the subject. Great, so let's sign the thing and be on our merry way:

$ openssl ca -out name-cert.pem -days 365 \
> -config ./openssl.conf -infiles name-req.pem

(output cut)

... and then see what happened:

$ openssl x509 -text -in name-cert.pem
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 1048581 (0x100005)
        Signature Algorithm: md5WithRSAEncryption
        Issuer: O=My Company, L=My Town, ST=State or Providence, C=US, CN=aaa
        Validity
            Not Before: Jan 23 15:42:40 2010 GMT
            Not After : Jan 23 15:42:40 2011 GMT
        Subject: C=US, ST=State or Providence, O=My Company, OU=User, CN=Fing User
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:d6:6b:97:c4:2c:e2:51:c4:2e:8f:96:c6:30:86:
                    0c:7c:ed:04:71:c8:78:1d:d9:5a:ee:05:d1:e3:60:
                    bf:f6:2e:fd:bf:b6:44:24:57:cd:48:f2:33:97:93:
                    ee:80:4f:5c:ab:00:73:36:85:e5:8e:6b:3e:99:f8:
                    0d:5b:58:11:4f:40:64:14:d1:0b:29:43:bc:30:7c:
                    4a:e4:96:90:ba:89:92:8d:0c:a7:2e:85:c6:35:40:
                    49:df:eb:34:94:06:c0:cf:dd:5a:77:3d:38:6e:45:
                    80:fb:70:6e:b2:85:c1:f2:9a:29:14:d7:16:0c:bf:
                    05:5e:6e:4d:93:67:a2:7e:71
                Exponent: 65537 (0x10001)
    Signature Algorithm: md5WithRSAEncryption
        8d:73:3b:10:2d:f1:e7:ae:a5:94:90:12:85:22:c8:4d:d0:d0:
        15:e9:dc:60:5c:5f:06:cb:16:e1:0a:76:95:a1:b3:b1:86:28:
        3f:d4:6a:9e:5a:60:98:37:49:bc:57:1d:5e:80:e4:6c:b7:ae:
        55:9e:5b:0a:a6:41:a4:4c:6b:8e:a3:18:88:fa:6d:84:93:20:
        be:9d:68:b2:fe:4a:ce:1d:44:69:11:dd:b0:4d:d3:4f:fb:af:
        a9:da:25:e1:34:02:c8:00:55:f3:05:a4:ca:bb:73:2f:63:9e:
        b6:80:68:d8:96:24:a6:09:e0:0b:3c:a9:f5:a5:72:40:ae:ce:
        9e:37
(certificate cut)

Looks goo... wait a second, where did the mail address go‽ That's the moment when you start digging and digging and digging, and don't find much but instructions on making a self-signed CA certificate, but you already did that.

Here is the solution: you need to put the mail address into an extension, namely subjectAltName. That is done in the configuration file you're using for creating the request and signing the certificate request. That file is quite big, so just let me show the sections that's done in if you're using the file from the tutorial linked above:

[ CA_default ]
...
copy_extensions = copy

[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
# now the important part
subjectAltName = email:copy

What that does is

You are strongly advised to read the WARNINGS section in the manual for the CA command, since copying extensions could be exploited, but we are assuming that you are not blindly signing requests from all over the world.

With that configuration in place, let's create a new request and see what happens:

$ openssl req -new -nodes -out name-req.pem \
> -keyout private/name-key.pem -days 365 -config ./openssl2.conf
Generating a 1024 bit RSA private key
...........++++++
.++++++
writing new private key to 'private/name-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Organization Name (company) [My Company]:
Organizational Unit Name (department, division) []:User
Email Address []:g@b.c
Locality Name (city, district) [My Town]:
State or Province Name (full name) [State or Providence]:
Country Name (2 letter code) [US]:
Common Name (hostname, IP, or your name) []:Great User


$ openssl req -noout -text -in name-req.pem
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: O=My Company, OU=User/emailAddress=g@b.c, L=My Town, ST=State or Providence, C=US, CN=Great User
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:aa:91:30:cd:bc:7c:85:2c:ef:84:2b:48:5a:9f:
                    af:31:4e:dc:d9:c9:c9:2b:70:a1:cf:81:f4:a3:13:
                    1d:a2:9a:c6:27:26:6c:f2:7a:27:fa:08:ca:14:fe:
                    36:79:ae:6a:99:f0:22:2a:99:0a:e7:e5:65:85:68:
                    eb:8e:d9:2f:2c:76:6a:76:a7:85:ef:6e:40:60:1b:
                    01:f0:49:76:a5:33:77:09:e2:a0:b6:d1:43:2b:21:
                    c7:2d:19:cc:41:ef:e4:e3:10:af:0b:ff:eb:0f:d4:
                    b3:07:04:a0:ae:4a:54:55:12:70:c4:32:6f:d5:4f:
                    f2:15:03:d3:09:e2:c6:4b:f1
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                0A:BD:F5:76:3D:C8:A2:9E:B6:21:4B:6E:9E:41:80:B1:A8:34:10:F5
            X509v3 Subject Alternative Name:
                email:g@b.c
    Signature Algorithm: md5WithRSAEncryption
        59:a0:de:83:b1:cc:fc:22:29:3e:1d:7d:73:61:04:77:09:4a:
        06:cc:cc:fd:1a:3f:74:8a:32:ab:19:a6:a8:42:a6:6d:64:b5:
        a1:63:dc:ec:71:bc:ac:83:b9:a4:5e:ef:4f:f0:bf:07:24:52:
        6b:1b:60:ef:9e:0e:85:6c:1e:36:43:a4:0d:74:ff:9e:b5:0b:
        da:d6:34:aa:66:20:92:1c:69:ba:72:99:3c:80:83:03:dd:19:
        67:d3:88:3b:e4:ed:09:7c:66:be:f3:d6:e2:94:5d:d8:d7:7d:
        4f:81:ac:87:ae:c1:18:38:c7:58:e7:f4:1d:5b:63:74:74:a7:
        25:c0


$ openssl ca -out name-cert.pem -days 365 \
> -config ./openssl2.conf -infiles name-req.pem
Using configuration from ./openssl2.conf
Enter pass phrase for ./private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
organizationName      :PRINTABLE:'My Company'
organizationalUnitName:PRINTABLE:'User'
localityName          :PRINTABLE:'My Town'
stateOrProvinceName   :PRINTABLE:'State or Providence'
countryName           :PRINTABLE:'US'
commonName            :PRINTABLE:'Great User'
Certificate is to be certified until Jan 23 15:59:51 2011 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated


$ openssl x509 -email -in name-cert.pem
g@b.c

(certificate cut)

And there you are.

Bundling it up

Chances are that you will not want to mess around with a bunch of PEM files. The solution is to put it all into one neat PKCS file. That can easily be done with the OpenSSL command-line tool as well, and it can include the whole certificate chain:

$ openssl pkcs12 -export \
> -in name-cert.pem \
> -inkey private/name-key.pem \
> -certfile cacert.pem \
> -name "Great User" \
> -out name-cert.p12
Enter Export Password: (blind password here)
Verifying - Enter Export Password: (and again)

You can then import the file name-cert.p12 into Mumble, your mail program, and other applications that can use SSL certificates, and thereby identify yourself as a user of your very own CA. The program will just ask you for the export password you set when creating the bundle. If anybody else decides to trust your root certificate, you're all set for trusted communication with them.

By Shadowdancer, 2010-01-23, 17:14; permalink;
Last updated at 2010-01-24, 13:22 by Shadowdancer

Powered by merb 1.1.0 and DataMapper 0.10.2.