With OpenSSL

These guides are still in development -- check back later

The following example below will show you how to generate a certificate + public / private key that we're going to use for Digital Signatures and import onto our Yubikey into SLOT 9C.

❊ Create Config

The following config can be utilized to generate a x509 self-signed certificate with your private/public keypair.

In the code below, you may edit the values in the [ yubikey_dn ] section and specify your own values. For a list of references about the abbresviations below, please review the Distinguished Name list.

Create a new file in the following folder: C:\Program Files\Common Files\SSL\ssl_digisig_9c.cnf

Copy the config below and paste it in the newly created config file. Edit the values to fit your own certificate needs.

oid_section         = yubikey_oids

[ yubikey_oids ]
nameDistinguisher   = 0.2.262.1.10.7.20
adobeSigning        = 1.2.840.113583.1.1.5
adobeDigitcert      = 2.16.840.1.114412.3.21
msofficeSigning     = 1.3.6.1.4.1.311.10.3.12
msDocSigning        = 1.3.6.1.4.1.311.3.10.3.12
docuEncrypt         = 1.3.6.1.4.1.311.80.1
adobex509           = 1.2.840.113583.1.1.9
msAuthenticode      = 1.3.6.1.4.1.311.2
msTimestamping      = 1.3.6.1.4.1.311.3
gpgUsageSign        = 1.3.6.1.4.1.11591.2.6.2
gpgUsageEncr        = 1.3.6.1.4.1.11591.2.6.3

[ req ]
default_bits        = 2048
default_keyfile     = piv_sign_9c.pem
default_md          = sha256
distinguished_name  = yubikey_dn
x509_extensions     = yubikey_ext
req_extensions      = yubikey_ext
string_mask         = MASK:0x2002
utf8                = yes
prompt              = no

[ yubikey_dn ]
0.C                 = NA
1.ST                = NA
2.L                 = NA
3.O                 = Organization
4.OU                = Organization Unit
5.CN                = Your Common Name
6.emailAddress      = email@address.com
7.GN                = Your Given Name
8.title             = Cert Title
9.description       = Description about Cert
10.initials         = ABC
11.serialNumber     = 1234

[ sans ]
DNS.0               = localhost
DNS.1               = myexampleclient.com

[ yubikey_ext ]
basicConstraints    = CA:false,pathlen:0
nsCertType          = objsign, objCA
nsComment           = "PIV Signature 9C"
subjectAltName      = @sans
extendedKeyUsage    = critical,codeSigning, timeStamping, msCodeInd, msCodeCom, msCTLSign, OCSPSigning, adobeSigning, adobeDigitcert, msofficeSigning, msDocSigning, docuEncrypt, adobex509, msAuthenticode, msTimestamping, gpgUsageSign, gpgUsageEncr
keyUsage            = critical,digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign

The values for block [ yubikey_ext ] specify the usages for the certificate / keys.

If you are creating a PIV certificate specifically for Digital Signatures, don't change anything in the

[ yubikey_ext ] block.

A list of usages can be found below:

In the commands below, make sure to change the filenames and parameters to your own. In our examples, we like to name the files after the slot we're going to import them into on the yubikey such as piv_name_9c_priv

Priv = Private key Pub = Public key Due to this being a keypair and certificate for digital signatures, we'll throw it in slot 9C of the PIV module.

❊ Setup

Before getting started, create you a new folder where you will run all these commands and setup the following structure by creating the following files all in the same directory:

❊ Generate

An OpenSSL cert + private key can be generated using the following command:

-new

Generates new certificate request. Prompts user for the relevant field values. The actual fields prompted for and their maximum and minimum sizes are specified in config file. If -key option not used, it will generate a new RSA private key using information specified in the configuration file.

-x509

Outputs self signed certificate instead of certificate request. Unless specified using the set_serial option, a large random number will be used for the serial number. If existing request is specified with the -in option, it is converted to the self signed certificate otherwise new request is created.

-sha256

Specifies digest to sign the request with (such as -md5, -sha1).

Some public key algorithms may override this choice. Such as DSA signatures always use SHA1.

-days

Requires -x509 . Specifies number of days to certify for. The default is 30 days.

-config

Load alternative config. Oerrides the compile time filename or any specified in the OPENSSL_CONF environment variable.

-keyout

Gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configuration file is used.

-out

The output filename to write to or standard output by default.

openssl req -new -x509 -sha256 -days 1825 -config "C:\Program Files\Common Files\SSL\piv_name_9c.cnf" -keyout "private/piv_name_9c_priv.key" -out "public/piv_name_9c_pub.crt"

❊ Create PFX

Merge your new private key and certificate together into a .pfx

You will be prompted to provide a passphrase to execute the file.

Keep this file safe. and away from others.

-export

Specifies that a PKCS#12 file will be created rather than parsed.

-in

Filename to read certificates and private keys from. Must all be in PEM format. The order doesn't matter but one private key and its corresponding certificate should be present. If additional certificates are present they will also be included in the PKCS#12 file.

-inkey

File to read private key from. If not present then a private key must be present in the input file.

-out

Specifies filename to write the PKCS#12 file to. Standard output is used by default.

openssl pkcs12 -export -in "public/piv_name_9c_pub.crt" -inkey "private/piv_name_9c_priv.key" -out "private/piv_name_9c_priv.pfx"

❊ Create Private Key + Cert PEM from PFX

-in

This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.

-nodes

Stands for "No DES" don't encrypt the private keys at all.

-out

The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.

openssl pkcs12 -in "private/piv_name_9c_priv.pfx" -aes-256-cbc -out "private/piv_name_9c_priv.pem"

❊ Create OpenSSH

To generate your OpenSSH key, you must ensure that the permissions on your pem file are properly set. This means that you must right-click on this file, go to the Security tab, and make sure Inheritance is disabled.

-y

This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.

-f

Specifies the filename of the key file.

ssh-keygen -y -f "private/piv_name_9c_priv.pem" > "openssh/piv_name_9c_openssh.pub"

You can skip the steps for Create Private Key, this was done in the first command. These are here in case you need to create more.

❊ Create Private Key [Encrypted]

The following can generate a private encrypted key from your PFX file.

-in

This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.

-out

The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.

-nocerts

No certificates at all will be output.

openssl pkcs12 -in "private/piv_name_9c_priv.pfx" -nocerts -out "private/piv_name_9c_enc_priv.key"

❊ Create Public Certificate

Export public cert / key (PEM):

-in

This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.

-out

The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.

-nokeys

No private keys will be output.

-clcerts

Only output client certificates (not CA certificates).

openssl pkcs12 -in "private/piv_name_9c_priv.pfx" -clcerts -nokeys -out "public/piv_name_9c_pub.pem"

❊ Create Public Key

Export public key (RSA):

openssl rsa -in "private/piv_name_9c_priv.pem" -pubout > "public/piv_name_9c_pub.pub"

❊ Import to Windows User Certificates

Type certmgr. msc

Navigate to Certificates -> Current User -> Personal -> Certificates

In the white space, right-click and select All Tasks -> Import.

For Store Location select Current User and click Next.

Select the Browse button.

In the bottom right corner, click the dropdown and select Personal Information Exchange (*.pfx;*.p12) and select your recently exported piv_name_9c_priv.pfx

Select Next:

Enter the password you defined when you exported your PFX file with the openssl command.

Select Mark this key as exportable if you want to do a final export from the User Certificates list. If you do not select this option, you will not be able to export it later if you lose your openssl copies.

On the next window, it will ask where you wish to import the certificate to. I import to two locations:

You will need to import twice, to both the following locations:

  • Certificates -> Current User -> Personal -> Certificates

  • Certificates -> Current User -> Trusted Root Certification Authorities -> Certificates

You must place your certificate in the Trusted Root Certification Authorities folder if you wish to sign code using Powershell's Set-AuthenticodeSignature command.

Once you've completed the import:

Click Yes and you will finish the import:

You will need to go through the import process again to install your certificate in the other specified folders from above.

❊ Summary

After completing the above steps, you should have the following in a folder:

  • piv_name_9c_priv.pfx : contains your private key and your certificate, has a private key that is used to decrypt the data.

  • piv_name_9c_pub.pem : contains your public key, used to encrypt the data.

  • piv_name_9c_pub.crt: contains certificate only.

Last updated