# OpenSSL

## <mark style="color:red;">❊ Distinguished Name Values</mark>

In the code below, you may edit the values in the <mark style="color:red;">**`[ yubikey_dn ]`**</mark> section and specify your own values. For a list of references about the abbresviations below, please review the ![](https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2Fy8eADDDxBD8nZlyw8MMc%2Flink_1.png?alt=media\&token=0eefc560-f6f2-464e-9a58-8d86df1fca61) [**Distinguished Name**](https://yubico.gitbook.io/yubikey5/piv-1/generate/with-openssl/distinguished_name) list.

## <mark style="color:red;">❊ Create OpenSSL Config</mark>

Copy the following config file to \ <mark style="color:yellow;">`C:\Program Files\Common Files\SSL\piv_slot_9a.cnf`</mark>

<pre class="language-properties"><code class="lang-properties">oid_section         = yubikey_oids

[ yubikey_oids ]
nameDistinguisher   = 0.2.262.1.10.7.20
microsoftCaVersion  = 1.3.6.1.4.1.311.21.1
gpgUsageCert        = 1.3.6.1.4.1.11591.2.6.1

[ req ]
default_bits        = 2048
default_keyfile     = piv_sign_9a.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.S                 = 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

[ yubikey_ext ]
basicConstraints    = CA:false,pathlen:0
nsCertType          = objsign, objCA
nsComment           = "PIV SSH Authentication"
subjectAltName      = @sans
<strong># extendedKeyUsage    = critical,serverAuth, clientAuth, emailProtection, msSGC, nsSGC, msSmartcardLogin, secureShellClient, secureShellServer
</strong># keyUsage            = critical,digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign
</code></pre>

{% hint style="warning" %}
If you are creating a PIV certificate specifically for Digital Signatures, don't change anything in the <mark style="color:red;">**`[ yubikey_extensions ]`**</mark> block.
{% endhint %}

{% hint style="info" %}
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 <mark style="color:red;">`piv_name_9a_priv`</mark>

<mark style="color:red;">`Priv`</mark> = Private key\ <mark style="color:red;">`Pub`</mark>  = Public key\
\ <mark style="color:red;">**`9A`**</mark> signifies the Yubikey PIV slot we'll be importing our certificate into.
{% endhint %}

## <mark style="color:red;">❊ Setup</mark>

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:

* [📁](https://emojipedia.org/file-folder/) private
* [📁](https://emojipedia.org/file-folder/) public
* [📁](https://emojipedia.org/file-folder/) openssh

## <mark style="color:red;">❊ Generate Key + Cert from Config</mark>

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

<table><thead><tr><th width="200"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><strong><code>-new</code></strong></mark></td><td>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. <br><br>If <mark style="color:red;"><strong><code>-key</code></strong></mark> option not used, it will generate a new RSA private key using information specified in the configuration file.</td></tr><tr><td><mark style="color:red;"><strong><code>-x509</code></strong></mark></td><td>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.<br><br>If existing request is specified with the -in option, it is converted to the self signed certificate otherwise new request is created.</td></tr><tr><td><mark style="color:red;"><strong><code>-sha256</code></strong></mark></td><td><p>Specifies digest to sign the request with (such as -md5, -sha1). </p><p>Some public key algorithms may override this choice. Such as DSA signatures always use SHA1.</p></td></tr><tr><td><mark style="color:red;"><strong><code>-days</code></strong></mark></td><td>Requires <mark style="color:red;"><strong><code>-x509</code></strong></mark> . Specifies number of days to certify for. The default is 30 days.</td></tr><tr><td><mark style="color:red;"><strong><code>-config</code></strong></mark></td><td>Load alternative config. Oerrides the compile time filename or any specified in the OPENSSL_CONF environment variable.</td></tr><tr><td><mark style="color:red;"><strong><code>-keyout</code></strong></mark></td><td>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.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>The output filename to write to or standard output by default.</td></tr></tbody></table>

```
openssl req -new -x509 -sha256 -days 1825 -config "C:\Program Files\Common Files\SSL\piv_name_9a.cnf" -keyout "private/piv_name_9a_priv.key" -out "public/piv_name_9a_pub.crt"
```

## <mark style="color:red;">❊ Create PFX</mark>

Merge your new private key and certificate together into a <mark style="color:red;">**`.pfx`**</mark>&#x20;

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

{% hint style="warning" %}
Keep this file safe. and away from others.&#x20;
{% endhint %}

<table data-header-hidden><thead><tr><th width="175"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><strong><code>-export</code></strong></mark></td><td>Specifies that a PKCS#12 file will be created rather than parsed.</td></tr><tr><td><mark style="color:red;"><strong><code>-in</code></strong></mark></td><td>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.</td></tr><tr><td><mark style="color:red;"><strong><code>-inkey</code></strong></mark></td><td>File to read private key from. If not present then a private key must be present in the input file.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>Specifies filename to write the PKCS#12 file to. Standard output is used by default.</td></tr></tbody></table>

```
openssl pkcs12 -export -in "public/piv_name_9a_pub.crt" -inkey "private/piv_name_9a_priv.key" -out "private/piv_name_9a_priv.pfx"
```

## <mark style="color:red;">❊ Create Private + Cert (.PEM)</mark>

<table><thead><tr><th width="173"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><code>-in</code></mark></td><td>This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.</td></tr><tr><td><mark style="color:red;"><strong><code>-nodes</code></strong></mark></td><td>Stands for "No DES"<br>don't encrypt the private keys at all.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.</td></tr></tbody></table>

{% tabs %}
{% tab title="Encrypted" %}

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

{% endtab %}

{% tab title="Unencrypted" %}

```
openssl pkcs12 -in "private/piv_name_9a_priv.pfx" -nodes -out "private/piv_name_9a_priv.pem"
```

{% endtab %}
{% endtabs %}

## <mark style="color:red;">Create Private Key (.KEY)</mark>

{% hint style="warning" %}
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.
{% endhint %}

{% tabs %}
{% tab title="Private | Encrypted" %}
The following can generate a private <mark style="color:red;">**`encrypted`**</mark> key from your PFX file.

<table data-header-hidden><thead><tr><th width="161"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><code>-in</code></mark></td><td>This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.</td></tr><tr><td><mark style="color:red;"><strong><code>-nocerts</code></strong></mark></td><td>No certificates at all will be output.</td></tr></tbody></table>

```
openssl pkcs12 -in "private/piv_name_9a_priv.pfx" -nocerts -out "private/piv_name_9a_enc_priv.key"
```

{% endtab %}

{% tab title="Private | Unencrypted" %}
The following can generate a private <mark style="color:blue;">**`unencrypted`**</mark> key from your PFX file.

<table data-header-hidden><thead><tr><th width="161"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><code>-in</code></mark></td><td>This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.</td></tr><tr><td><mark style="color:red;"><strong><code>-nocerts</code></strong></mark></td><td>No certificates at all will be output.</td></tr><tr><td><mark style="color:red;"><strong><code>-nodes</code></strong></mark></td><td>Stands for "No DES"<br>don't encrypt the private keys at all.</td></tr></tbody></table>

```
openssl pkcs12 -in "private/piv_name_9a_priv.pfx" -nocerts -nodes -out "private/piv_name_9a_unc_priv.key"
```

{% endtab %}
{% endtabs %}

## <mark style="color:red;">❊ Create OpenSSH (.PUB)</mark>

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 <mark style="color:red;">**`Security`**</mark> tab, and make sure <mark style="color:red;">**`Inheritance`**</mark> is disabled.

<table data-header-hidden><thead><tr><th width="117"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><strong><code>-y</code></strong></mark></td><td>This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.</td></tr><tr><td><mark style="color:red;"><strong><code>-f</code></strong></mark></td><td>Specifies the filename of the key file.</td></tr></tbody></table>

```
ssh-keygen -y -f "private/piv_name_9a_priv.pem" > "openssh/piv_name_9a_openssh.pub"
```

## <mark style="color:red;">❊ Create Private RSA (.PEM)</mark>

Export private RSA key which can be used for connecting to SSH via Filezilla:

```
openssl rsa -in "private/piv_name_9a_priv.pem" -out "private/piv_name_9a_priv_rsa.pem" -outform PEM -traditional
```

## <mark style="color:red;">❊ Create Public Certificate (.PEM)</mark>

Export public cert / key (PEM):

<table><thead><tr><th width="176"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><code>-in</code></mark></td><td>This specifies filename of the PKCS#12 file to be parsed. Standard input is used by default.</td></tr><tr><td><mark style="color:red;"><strong><code>-out</code></strong></mark></td><td>The filename to write certificates and private keys to, standard output by default. They are all written in PEM format.</td></tr><tr><td><mark style="color:red;"><strong><code>-nokeys</code></strong></mark></td><td>No private keys will be output.</td></tr><tr><td><mark style="color:red;"><strong><code>-clcerts</code></strong></mark></td><td>Only output client certificates (not CA certificates).</td></tr></tbody></table>

```
openssl pkcs12 -in "private/piv_name_9a_priv.pfx" -clcerts -nokeys -out "public/piv_name_9a_pub.pem"
```

## <mark style="color:red;">❊ Create Public Key</mark>

Export public key (RSA):

```
openssl rsa -in "private/piv_name_9a_priv.pem" -pubout > "public/piv_name_9a_pub.pub"
```

## <mark style="color:red;">❊ Import to Windows User Certificates</mark>

Click ![](https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FAXecjdsVNIpY9sLQKz6m%2Fwindows_10x_icon.png?alt=media\&token=ff2dea74-fd36-4041-be27-013ecac09af9) -> Run

Type <mark style="color:red;">**`certmgr. msc`**</mark>

Navigate to Certificates -> Current User -> <mark style="color:red;">**Personal**</mark> -> <mark style="color:red;">**Certificates**</mark>

In the white space, right-click and select <mark style="color:red;">**`All Tasks`**</mark> -> <mark style="color:red;">**`Import`**</mark>.

For **Store Location** select **Current User** and click Next.

Select the **Browse** button.

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FFqxZauXQVpkpt9WeZWDo%2Fssl_1.png?alt=media&#x26;token=b37d5ee0-a424-46db-bd7b-c038d1bde4e6" alt=""><figcaption></figcaption></figure>

In the bottom right corner, click the dropdown and select <mark style="color:red;">**`Personal Information Exchange (*.pfx;*.p12)`**</mark> and select your recently exported <mark style="color:red;">**`piv_name_9a_priv.pfx`**</mark>

Select **Next:**

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FDyPde7IyYhce0ybOA2PN%2Fssl_2.png?alt=media&#x26;token=7ce8b937-85bd-484b-bb50-746f7b5d8066" alt=""><figcaption></figcaption></figure>

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

Select <mark style="color:red;">**`Mark this key as exportable`**</mark> 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:

<div><figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FJ07ho2VudZyj6GLnbd4w%2Fssl_3.png?alt=media&#x26;token=af9fcf2e-c26a-4daa-ad6b-2885f7be7961" alt=""><figcaption></figcaption></figure> <figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FEt8A3dg0kmCSDzZaKNio%2Fssl_4.png?alt=media&#x26;token=3402e307-c734-41ff-af62-843d7f044bc2" alt=""><figcaption></figcaption></figure></div>

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

* Certificates -> Current User -> <mark style="color:red;">**`Personal`**</mark> -> Certificates
* Certificates -> Current User -> <mark style="color:red;">**`Trusted Root Certification Authorities`**</mark> -> Certificates

Once you've completed the import:

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FMcZpo2AkbRQnSnuJIPsw%2Fssl_5.png?alt=media&#x26;token=2289b9e3-97fe-4e68-b7f5-0644216da24a" alt=""><figcaption></figcaption></figure>

Click **Yes** and you will finish the import:

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FOVCrQfaZ837YG3PhAT5d%2Fssl_6.png?alt=media&#x26;token=e88c4311-008e-4a68-b44f-013a3a86c93f" alt=""><figcaption></figcaption></figure>

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

After completing the above steps, you should have the following files. You may delete the files you do not want, but ensure you leave at least one private key, one public, and the certificate. Also leave the OpenSSH public key if you wish to use this PIV slot to authenticate with SSH.

<table><thead><tr><th width="293"></th><th></th></tr></thead><tbody><tr><td><mark style="color:red;"><strong><code>piv_name_9a_priv.pfx</code></strong></mark></td><td>Private key + certificate (password protected)</td></tr><tr><td><mark style="color:red;"><strong><code>piv_name_9a_priv.pem</code></strong></mark></td><td>Private encrypted key + certificate</td></tr><tr><td><mark style="color:red;"><strong><code>piv_name_9a_priv.key</code></strong></mark></td><td>Private encrypted key only</td></tr><tr><td><mark style="color:red;"><strong><code>piv_name_9a_pub.pem</code></strong></mark></td><td>Public Certificate (pem format)</td></tr><tr><td><mark style="color:red;"><strong><code>piv_name_9a_pub.crt</code></strong></mark></td><td>Public Certificate</td></tr><tr><td><mark style="color:red;"><strong><code>piv_name_9a_openssh.pub</code></strong></mark></td><td>Public OpenSSH key</td></tr></tbody></table>

## <mark style="color:red;">❊ Import to Yubikey (command-line)</mark>

You can import your new PIV certificate utilizing the ykman command-line.

Open command prompt, terminal, or powershell.

Then navigate to the folder where your PIV <mark style="color:red;">**`.pfx`**</mark> certificate is located and execute the two commands below one after the other:

{% code lineNumbers="true" %}

```sh
ykman piv keys import --pin-policy=ALWAYS --touch-policy=ALWAYS 9A C:\d\piv_name_9A_priv.pfx
ykman piv certificates import 9A C:\d\piv_name_9A_priv.pfx
```

{% endcode %}

You will be asked to supply the <mark style="color:red;">**`management key`**</mark> for your Yubikey, and the <mark style="color:red;">**`password`**</mark> used when you created the PIV certificate.

After executing the commands, you should now have slot 9A configured with a PIV certificate / keys.

You can confirm this by launching the Yubikey Manager application, navigating to <mark style="color:red;">**`Applications`**</mark> -> <mark style="color:red;">**`PIV`**</mark>.&#x20;

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FxfZotkxSYfMwF3cRDLIY%2Fanim_piv.gif?alt=media&#x26;token=645b71fd-e07f-4b8d-a6c9-3c73c075ab4d" alt=""><figcaption></figcaption></figure>

Then select the **Authentication** tab (Slot 9A).

<figure><img src="https://4238369593-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fqj0swE9RiXnBGKcxMY3V%2Fuploads%2FuEF8ejkcr4wpy7UUaZQu%2F9a.png?alt=media&#x26;token=02046d32-c5f8-4696-85b3-8c1c6bdd8979" alt=""><figcaption></figcaption></figure>
