SSH authentication using PKI card

June 11, 2019    Blog Post

This post has been written as a memory dump from my experiments with the SSH service and the PKI card. I hope you find it useful.

I assume that you have a PKI card and reader. You can have a build-in reader like me (Broadcom Corp 5880) or an external one like Omnikey HO3121 USB2 (I also have it). In addition, you need software that will make your PKI reader and card visible on your system (installation of it is not part of this post).

My native system on which I work every day is Linux Mint ( yeah, life is much easier !!! ), but I will also write a part for Windows.


Let's talk with the PKI reader and card

Depends on the software you use with the card reader on Windows, you must follow the instruction to it to access the card reader and card. I use Atos CardOs API and all required information is available when I click small Chip logo in the icon's try bar..

On Linux, I use opensc tools to talk to reader and card.

Let's start by checking if my card reader is recognized by the software:

$ opensc-tool --list-readers
# Detected readers (pcsc)
Nr.  Card  Features  Name
0    Yes             Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00

I have a Broadcom Corp 5880 PKI card reader on channel 0. Now let's list all the certificates on my card:

$ pkcs15-tool --dump
Using reader with a card: Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
PKCS#15 Card [PKCS#15]:
	Version        : 0
	Serial number  :
	Manufacturer ID: www.atos.net/cardos
	Flags          : Login required, PRN generation
PIN [PIN]
	Object Flags   : xxxxxxxxxxxx
	Auth ID        : 02
	ID             : 01
	Flags          : xxxxxxxxxxxx
	Length         : xxxxxxxxxxxx
	Pad char       : 0x00
	Reference      : xxxxxx
	Type           : UTF-8

AuthKey [Admin Key]
PIN [Extra PIN #0]
Private RSA Key
Private RSA Key
Private RSA Key
.
.
.
< more and more and more >

Communication with the PKI card also works.

If at any time after verification that you have access the the PKI card, you will receive information that the card ID is unavailable / present, but the card is in the reader, do what I do, reseat the card. It always works (for me).

List available public keys on the PKI card

Now it's time to focus on what we need - Public RSA keys, so let's list only them:

$ pkcs15-tool --list-public-keys
Using reader with a card: Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
Public RSA Key [irek AUT 11]
	Object Flags   : xxxxxxxxxxxxx
	Usage          : xxxxxxxxxxxxx
	Access Flags   : xxxxxxxxxxxxx
	ModLength      : xxx
	Key ref        : xxxxxxxxxxxxx
	Native         : xxxxxxxxxxxxx
	Path           : xxxxxxxxxxxxx
	ID             : d62edf638a8e66bb2914209cf96483a6ac55dda9

Public RSA Key [irek ENC 21]
	Object Flags   : xxxxxxxxxxxxx
	Usage          : xxxxxxxxxxxxx
	Access Flags   : xxxxxxxxxxxxx
	ModLength      : xxx
	Key ref        : xxxxxxxxxxxxx
	Native         : xxxxxxxxxxxxx
	Path           : xxxxxxxxxxxxx
	ID             : 2a760dddf9890fa6144f331b992a47508b3466bc

Public RSA Key [irek ENC 11]
	Object Flags   : xxxxxxxxxxxxx
	Usage          : xxxxxxxxxxxxx
	Access Flags   : xxxxxxxxxxxxx
	ModLength      : xxx
	Key ref        : xxxxxxxxxxxxx
	Native         : xxxxxxxxxxxxx
	Path           : xxxxxxxxxxxxx
	ID             : f58b9040e9f6f95ad088d3d87e50ca36c5519475

I have 3 public RSA keys and I can use any, so I will use 1st one designated for Authentication. Its ID is d62edf638a8e66bb2914209cf96483a6ac55dda9 and we will need this information in next task.

Generating the SSH public key

Linux

There are many ways to get a public SSH key from an x509 key, but I'll show you two of them:

  • using pkcs15-tool (or pkcs11-tool)
  • We need the key ID from the previous command (ID:d62edf638a8e66bb2914209cf96483a6ac55dda9) to get the key we need. We are running:

    $ pkcs15-tool -r d62edf638a8e66bb2914209cf96483a6ac55dda9 2> /dev/null|openssl x509 -pubkey -noout|ssh-keygen -i -f /dev/fd/0 -m PKCS8
    
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC……………………………………………………………………………………………………………………………………………/L+ZZnl
    
  • using ssh-keygen
  • Knowing that the key we are looking for is the 1st key on that list, we are running:

    $ ssh-keygen -D /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC………………………………………………………………………………………………………………………………….../L+ZZnl
    ssh-rsa 2nd key /bLb
    ssh-rsa 3rd key dU9r
    
Windows

Download putty-cac and set “PKCS Cert” to point to the CardOs library cardos11_64.dll (C:\Windows\System32\cardos11_64.dll) or any other provider’s library. The “Copy To Clipboard” button copies the public key to the clipboard, and this part have to be added to “authorized_keys” file on the Linux server.

Putty-cac

Adding the public ssh key to the account on the remote system

The generated public ssh key must be added to “.ssh/authorized_keys” on the remote system under the account where we want to login using PKI card.

Connection to a remote system using a stored PKI certificate

Linux
$ ssh -I /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so 192.168.56.130
Enter PIN for 'PIN (PKCS#15 Card + O':
Last login: Wed May 22 17:49:21 2019 from 192.168.56.1
Windows

Putty-cac login

Adding the MFA (optional)

To complicate things even little bit more, we can add an option that requires a password and PKI card for authentication. To do this, edit "/etc/ssh/sshd_config" and add/setup:

AuthenticationMethods "publickey,keyboard-interactive"
ChallengeResponseAuthentication no

Now we need to restart/reload the sshd service and see if it works.