[HOWTO] Creating and Converting X.509 Certificates with OpenSSL for use in Microsoft Windows (PKCS12)

I couple of years ago (back in 2010) I assembled a small document on how to use OpenSSL to create and convert X.509 certificates so Windows can properly recognise and work with them because I tended (and still do) to forget its somehow cryptic usage. This document has been lying around on my computer for now almost six years and is still in use. So – with the current year 2015 slowly phasing out – I decided to create a small blog post from it.

As a precondition for all examples we set the OPENSSL environment variable depending on your bitness and your actual installation:

SET OPENSSL=%ProgramFiles%\GnuWin32\bin\openssl.exe
SET OPENSSL=%ProgramFiles%\OpenSSL-Win64\bin\openssl.exe

Contents

Create self-signed certificate

This involves the following steps:

  1. Generate new private key
  2. Generate Certificate Signing Request from private key
  3. [optional] Remove password from private key
  4. Create signed public key
  5. Copy into all-in-one PEM
  6. Convert from PEM to PFX (PKCS12)
REM Generate new private key
"%OPENSSL%" genrsa -out "cert-priv.key" 4096

REM Generate Certificate Signing Request from private key
"%OPENSSL%" req -new -key "cert-priv.key" -out "cert-req.csr" -sha256 -config "%OPENSSL_CONF%"

REM Remove password from private key
"%OPENSSL%" rsa -in "cert-priv.key" -out "cert-priv-nopass.key"

REM Create signed public key
"%OPENSSL%" x509 -req -days 1100 -in "cert-req.csr" -signkey "cert-priv-nopass.key" -out "cert-signed.crt"
"%OPENSSL%" x509 -req -days 1100 -in "cert-req.csr" -signkey "cert-priv-nopass.key" -out "cert-signed.crt" -extensions v3_ca -extfile "%OPENSSL_CONF%"

REM Copy into all-in-one PEM
COPY "cert-signed.crt" + "cert-priv-nopass.key" "cert-pub-priv.pem"

REM Convert from PEM to PFX
"%OPENSSL%" pkcs12 -export -in "cert-pub-priv.pem" -out "cert-pub-priv.pfx"

Check private key

"%OPENSSL%" rsa -check -in private.pvk

Check public key

"%OPENSSL%" x509 -in public.cer -text [-nokey]

Convert PFX to PEM

When converting from PFX (PKCS12) you can selectively perform the following actions:

  1. All-in-one, incl chain, incl password encrypted file
  2. Convert public key only
  3. Convert private key only
REM all-in-one, incl chain, incl password encrypted file
"%OPENSSL%" pkcs12 -in cert.pfx -out cert-priv-pub.pem -nodes

REM pub
"%OPENSSL%" pkcs12 -in cert.pfx -out cert-pub.pem -nokeys

REM priv
"%OPENSSL%" pkcs12 -in cert.pfx -out cert-priv.pem -nocerts

Create all-in-one PEM

Combining a a public and private key in PEM format is a simple matter of appending both keys (public key first):

COPY pub.pem + priv.pem out.pem

Convert PEM to PFX

"%OPENSSL%" pkcs12 -export -in cert.pem -out cert.pfx

Check SSL server certificate

"%OPENSSL%" s_client -connect dfch.wordpress.com:443

With this command you retrieve information about the TLS/SSL certificate of your web server. The output may look similar to this:

CONNECTED(00000160)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go D
addy Root Certificate Authority - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.wordpress.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authorit
y
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFKDCCBBCgAwIBAgIIAfu9ABctn2QwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow
GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz
LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1
cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTUwOTA2MTY1MjQxWhcN
MTgxMDE0MTEyOTI2WjA9MSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0
ZWQxGDAWBgNVBAMMDyoud29yZHByZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMOLqLElQImwQFKMq3Uo/3Yk9SuVeuVYkDVTZpB58PiZCe6q
2f8kaITmhQoFfFMv444Wq0K9k72aHK1YhqEpU7cNvEZxfTrW+ubuUr53iZkfYS7j
ORHYdkGuKBZpysLJ8/k+Dm4TuOQwGNzEKaluAuWdWd2XmIEheD2kzlYey7JzvqXh
p6wmjCVhKD966AKBNcoL8WOtMdVPIRmR1I2FIN1dFTG4vKe4YPm7SiRNQ+keMuBf
Hb8l/Z3HHdGOroZnfR6dJWdmt8Z8JonAgA2BUOGCB9sB6BhJvMaBXQf2rBicRO+N
E6QOeEYeswSOEqPcVR9VSxhgq0HIHNXogg6O2vkCAwEAAaOCAbIwggGuMAwGA1Ud
EwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB
/wQEAwIFoDA3BgNVHR8EMDAuMCygKqAohiZodHRwOi8vY3JsLmdvZGFkZHkuY29t
L2dkaWcyczEtMTE5LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYI
KwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np
dG9yeS8wdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5n
b2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29k
YWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAUQMK9J47M
NIMwojPX+2yz8LQsgM4wKQYDVR0RBCIwIIIPKi53b3JkcHJlc3MuY29tgg13b3Jk
cHJlc3MuY29tMB0GA1UdDgQWBBSjIIf50CVTMgx09Zz+DTIugaYCvjANBgkqhkiG
9w0BAQsFAAOCAQEAs+oqXpiA63H/EpGLtE+DusOazwvz1QzNsFRCqJSjflsV1Bc1
7zPwvNbxT4m96wbYEdCXvQi85MIGZ4+EJAz21gk9HCIsHGgr2farx1pp38flHZtH
wGnMenBscZJQfn1f1X4U5MsQMuSBMiO1zEF3Hf8kia2n3Dj4Dz80w8UTgnDpU3OL
6PYnca78Z/EC1slR1xZjYXBcTLIxkQNOlkvjW/7mlN6hDSVdmoNbw4ID8cy20Mtu
10BzTpB2TsvZwMGompxxpZE5vn5zc6WJHWajOAWbztCupAu2JfBNG1q67gvhBZPs
uGfPVF0ag8twse+vDwRwK5K51To6fR5LtJx5fw==
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.wordpress.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 4394 bytes and written 447 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 220F1CAAA1956BCA35195E462A7A799A9F10DB465BB8A376FEE1ED619765BB82

Session-ID-ctx:
Master-Key: 92F7A37BEDF558605C9856BC7FAE9B5A2480069D99C730F38732726852D7240F
7846238D163B8196E38B3848A486206B
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 21600 (seconds)
TLS session ticket:
0000 - 97 6b 09 90 00 05 d3 35-19 7c f0 d4 85 e4 45 c3 .k.....5.|....E.
0010 - 0a 26 46 c8 71 fa e9 c3-27 0a 0f ce f9 71 a6 21 .&F.q...'....q.!
0020 - 80 b1 b2 27 94 9d e5 ec-2d 59 3c 57 3c 0d 21 7f ...'....-Y<W..
0060 - 55 e7 c6 91 79 0f a5 94-61 be 65 66 f6 98 80 f9 U...y...a.ef....
0070 - 9f 7b 58 fd 6c bb 77 53-21 7b 15 e0 16 33 ba 80 .{X.l.wS!{...3..
0080 - 20 82 71 ea 8f 22 dc 32-88 30 e8 aa b0 b9 6c 69 .q..".2.0....li
0090 - 9b f8 49 19 47 6c 46 f2-f3 a4 61 60 18 ed c8 c6 ..I.GlF...a`....
00a0 - 6c 87 4c ad d1 8e 63 32-99 f5 8e a3 42 e0 5b 99 l.L...c2....B.[.

Start Time: 1451466829
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
closed

Subject Alternative Name (SAN) Certificates

When creating Subject Alternative Name (SAN) certificates you have to adjust your openssl.cfg file (and reference it in you openssl command):

"%OPENSSL%" x509 -req -days 1100 -in "cert-req.csr" -signkey "cert-priv-nopass.key" -out "cert-signed.crt" -extensions v3_ca -extfile "%OPENSSL_CONF%"

Here you see the differences between a regular config file and one that is prepared for SAN certificates:

OpenSSL SAN Certificates

OpenSSL SAN Certificates

Links

Here are a few links and information regarding Certificates from which I took some information in this blog post:
1. JavaKeyStore, JKS, rc15ktl.jar, KeyTool IUI
2. A few frequently used SSL commands
3. How to Convert PFX Certificate to PEM Format for Use with Citrix Access Gateway
4. openssl(1)
5. MSExchangeFAQ – OpenSSL
6. keytool for manipulating Java KeyStores (jks) — A PKCS12 (on Windows aka PFX) can be used as a keystore. The alias in a single PFX can be checked with “-list” option

Trackbacks

  1. […] was I didn’t know much about certificates and had to create a pfx file. So I went through a tutorial (which was written by my boss) about how to create a certificate and sign it with OpenSSL. I […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: