| ??? | First version |
|---|---|
| 2005-03-29 | Added Mozilla Thunderbird + engimail stuff |
| 2005-05-30 | Added small notice about ifdproxy |
| 2005-09-24 | Updated instructions to use OpenSC 0.9.6 |
| 2005-09-25 | Added Debian-specific instructions |
| 2005-10-28 | Added some shortcuts for key generation |
| 2005-11-01 | Added information about Smart Card Bundle / Winodws |
| 2005-11-17 | Some very minor changes |
Using Rainbow iKey 3000 under Linux (or any other smart card)
IntroductionSmart Cards to keep it secure
Something about asymmetric and symmetric
Hardware needed
Software needed
Installing OpenCT and OpenSC
Generating keys and certificates
Local login with the smart card
Remote login with the smart card
Remote remote logins
Encrypting files
Encrypted home directories
Authenticating to web sites (Mozilla Firefox)
Encrypting and signing your email (Mozilla Thunderbird)
OpenCT proxying
Windows
Windows + PuTTY + OpenSC
Final words
Credits
Introduction
Today everybody has access to multiple computers, web sites etc. and every place will require password to remember. Passwords should be different in every place and they should be long enough (over 10 chars!) to be secure. Now, I have personally access hunderds of places and machines and it is impossible to have indepent and secure passwords, isn't it? I haven't studied cryptography much, but I know there is much better ways to authenticate yourself than passwords. Public Key Infrastructure is todays hit - you have two keys, your public key and private key. You give you public key to everyone and keep your private key secret. Now everybody having you public key can authenticate your identity without your private key. I won't explain how this is possible, because there are much material abou PKI. So, you can carry you private key with you and perform authentication with it. However, if you carry your key in floppy disk or some other media, it can be stolen and then your identity will ve stolen. You can have password protecting your private key but it can be cracked.
Smart Cards to keep it secure
Well there is solution - smart cards. Smart cards which have cryptograph chip inside them and which will perform cryptograph operations with it. You can store your public and private key in the smart card. Public key can be read from the smart card without any passwords, but private key will NEVER leave the smart card. It can not be read from card even by you once it is imported. So it is impossible to stole, isn't it (well, there are theoretic attacks using electornic microscope :-)? When you want to authenticate yourself, you handle authentication process to the smart card. The smart card can be protected using short PIN code. When multiple false PIN codes are entered, the smart card will lock itself to prevent brute force attacks. This is most secure authentication model currently known. Only realistic threat is the smart card beign stolen and you pin code being spied. That is MUCH more secure than simple username and password.
Ok, I had hundreds of passwords and wanted to get rid of them. I searched net and found that there are two kinds of smart cards - card readers + cards and USB tokens. I decided to buy USB token since every computer have USB port, but there are no card readers. The token vas pretty expensive (~70 euros after postace fees), but I wanted to play with it. I bought Rainbow iKey 3000 since it is supported under Linux and was somehow affordable. CyProtect sells them. The token arrived in five days from Germany to Finland. That was fast. Then I begined to search documentation about using smart cards and found that there are virtually no documentation for end users! Every documentation is for developers. Oh well, it seems I'm pioneer of one kind and I decided to write my own documentation to encourage using usb tokens. It is not easy, but it s possible under Linux. Let's begin.
Something about asymmetric and symmetric
Our smart cards are done for asymmetric key cryptography which basically means the same as public key cryptography. Like asymmetric says, you have different keys for encrypting and different for decrypting. This is very flexible BUT it is also very slow to perform decryption and also very long keys are needes to ensure security. Asymmetric algorithms, like RSA which we are using with smart cards, will need at least 1024 bit keys. Smart cards usually will support RSA with 1024 bit keys, just like our iKey. 2048 bits would be better, but iKey won't support it.
Then we have symmetric key cryptography. It means that you have single key for encrypting and decrypting. Drwaback is that you cannot publish your key, but cons are that you won't need very long key and thus operations are very fast. In this document we use AES (actualle Rijndael, AES == Advanced Encryption Standard) algorithm which will be fine with key lenghts of 256 bits.
We can get both of best worlds by using symmetric key cryptography for encrypting hard drives etc. big stuff AND encrypting symmetric key using asymmetric key cryptography. When we want to decrypt, we use our private key to decrypt our encryption key, which will decrypt our document.
Hardware needed
Any USB token or smart card supported by OpenSC. There should be several working tokens available but I have only tried iKey 3000 so this document will cover only it.
Software needed
- Any OS supporting USB ports and having programs listed below. I use Debian GNU/Linux so instructions are very strongly biased to Linux, sorry.
- OpenCT and OpenSC - open source implementation for several smart card standards. OpenSC should be at least version 0.9.4 since it contains many improvements used by this document and earlier versions don't suport iKey fully. OpenCT 0.6.4 is known good.
- PAM - if you wan't to use smart card for local login
- pam_mount for encrypted home directories.
- dm-crypt for encrypted home directories.
- OpenSSH - if you wan't to use smart card for remote connections.
- OpenSSL - General SSL tools.
Installing OpenCT and OpenSC
You should always use package manager to install needed software. In Debian I would say 'apt-get install openct opensc' to install these packages and everything would be automaticly installed. However, opensc needs some manual patching because it lacks few features needed with encrypted home directories so sadly you need to compile it from the sources. Stock openct is ok (I am using version 0.6.4 in Debian sarge). You need to apply two patches in order to use encrypted home directories with OpenSC and my instructions (please enlighten me if patching could be avoided!):
You need --raw support for pkcs15-crypt. Feature is implemented in CVS version of OpenSC but not in 0.9.6 which is latest version when writing this. CVS version contains some other patches too but at least pkcs15-crypt.c file from CVS snapshot 20050924 worked fine when applied to 0.9.6. You can use CVS version or use pkcs15-crypt.c from CVS version in 0.9.4 or you can apply this patch which upgrades your pkcs15-crypt.c to 20050924.
Also you need support for reading PIN-code from STDIN in pkcs15-crypt. That feature is not in CVS version and that makes patchin necessary (well one could use expect to get around the problem but because we need to patch in any case...). Patch may introduce some security dilemmas because PIN-code is meant to be read directly from user... However, the patch, applies cleanly to 0.9.4.
When compiling, try to use your distributions source-package and comple binary package suitable for your distribution. Ie. with Debian I would say 'apt-get source opensc', apply patches and say 'debian/rules binary' which would give me nice binaries manageable with package manager.
I have compiled opensc with patches above for Debian sarge. You can download .deb:s from http://keitin.net/debian/binary/opensc/ or you can even use apt-get (add 'http://keitin.net/debian/ binary/' to apt sources and pin 'release o=keitin.net' above official sources). However I take no responsibility of correctness of those packages since I am no trained Debian developer :-)
After you have successfully installed OpenCT and OpenSC, check that your smart card is found:
pixie:~# openct-control status No. Name Info =================================================== 0 Rainbow iKey 3000 slot0: card present pixie:~# opensc-tool -n StarCOS
Generating keys and certificates
duet informed me that following commands should generate
needed keys and certificates without complicated hassle below:
openssl genrsa -out my.key 1024
openssl req -new -x509 -days 1095 -key my.key -out my.crt
Thanks, haven't checked them but reader could try those command.
You need asymmetric RSA keys and X.509 certificate to use with smart card. I found some instructions from ipsec site, check them out for more information. Then, let's create new Certificate Authority (ca). Use some random data as password (afterward store password and ca-files to very secure place if you want to do some more tricks with your authority):
pixie:~# /usr/lib/ssl/misc/CA.sh -newca CA certificate filename (or enter to create) Making CA certificate ... Generating a 1024 bit RSA private key .............................................++++++ .........++++++ writing new private key to './demoCA/private/./cakey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:FI State or Province Name (full name) [Some-State]:None Locality Name (eg, city) []:None Organization Name (eg, company) [Internet Widgits Pty Ltd]:None Organizational Unit Name (eg, section) []:None Common Name (eg, YOUR name) []:Jari Eskelinen Email Address []:jari.eskelinen@iki.fi
There should now be folder demoCA, which will contain ca datafiles. Be proud, you have the power now :-) But your power will expire soon, default value is 1 years. Let's expand id to 10 years:
pixie:~/open# openssl x509 -in demoCA/cacert.pem -days 3650 -out demoCA/cacert.pem -signkey demoCA/private/cakey.pem Getting Private key Enter pass phrase for demoCA/private/cakey.pem:
Hop. You can check that this succeeded by command openssl x509 -in demoCA/cacert.pem -text. Then we should create new certificate request (crq). New private/public RSA keys are created and certificate request is created. Once again, use some random data as password (and place password in secure place with you certificate request and keys):
pixie:~# /usr/lib/ssl/misc/CA.sh -newreq Generating a 1024 bit RSA private key ...++++++ ................++++++ writing new private key to 'newreq.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:FI State or Province Name (full name) [Some-State]:None Locality Name (eg, city) []:None Organization Name (eg, company) [Internet Widgits Pty Ltd]:None Organizational Unit Name (eg, section) []:None Common Name (eg, YOUR name) []:Jari Eskelinen Email Address []:jari.eskelinen@iki.fi Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Request (and private key) is in newreq.pem
You have now new private key & certificate request in file newreq.pem. Key is encrypted but we need it unencrypted, so let's decrypt it:
pixie:~# openssl rsa -in newreq.pem -out newkey.pem Enter pass phrase for newreq.pem: writing RSA key
Then, let's sign the request using our ca:
pixie:~# /usr/lib/ssl/misc/CA.sh -sign Using configuration from /usr/lib/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: ... clip ... Certificate is to be certified until Jul 18 19:04:27 2005 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries ... clip ... -----END CERTIFICATE----- Signed certificate is in newcert.pem
NOTE: Your certificate if valid for one year by default.
Now we should have file newreq.pem which contans our (encrypted) private key and certificate request. Then we have newkey.pem, which contans unencrypted private key. And then we have newcert.pem which contains our (self) signed certificate. Time to put keys and certs to smartcard (NOTE: smart card wil be erased!!!):
pixie:~# pkcs15-init -E pixie:~# pkcs15-init --no-so-pin --create-pkcs15 --profile pkcs15 pixie:~# pkcs15-init --auth-id 1 --store-pin --pin "1234" --puk "123456" --label "PIN" pixie:~# pkcs15-init --auth-id 1 --pin "1234" --key-usage sign,decrypt --store-private-key newkey.pem pixie:~# pkcs15-init --auth-id 1 --pin "1234" --store-certificate newcert.pem
Nils Larsch informed me that iKey 3000 (using StarCOS SPK 2.3) won't need separate keys for signing and decrypting like some other smart cards (CardOS M4). If you are using a smart card which chip don't support signing & decrypting with same key, use --split-key when storing private key to card. However Nils also said that it is good idea to use truly separate keys: "Note: using a seperate key for signing (non-repudiation) is really a good idea, only for authentication keys the split key stuff is really recommendable.". Thanks Nils!
You can call pkcs15-init --finalize to finalize card. Further writes to card will be impossible then. Finalize is no longer needed, informed Nils.
Hendrik Volkmer pointed out that it would be wise to create asymmetric RSA keys inside smart card so that private key will NEVER be stored in disk. Drawback is that if you break your smart card, you cannot recover. Creating key inside smart card is easy (if supported by smart card): pkcs15-init --pin "1234" --auth-id 1 --generate-key rsa --key-usage sign,decrypt. Certificates however cannot be generated, so you must use openssl for logins.
After you have imported keys to the smart card, please delete unencrypted key newkey.pem. Also please archive other files to safe place - if they can be stolen, they can be breaked by brute force (well, currently attacker would need extraordinary computing power, but better to be safe than sorry). Archive passwords used to other secure place, so that both canno't be stolen simultaneously (ok, I'm paranoid). If you use smart card only for you personal computer or so, you may even permanently delete everything - but if smart card breaks or you forget your pin, it's impossible to recover. You need to crack you Linux-boxes, encrypted files are gone etc.
NOTE: it may be also good idea NOT TO define PIN in command line like I did above. If someone is logged in to your box and does 'ps -aux' at right time, pin is shown to him! Also PIN may be stored to ~/.bash_history or some other similiar file depending on your shell. This is no big threat if you do this with your personal computer, but once again, better to be safe than sorry :). And paranoia is good when dealing with data security.
Local login with the smart card
To login locally with the smart card, you need pam_opensc PAM module. It comes with OpenSC. Then you will need to store your public key to ~/.eid/authorized_certificates:
pixie:~# mkdir ~/.eid pixie:~# pkcs15-tool -r 45 -o ~/.eid/authorized_certificates
Then you need to set up PAM for accepting smart card logins. Personally I disabled password login completely from pam configuration and set user passwords to random binary data. My /etc/pam.d/login has been modified like this (ignore pam_mount, it will be explained below):
auth sufficient pam_opensc.so
Login should now work with the smart card. Similiar modifications can be done to su, xlock, gdm etc:
jarpatus@pixie:~$ su Using card reader Rainbow iKey 3000 Enter PIN131 [PIN]: pixie:/home/jarpatus#
Remote login with the smart card
OpenSSH (and commercial also) have program called ssh-agent. When remote ssh-server asks for authentication, local client will pass it to ssh-agent which will pass it to the smart card in our case. Probably you'll need to recompile openssh with parameter --with-opensc. Then you just need to start ssh-agent, make it aware of the smart card and place your public key to places you need to access.
I have compiled OpenSSH with OpenSC support for Debian sarge. You can find .debs from http://keitin.net/debian/binary/openssh/ or use my apt repository like insturvted above in installing OpenSC section.
pixie:~$ ssh-keygen -D 0 > id_rsa.pub
Append id_rsa.pub to remote servers ~/.ssh/authorized_keys. Then try login:
pixie:~# eval `ssh-agent` Agent pid 21079 pixie:~# ssh-add -s 0 Enter passphrase for smartcard: Card added: 0 pixie:~# ssh jarpatus@gnoll Linux gnoll 2.4.26 #1 ke kesäkuun 9. 14:35:01 EEST 2004 i686 GNU/Linux jarpatus@gnoll:~$
See Mark A. Hershbergers guide.
TODO: Using smart card with commercial ssh (ssh2).
Remote remote logins
Just enable Forward ssh-agent in your ssh_config and you are able to login remote hosts from ssh'ed remote hosts - ssh-agent queries are forwarded to your local machine. Neat. You can chain as many connections as you want. But be careful - if there is cracked machine and you have the smart card inserted, you can be in trouble!
Encrypting files
TODO: how this is done with opensc, openssl and other software.
Encrypted home directories
NOTE: You need --raw support for pkcs15-crypt and readpin patch also. Please see section about installing OpenSC.
Encrypting small files can be done using OpenSSL and your public key and decrypting can be done using the smart card. Good application is to encrypt the symmetric key you will use to encrypt your harddrives and whenever you log in, the key is decrypted using the smart card and then the key will be used to decrypt your home directory. General example:
pixie:~# pkcs15-tool --read-public-key 45 > mykey.pub pixie:~# openssl rsautl -encrypt -pubin -inkey mykey.pub -in plaintext -pkcs -out encrypted pixie:~# pkcs15-crypt --pkcs1 --decipher -k 45 -i encrypted -o decrypted Enter PIN [PIN]:
Ok, then we encrypt our hard drives using symmetric AES algorithm. I will use dm-crypt instead of cryptoloop since there were some issues regarding to cryptoloop and dm-setup is newer way to do encrypting anyways. That means that you will need 2.6.x kernel, sorry. First, create binary random key for encrypted volume (when encrypting hard drive we use symmetric cryptography meaning that key lenght of 256 bits is enough, but let's use 768 bits for future - well, dm-crypt will hash it to 256 bytes... :-) and encrypt it (output will be padded to be 1024 bytes - requirement of pkcs15-crypt). Then check that you can decrypt it:
pixie:~# dd if=/dev/random of=/crypt/key.plain bs=1 count=96 96+0 records in 96+0 records out 96 bytes transferred in 0,000909 seconds (105616 bytes/sec) pixie:~# openssl rsautl -encrypt -pubin -inkey mykey.pub -in /crypt/key.plain -pkcs -out /crypt/key pixie:~# rm /crypt/key.plain pixie:~# pkcs15-crypt --pkcs1 --decipher -k 45 -i /crypt/key
You have your encrypted AES key in your harddrive. This means that it can be stolen and cracked by brute force. If you use long enough (let's say, 256 bits) keys, this should not be problem until they get their qantum computers working.
Then creating encrypted volume (2 GB). Please make sure you have device mapper support compiled to your kernel or modules loaded. Hendrik Volkmer give me great idea about storing encypted encryption key to first sectors of volume image so that it cannot be accidentally deleted. I have updated these instructions to use that approach (experimental, experimental...):
pixie:~# dd if=/dev/urandom of=/crypt/pixie.home.jarpatus bs=8M count=256 pixie:~# dd conv=notrunc if=/crypt/key of=/crypt/pixie.home.jarpatus bs=1 128+0 records in 128+0 records out 128 bytes transferred in 0,075367 seconds (1698 bytes/sec) pixie:~# rm /crypt/key pixie:~# dd if=/crypt/pixie.home.jarpatus bs=1 count=128 of=/tmp/key 128+0 records in 128+0 records out 128 bytes transferred in 0,121282 seconds (1055 bytes/sec) pixie:~# losetup /dev/loop0 /crypt/pixie.home.jarpatus pixie:~# pkcs15-crypt --raw --pkcs1 --decipher -k 45 -i /tmp/key \ | cryptsetup --hash=plain --cipher=aes --key-size=256 --offset=2048 create _dev_loop0 /dev/loop0 pixie:~# rm /tmp/key pixie:~# mkfs.ext3 /dev/mapper/_dev_loop0 ... pixie:~# mount /dev/mapper/_dev_loop0 /home/jarpatus
Phew. That created imagefile, wrote key to the beginning of it and deleted original keyfile, read key back from from imagefile to temporary file, decrypted it and feed decrypted key to cryptsetup which set up encrypted volume but leaved 2048 sectors untouched (2048 * 512 bytes == 1 MB, I left some spare room for other tricks someone may invent). from imagefile. Then ext3 file system was created and finally volume was mounted to /home/jarpatus!
NOTE: you can also use whole partition as encrypted volume. Just skip losetup-stuff and use device name (like /dev/hdc1) instead of image-file.
Now you should copy your stuff to you brand new home directory. Please notice, that ~/.eid should be in unmounted /home/jarpatus and when you mount your encrypted volume, it will be left under mount. You should copy ~/.eid also to encrypted volume for being able to log in when your home is already mounted.
TODO: always mount before login so unmounted dir can be empty?
Following information is obosolete in a way. I have
found pam_mount very difficult to use and it seems to be very wrong
utility in any case. I wrote perl -scripts for replacing pam_mount and
these scripts can be utilized using pam_script. You try to log in
-> you are authenticated by pam_opensc -> pam_script calls
donglemount_mount.pl -> it mounts your home dir -> logout ->
pam_script calls donglemount_umount.pl -> everything nice and clean.
This script could contain bugs etc. stuff, but I would appreciate if
somebody would try it out and give some feedback. I use this script
with my laptop in every day use so it should work in normal
situations. Please download: donglemount.
If you use this path, please skip paragraphs elow in this chapter.
There is PAM module called pam_mount which will do this automaticly when you log in. Grab it sources and install. Edit /etc/security/pam_mount.conf and use following kind of lines:
fsck /bin/true losetup /bin/true unlosetup /bin/true umount /crypt/umount.crypt %(MNTPT) lclmount /crypt/mount.crypt %(VOLUME) %(MNTPT) -o %(OPTIONS) volume jarpatus local - /crypt/pixie.home.jarpatus /home/jarpatus loop - -
Then copy files mount.crypt and umount.crypt to /crypt from pam_mount sources. You need to modify mount.crypt and add 5 lines to it:
KEYSIZEOPT="256"
if [ -n "$KEYSIZE" ]; then
KEYSIZEOPT="$KEYSIZE"
fi
dd if=/crypt/pixie.home.jarpatus bs=1 count=128 of=/tmp/key
pkcs15-crypt --raw -p - --pkcs --decipher -k 45 -i /tmp/key \
| $CRYPTSETUP --cipher=aes --hash=plain --key-size=256 --offset=2048 create $DMDEVICE $DEVICE
fsck -p /dev/mapper/$DMDEVICE
rm /tmp/key
if [ $? != 0 ]; then
echo "${0##*/}: error creating $DMDEVICE" >&2
[ x"$LOOP" = xtrue ] && $LOSETUP -d $DEVICE
exit 1
fi
Now umount your volumes, delete loopbacks and try to log in. It should work. Fsck is done just before mounting. I disabled pam_mount's own fsck capability, since it is unable to use smart card. I think pam_mount is unneededly complicate program for this use, but I was unable to find any other pam module, which allows to execute script upon login/logout. Oh and modify your /etc/pam.d/login:
auth optional pam_mount.so auth required pam_opensc.so use_first_pass session optional pam_mount.so use_first_pass
NOTE: If you use Debian, please read Debian specific documentation from pam_mount docs. Unmounting won't work by default. You must edit /etc/login.defs and change CLOSE_SESSIONS to yes.
TODO: how to backup encrypted home?
Authenticating to web sites (Mozilla Firefox)
http://www.opensc.org/files/doc/opensc.html#opensc.using.mozilla should help you. Thanks Stepan!
Encrypting and signing your email (Mozilla Thunderbird)
TODO: everything
OpenCT proxying
OpenCT does have program called ifdproxy included with it. It will proxy openct connection between two computers so you could have smart card reader in remote mahchine and use it like it is connected locally. However, it seems that only serial smart card readers are supported so using iKey 3000 with it is not supported at leastr currently.
Windows
Sometimes man have to do dirty things, in this case, using Windows. I have to use Windows at my work and when I'm visiting my relatives so it is a must to be able to connect using USB token. Now, OpenSC supports StarCOS drivers, which is good. You need to download drivers from Rainbow's site (nowadays SafeNet who bought Rainbow!): http://c3.safenet-inc.com/ikeyESC.asp. Install them of course. Now, one could use key management software coming with iKey, but keys created using OpenSC aren't compatible currently and vice versa. Meaning that, that you can use OpenSC OR Rainbow's own software. Sad. With OpenSC you can't currently authenticate yourself to Windows, but Mozilla and PuTTY should be fine. With Rainbow's software you can authenticate (if you have Active Directory server etc. horrible stuff) and something else - I haven't been playing around much.
Windows + PuTTY + OpenSC
OpenSC hosts PuTTY modification "Smart Card Bundle" which allows PuTTY and pageant to use our token. Just browse to http://www.opensc.org/files/ and download latest Smart Card Bundle (scb-*.exe) and extract. Then follow instructions from http://www.opensc.org/scb/wiki/PuttySmartcard. Also pageant seems to work when you add dummy smartcard.ppk key for it and connect. Even agent forwarding seems to work! Just don't try to use saved session for which you have configured smartcard or pageant will hang.
Final words
Huh?
Credits
Nils Larsch - For guiding me about usage of opensc.Hendrik Volkmer - For idea about storing key to first sectors of volume and some other great ideas too.
Vaclav Stepan - Some links and kind words :)