Free strong (two factor) authentication using One Time Passwords on your mobile phone

Authentication is the process by which you verify that someone is who they claim they are. In computerland this mostly involves a secret. By using the secret (for instance a password) in the authentication process Alice (there she is again) proves to Bob that she really is Alice since the secret is coupled to her (digital) identity. This process is as old as the road to Rome.
But not all secrets are as secret as we would like them to be. If i choose the name of my girlfriend as the secret, it might be easily guessed, even by someone who doesn’t know me, but is willing to go through the effort of making a few phone calls. Also secrets can be captured in transit, through shouldersurfing when you log in to the system, etcetera.

The next step in this game is strong authentication a.k.a. two factor authentication, this is where you combine two out of the next three options to prove your identity:

  • something you know (e.g. password, pin)
  • something you have (e.g. token, smartcard, cellphone)
  • something you are (e.g. fingerprint, iris pattern, DNA, voice)

So apart from capturing someones secret, Eve also has to steal the token/smartcard/cellphone or in case of biometrics duplicate your fingerprint/iris in a way the scanner is convinced that it’s still attached to a human being. This doesn’t make it impossible to authenticate as somebody else, it just makes it harder.

One of the problems with strong authentication is that it is expensive. You can get (for instance) an RSA token on a trade fair for free, but when you actually want to use one you have to buy the token and also buy the license for the authentication server that is needed to make it work, this may set you back between $50 – $100 per user.

Another disadvantage is the the cryptographic algorithm used to produce to codes is know only to the company, so you can’t use the RSA token and verify the authentication process to a authentication server of a different vendor. Also nobody can check if the cryptographic principles on with the product is build are sound. Good cryptography is build on open source so anyone can verify the correctness of it’s operation.
Luckily for us there is the Open Authentication Framework (OATH) which led to the definition of the “Hashed Message Authentication Code One Time Password” or HMAC OTP or even more concise HOTP. If you are interested you can read rfc4226 on it’s inner working’s and even build your own implementation.

The next step is to build our own strong authentication system using HOTP. Tri-D systems has an open source One Time Password authentication server available for download. They also sell the tokens to use for authentication, but since we are talking open source HOTP we can look for a company which sells the authentication server and has a (soft) token for free: Data Security Systems Solutions. They provide a free Java Phone Token which can generate the One Time Passwords.

Build Process

goto: http://www.tri-dsystems.com/software/downloads.html
accept license and download otpd-3.1.0.tar.gz & pam_otp_auth-3.2.2.tar.gz

gtar zxvf otpd-3.1.0.tar.gz
cd otpd-3.1.0/
./configure
make
make install

mkdir /etc/otpstate
touch /etc/otppasswd
chmod 600 /etc/otppasswd
chmod 700 /etc/otpstate
mkdir /var/run/otpd
touch /var/run/otpd/socket

install oathdsss on your Nokia or Windows Mobile phone
from: http://www.dsssasia.com/token.html
and start the program

First time initialization asks for a label, e.g. SEC
a seed length between 16 … 20 (choose 20)
OTP Length between 6 … 8 (choose 6)

Select Options -> Init
and register the seed displayed:
e.g. 44D060008BF440A2F9FF588AAD537F78B820F200
Now copy the seed to your computer, don’t make any mistakes or it won’t work.
The seed is case insensitive since it’s a hexadecimal number. If you are using a Windows Mobile device, you might have to switch it to landscape to see all the characters, you should see a left and right square bracket.

Do you want to set a PIN to protect the OTP?
Yes (otherwise it wouldn’t be two factor authentication)
Pin: ****
Pin Again: ****

If all goes well oathdsss finishes and when you start it
up again, you will be asked for a PIN and after that the
6 number OTP is displayed together with a countdown timer
running from 60 seconds.

Setting up the OTP server
Enter the generated seed from your cellphone into /etc/otppasswd

cat >> /etc/otppasswd
foo:hotp-d6:44D060008BF440A2F9FF588AAD537F78B820F200

foo is the username, alter it at your convenience
hotp-d6 is the token algorithm, so HOTP with a 6 digit OTP.

Generate two OTP’s from your cellphone and use them with resynctool (this is installed together with the OTP server) to save the state information which the OTP server will need in the authentication process:

resynctool -1 816857 -2 433761 -u foo -k 44D060008BF440A2F9FF588AAD537F78B820F200 > /etc/otpstate/foo

If you look at the contents of /etc/otpstate/foo you should see something like:

5:foo:0000000000000003:::0:0:0:

Due to a bug (i assume) resynctool is not able to work with 7 or 8 figure OTP’s (it will present you with the error message: resynctool: passcode 1 wrong length). There is also a second bug (maybe we should call it an discrepancy). While resynctool writes: 0000000000000003 meaning the first two OTP’s have been used and the next to be presented is number 3, the otp server reads that 0000000000000003 as: the first three OTP’s have been used and the next to be presented is number 4. So change the number back to 0000000000000002 or generate an OTP from you cellphone and don’t use it.

Testing authentication

start up otpd as root in debug mode:

# otpd -D
otpd: otpd 3.1.0 starting
otpd: accept_thread: tid=3086179248

Now generate an OTP from your phone and test it with:

# otpauth -u foo -p 549855 -s /var/run/otpd/socket
0 (ok)

On the otp server you will see:

otpd: accept_thread: plugin accept fd=5
otpd: work_thread: tid=3076053936, fd=5
otpd: work_thread(3076053936,5): handling plugin request for [foo]
otpd: verify: [foo], sync challenge t:0 e:0 0000000000000004, expecting response 549855
otpd: verify: user [foo] authentication succeeded
otpd: work_thread(3076053936,5): plugin disconnect

If you don’t see a 0 (ok) from otpauth, you might get a 3 (authentication error) which means you didn’t present the expected OTP to the server. In the server debug window you will see 5 OTP’s (configurable through /etc/otpd.conf) which the server expects from that user account. Generate another one from you phone an you will immediately see if that one is in the list and will work.
If you get a 5 (service error) there is something wrong with your configuration and you have to fix that first before authentication will work.

You might want to play around a little bit more with the HOTP software to get a grip on how it’s working. An easier way to generate the OTP’s is through a small perl program on your computer. For this you have to install the Authen::HOTP module:

perl -MCPAN -e 'install Authen::HOTP'

And then create this program:
[perl]
#!/usr/bin/perl
use Authen::HOTP qw(hotp);
use strict;

my $secret=”44D060008BF440A2F9FF588AAD537F78B820F200″;
my $counter=$ARGV[1];
my $digits=$ARGV[0];

my $pass = hotp($secret, $counter, $digits);
print “$pass\n”;
[/perl]

Now it’s a easy as:

# ./hotp.pl 6 5
853481

If you got a successful authentication we can proceed to doing something useful with HOTP. Tri-D delivers a pam-otp module which you can use on a local system to replace your standard username/password authentication dialog. But they really recommend using the OTP daemon through RADIUS.
So download freeradius and compile & install:

cd /tmp
wget ftp://ftp.freeradius.org/pub/radius/freeradius-1.1.7.tar.bz2
gtar jxvf freeradius-1.1.7.tar.bz2
cd freeradius-1.1.7
./configure
make
make install

cd redhat/
cat rc.radiusd-redhat > /etc/init.d/radiusd
chkconfig --add radiusd
chkconfig --list radiusd
radiusd         0:off   1:off   2:off   3:off   4:off   5:off   6:off

On my redhat system i had to modify /etc/init.d/radiusd to read:
RADIUSD=/usr/local/sbin/radiusd
and i had to run ldconfig again or otherwise radiusd would complain about
a missing libradius-1.1.7.so

Modify the radius configuration /usr/local/etc/raddb/radiusd.conf to allow for One Time Passwords:

  • remove the comment (#) before: $INCLUDE ${confdir}/otp.conf
  • add otp directly below authorize {
  • add otp directly below authenticate {

And start otpd and the radius service up:

# otpd
# service radiusd start
Starten van RADIUS server:                                 [  OK  ]

Now we can test OTP authentication through RADIUS with the radtest program:

# ./hotp.pl 6 11
885417

# radtest foo 885417 localhost 10 testing123
Sending Access-Request of id 197 to 127.0.0.1 port 1812
        User-Name = "foo"
        User-Password = "885417"
        NAS-IP-Address = 255.255.255.255
        NAS-Port = 10
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=197, length=20

# tail -1 /var/log/messages
May  1 23:25:10 vortex otpd[11395]: verify: user [foo] authentication succeeded

testing123 is the default RADIUS secret for localhost, you MUST change that in:
/usr/local/etc/raddb/clients.conf, the NAS port number (10) is not used.

On my testbox there was no pam_radius_auth module, so:

cd /tmp
wget ftp://ftp.freeradius.org/pub/radius/pam_radius-1.3.17.tar.gz
gtar zxvf pam_radius-1.3.17.tar.gz
cd pam_radius-1.3.17
make
cp pam_radius_auth.so /lib/security/
cat  pam_radius_auth.conf > /etc/raddb/server
chmod go-rwx /etc/raddb/server

Edit /etc/raddb/server to match te secret for localhost in /usr/local/etc/raddb/clients.conf, next add a line in /etc/pam.d/system-auth like this:

auth        required      /lib/security/$ISA/pam_env.so
auth        sufficient    /lib/security/$ISA/pam_unix.so likeauth nullok
auth        sufficient    /lib/security/pam_radius_auth.so try_first_pass
auth        required      /lib/security/$ISA/pam_deny.so

This will allow normal password authentication, but if you are providing an OTP the unix password authentication will fail and the OTP is passed on to the pam_radius_auth module for validation.

You can also use OTP authentication on you Apache webserver by using the mod_auth_radius module.

Have fun!

sources:
Foo Bar Quux
Tri-D QuickStart Guide

Update 20080529
Since it looks like the Tri-D site is offline, i will make my copies of otpd and pam_otp_auth available for download: