Linux smart card authentication howto

This is something I posted on Ubuntu Forums a while ago. Since the tutorials section of UF is bound to disappear, I am reposting it here. I have only tested it on Ubuntu; it should work as is on Debian and other Debian-derivatives, and almost as-is on any modern Linux distribution.

Because your machine hosts extremely sensitive data (or, more probably, just for the geek factor) passwords sometimes just don’t cut it. Thanks to the OpenSC project, Linux users can also use smart cards in lieu of passwords to authenticate against various services, which, in addition to being immune to dictionary or brute force attacks, just looks way cooler. This guide will describe the steps needed to use smart cards for various authentication and encryption purposes. I’d like to thank UF user Berduchwal for starting work (and getting me interested to it) in this thread.

Getting started

The first section of this guide will describe the basic steps you will need to get your smart card ready to be used for various authentication procedures. Each single application will then be described in a separate post and linked at the end of this post.

The hardware

First and foremost, you will obviously need the correct hardware. It can be either a smart card and a smart card reader, or an USB token which provides the same functionality as a smart card, but plugs directly into an USB port, thus eliminating the need for an additional reader. The OpenSC project’s Wiki has a list of supported smart cards and USB tokens, as well as a small list of compatible readers.

The hardware I will use for this guide is an Feitian EnterSafe smart card and SCR301 USB smart card reader. Gooze sells them as a bundle for 32,05 EUR plus shipping (ships only to the EU for legal reasons).

The software

All the necessary software is in the Ubuntu repositories. The packages you need are opensc, pcsc-tools, and libccid. More packages might be needed for specific applications (e.g., PAM authentication), those will be covered in the relevant sections of this guide.

First steps

Now that you have your smart card, reader and all the packages, let’s get to business. First, make sure your reader is detected and supported. First, the usual suspect when it comes to detecting USB devices:

firas@tsukino ~ % lsusb                   
Bus 004 Device 007: ID 096e:0503 Feitian Technologies, Inc. 
Bus 004 Device 004: ID 05ac:8213 Apple, Inc. 
Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 003: ID 05ac:0237 Apple, Inc. 
Bus 003 Device 002: ID 05ac:8242 Apple, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 004: ID 05ac:8403 Apple, Inc. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 05ac:8507 Apple, Inc. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

My Feitian card reader appears. The opensc-tool command can give us more information:

firas@tsukino ~ % opensc-tool --list-readers      
Readers known about:
Nr.    Driver     Name
0      pcsc       Feitian SCR301 00 00

If you get “No smart card readers found.”, unplug your card reader, reboot, and plug it back in. This is because the Debian packages (and maybe others) use udev to set the correct permissions on your card reader device, and a reboot might be necessary for the udev rules to kick in. Also note that the version of pcscd shipped in Ubuntu 12.04 seems to have a bug which causes it to stop detecting your reader after a while. Installing the packages pcscd and libpcsclite1 from the Ubuntu 12.10 repositories (or, of course, upgrading to Ubuntu 12.10 altogether) fixes this issue.

Now to see whether your card is supported:

firas@tsukino ~ % opensc-tool --reader 0 --name
Card not present.

But insert the card first. ;)

firas@tsukino ~ % opensc-tool --reader 0 --name
entersafe

This is the name of your card. If you run the command with the -v (verbose) flag, it will also tell you the name of the driver your card uses:

firas@tsukino ~ % opensc-tool --reader 0 --name -v
Connecting to card in reader Feitian SCR301 00 00...
Using card driver entersafe.
Card name: entersafe

Now that we’ve made sure the card is supported, we can initialise it (roughly the same thing as formatting a filesystem) so we can store stuff on it:

firas@tsukino ~ % pkcs15-init -C --profile pkcs15+onepin --pin 1234 --puk 123456 --label "Firas Kraiem"
Using reader with a card: Feitian SCR301 00 00

The label is optional, it will appear in some authentication prompts, so you probably want to put your name there. Note that some smart cards, such as the Schlumberger CryptoFlex used on the Quick Start page on the OpenSC wiki, will ask you for a “Security Officer” PIN. This is because they support creating several users, each with his own user PIN, keys and data, that will be able to use the same smart card. My EnterSafe, on the other hand, is single-user, so I enter only my user PIN. If your card is multi-users, you will have to create a user, as described on the wiki. (Actually the EnterSafe card is muti-user as well, but the provided driver currently does not support this feature.)

A small note on the codes: the PIN (Personal Identification Number) is the code you will need to enter when you use the smart card (for example when you store a key on it, or when you want to use a key). The PUK (PIN Unlock Key) is used to reinitialise the PIN if you forget it or it gets compromised.

We can now see the structure of the card with:

firas@tsukino ~ % pkcs15-tool -D
Using reader with a card: Feitian SCR301 00 00
PKCS#15 Card [Firas Kraiem]:
	Version        : 0
	Serial number  : 2812504610040810
	Manufacturer ID: EnterSafe
	Last update    : 20130312233841Z
	Flags          : EID compliant

PIN [User PIN]
	Object Flags   : [0x3], private, modifiable
	ID             : 01
	Flags          : [0x32], local, initialized, needs-padding
	Length         : min_len:4, max_len:16, stored_len:16
	Pad char       : 0x00
	Reference      : 1
	Type           : ascii-numeric
	Path           : 3f005015

First key

You generate a RSA key pair on your card with the -G flag of pkcs15-init:

firas@tsukino ~ % pkcs15-init -G rsa/1024 --auth-id 01 --label "My Private Key" --public-key-label "My Public Key"
Using reader with a card: Feitian SCR301 00 00
Using reader with a card: Feitian SCR301 00 00
User PIN [User PIN] required.
Please enter User PIN [User PIN]: 

Replace 1024 with 2048 or 4096 for a longer key (if supported by your card). Replace 01 with the auth-id of the user who will use the key (you can find a user’s auth-id under his PIN section in the output of pkcs15-tool -D). Labels are, once again, optional. Note that the key will be generated directly on your card; it will never be stored on your computer, not even in RAM.

We can use the same command as above to see our new keys in the card’s structure:

firas@tsukino ~ % pkcs15-tool -D 
Using reader with a card: Feitian SCR301 00 00
PKCS#15 Card [Firas Kraiem]:
	Version        : 0
	Serial number  : 2812504610040810
	Manufacturer ID: EnterSafe
	Last update    : 20130312235052Z
	Flags          : EID compliant

PIN [User PIN]
	Object Flags   : [0x3], private, modifiable
	ID             : 01
	Flags          : [0x32], local, initialized, needs-padding
	Length         : min_len:4, max_len:16, stored_len:16
	Pad char       : 0x00
	Reference      : 1
	Type           : ascii-numeric
	Path           : 3f005015

Private RSA Key [My Private Key]
	Object Flags   : [0x3], private, modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x1D], sensitive, alwaysSensitive, neverExtract, local
	ModLength      : 1024
	Key ref        : 1 (0x1)
	Native         : yes
	Path           : 3f005015
	Auth ID        : 01
	ID             : a32a6d12c8186af8ecc46554ef1c9074bbc99562
	GUID           : {a32a6d12-c818-6af8-ecc4-6554ef1c9074}

Public RSA Key [My Public Key]
	Object Flags   : [0x2], modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x0]
	ModLength      : 1024
	Key ref        : 0
	Native         : no
	Path           : 3f0050153000
	ID             : a32a6d12c8186af8ecc46554ef1c9074bbc99562

Or we can use –list-keys to see only the keys:

firas@tsukino ~ % pkcs15-tool --list-keys
Using reader with a card: Feitian SCR301 00 00
Private RSA Key [My Private Key]
	Object Flags   : [0x3], private, modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x1D], sensitive, alwaysSensitive, neverExtract, local
	ModLength      : 1024
	Key ref        : 1 (0x1)
	Native         : yes
	Path           : 3f005015
	Auth ID        : 01
	ID             : a32a6d12c8186af8ecc46554ef1c9074bbc99562
	GUID           : {a32a6d12-c818-6af8-ecc4-6554ef1c9074}

firas@tsukino ~ % pkcs15-tool --list-public-keys
Using reader with a card: Feitian SCR301 00 00
	Object Flags   : [0x2], modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x0]
	ModLength      : 1024
	Key ref        : 0
	Native         : no
	Path           : 3f0050153000
	ID             : a32a6d12c8186af8ecc46554ef1c9074bbc99562

If you need to send the public key to other people, you can retrieve it with:

firas@tsukino ~ % pkcs15-tool --read-public-key a32a6d12c8186af8ecc46554ef1c9074bbc99562
Using reader with a card: Feitian SCR301 00 00
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCD9oT0e3VV3ja8aNpIn2YD8WvS
0cdLbYsslSMtV6zJyGLlpnBv1RunMUSGiYXkKhtB2CtCQrNuUt3/dKdzBtLD5cty
peEDX4ZRt75VVfKxer0UM0p4zmRdIeGckQOB0J+CWU62pkHqGkoCaM3PI0VKIifS
jYds4hoCqtxe2POArQIDAQAB
-----END PUBLIC KEY-----

Of course, put the ID of the key you want to read (you can get it, once again, in the output of pkcs15-tool -D).

Note that there is normally no way to extract the private key from the card. If you need a backup, you must generate the key on your computer, store it on your card (see below) and back it up in a safe location (which could be on another card).

Our RSA key is now ready to be used. I will cover each application in a separate message, so stay tuned. ;)

Other Stuff

This section will document other procedures that are not specific to a single application.

Using a pre-existing key

In some circumstances, you might want to use a pre-existing key instead of generating one directly on your card. This can be useful, for example, if you need a backup of your key, or if you need to distribute the key to several users.

Starting with a freshly initialised card:

firas@tsukino ~ % pkcs15-tool -D                                                
Using reader with a card: Feitian SCR301 00 00
PKCS#15 Card [Firas Kraiem]:
	Version        : 0
	Serial number  : 2812504610040810
	Manufacturer ID: EnterSafe
	Last update    : 20130313000152Z
	Flags          : EID compliant

PIN [User PIN]
	Object Flags   : [0x3], private, modifiable
	ID             : 01
	Flags          : [0x32], local, initialized, needs-padding
	Length         : min_len:4, max_len:16, stored_len:16
	Pad char       : 0x00
	Reference      : 1
	Type           : ascii-numeric
	Path           : 3f005015

Generate the new key on your computer, for example with OpenSSL (of course skip this step if you want to use a key you already have):

firas@tsukino ~ % openssl genrsa -des3 -out mykey.key 1024
Generating RSA private key, 1024 bit long modulus
....................................................................++++++
.....++++++
e is 65537 (0x10001)
Enter pass phrase for mykey.key:
Verifying - Enter pass phrase for mykey.key:

And store the key on your card with the -S flag of pkcs15-init:

firas@tsukino ~ % pkcs15-init -S mykey.key --auth-id 01 --label "My Private Key" --public-key-label "My Public Key"
Using reader with a card: Feitian SCR301 00 00
Please enter passphrase to unlock secret key: 
User PIN [User PIN] required.
Please enter User PIN [User PIN]: 

We can see the key in the output of pkcs15-tool -D:

firas@tsukino ~ % pkcs15-tool -D
Using reader with a card: Feitian SCR301 00 00
PKCS#15 Card [Firas Kraiem]:
	Version        : 0
	Serial number  : 2812504610040810
	Manufacturer ID: EnterSafe
	Last update    : 20130313000349Z
	Flags          : EID compliant

PIN [User PIN]
	Object Flags   : [0x3], private, modifiable
	ID             : 01
	Flags          : [0x32], local, initialized, needs-padding
	Length         : min_len:4, max_len:16, stored_len:16
	Pad char       : 0x00
	Reference      : 1
	Type           : ascii-numeric
	Path           : 3f005015

Private RSA Key [My Private Key]
	Object Flags   : [0x3], private, modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x0]
	ModLength      : 1024
	Key ref        : 1 (0x1)
	Native         : yes
	Path           : 3f005015
	Auth ID        : 01
	ID             : 8b9b45c7af6478a50bb7bd7ce0f86b3bb97f75b2
	GUID           : {8b9b45c7-af64-78a5-0bb7-bd7ce0f86b3b}

Public RSA Key [My Public Key]
	Object Flags   : [0x2], modifiable
	Usage          : [0x4], sign
	Access Flags   : [0x0]
	ModLength      : 1024
	Key ref        : 0
	Native         : no
	Path           : 3f0050153000
	ID             : 8b9b45c7af6478a50bb7bd7ce0f86b3bb97f75b2

Reinitialise your card

If you want to reinitialise your card and start again, use the -E flag of pkcs15-init:

firas@tsukino ~ % pkcs15-init -E
Using reader with a card: Feitian SCR301 00 00

And we can see that the card is empty:

firas@tsukino ~ % pkcs15-tool -D
Using reader with a card: Feitian SCR301 00 00
PKCS#15 Card [(null)]:
	Version        : 0
	Serial number  : 2812504610040810
	Manufacturer ID: entersafe
	Flags          : 

Needless to say, the keys stored on the card will be lost (if you didn’t back them up).

Applications

OpenSSL
PAM, for logins (both console and graphical), sudo, and more.
OpenSSH
TrueCrypt

5 thoughts on “Linux smart card authentication howto

  1. Pingback: Smart Card login on Ubuntu | linuxtoolbox

  2. Sijan

    I am using VISA card , which i particulary agree is not a good idea.
    I have a smart card reader , which i will detail down, but everytime i try to retrieve any thing , it shows me error as unsupported card ,
    Details :
    Using reader with a card: Alcor Micro AU9540 00 00
    PKCS#15 binding failed: Unsupported card

    Please let me know what i am doing wrong to fix the issue

    Reply
  3. Pingback: Common operations using Estonian eID (Linux) | David Vassallo's Blog

  4. Chris

    Hey ! Thanks a lot for your howto!

    I have the following problem. Everytime when i try to run

    pkcs15-init -C –profile pkcs15+onepin –pin 1234 –puk 123456 –label “Firas Kraiem”

    it gives me the following error:
    Failed to create PKCS #15 meta structure: Card command failed

    Do you know what to do? I have GemPC Twin SmartCard Reader

    Cheers and thanks a lot

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *