The Joy of S/Key

One Time Passwords (OTP) are certainly nothing new. In fact, they have been in use for
over ten years. The idea is essentially very simple: every time you login to a system, you use a different password. If someone were to eavesdrop on the connection, the password they captured would be
useless to them.

In 1994, Neil Haller of Bellcore announced the “S/KEY One Time Password System”
at the Symposium on Network and Distributed System Security. It described a practical way to implement OTP that was both secure and simple. Over the years it has matured into strong, practical system that is now described by RFC2289. Furthermore, implementations exist for many Operating Systems, and just about all BSD flavours include it as standard. Despite this, it is still rare, in my experience anyway, to encounter people that have even heard of it. As far as I can tell, there are two main reasons for its lack of popularity:

  1. In the days of SSH and encrypted traffic, people no longer think it’s necessary.
  2. In order to login to a system using S/KEY, you need a computer to generate the next
    password, which raises the question of how you securely login to it.

While both points appear valid, they are both flawed.

It is true that SSH arguably does a better job of protecting passwords from eavesdroppers. In fact SSH provides for more than that, and it also protects all content from eavesdroppers. However there is one very common form of attack to which SSH is not immune: keylogging. Keyloggers record the keys you hit, and they don’t care whether
you’re using an SSH client or telnet. They have to be installed on the machine you are using, either in software or hardware. However, now that we live in the age of Microsoft and Cybercafes, using a
trojanised machine is all too easy to do. What most people don’t realise is that SSH, or at least OpenSSH, is already S/KEY aware. So why not use it ?

As for the second point, indeed you do need a computer. However – you, dear reader, almost certainly have a computer in your pocket or on your wrist at this moment. In fact, if your mobile phone is Java-enabled , which
these days is quite likely, then you can use it to generate S/KEY passwords. Very much like an RSA SecurID fob, only cheaper, and without a six-month lifespan.

This article gives an introduction to S/Key, together with an example of how to start using
it on OpenBSD. The final section of this article lists several links to further reading, S/Key generators and details of using it on other Operating Systems.

The Guts

This section explains how S/Key actually works. Feel free to skip it if you’re not interested although, in my opinion at least, it is not only interesting, but quite beautiful!

A user wishing to use OTP to login to a server
must first initialise the S/Key system. The initialisation consists
of a short string provided by the server, known as the seed,
and a secret passphrase provided by the user. The two strings are
concatenated and passed through a hash function. RFC2289 allows for
the use of three different hash functions: MD4, MD5 and SHA-1. The
choice of hash is left up to the user.

The output of the hash function is then reduced,
or folded, to 64-bits using a method described in the RFC.
This 64-bit value, known as theinitial step,is then
passed through the hash function, and again folded. This process
continues until the hash has been applied a number of times, let’s
say 99. The server then stores the final output, together with the
seed value and the number of times the hash was applied, the
sequence number,
in the server’s
S/Key database. The system is now ready to accept a login.

When the user wishes to
login to the server, the server provides a challenge, which
consists of the chosen hash, the seed and a number which is one less
than the sequence number stored in the database; in this case, 98.

The user then
goes through the same procedure used to produce the initial step and
hashes it that number of times. The resulting 64-bit hash is
the One Time Password.

The user then conveys this password to the server
(more about this later).

Remember that this is not going to be the same as
the hash stored in the server’s S/Key database, which has been hashed
one more time. So, in order to compare it to that which is stored in
the database , the server must hash the password one more time. If it
matches, the user has demonstrated they know the passphrase and so
they have successfully been authenticated. The server stores the
password as provided by the user (i.e. before the server applied the
final hash) together with the new, lower, sequence number (98) in the
database and logs the user in.

The next time the user logs in, the sequence
number in the challenge will be the next lowest sequence number, in
this case 97.

From this we can infer:

  • Eavesdroppers, or keyloggers, obtaining the
    password will find it of no use since the next login will require a
    different password.
  • Even if someone gains access to the S/Key
    database, the information will be useless to them, as they will need
    to reverse the hash algorithm to find the next password.
  • After all of the sequence numbers have been
    exhausted, the user will need to re-initialise the system with a new
    seed, and optionally a new passphrase. This is arguably a good side

There is one significant step in the process that
has been omitted thus far. Whilst the user may legitimately type the
8 digit hex number in response to the challenge, humans are
notoriously averse to this sort of thing. Consequently, RFC2289 also
provides a user-friendly way of expressing the 64-bit passphrase in
English. A simple algorithm is provided, together with a small
lexicon, that describes a method by which any 64-bit string can be
converted to a list of six words, and back again. For example, the
64-bit number:

3F3B F4B4 145F D74B

would be converted to the English words:


For most users, this makes the whole procedure far
less painless and far more acceptable.

Using S/KEY

Initially, the system
needs to have S/Key enabled. The superuser merely needs to issue the

skeyinit -E

And the system will be available to all users.

Each user that wishes to use S/Key needs to initialise their account. The skeyinit(1)
program is used for this, too. In this example we plan to use SHA1
hashes, and so the command issued is:

skeyinit -sha1

The system responds with a warning and prompts the user to enter their current system password:

- Only use this method if you are directly connected
          or have an encrypted channel.  If you are using telnet,
          hit return now and use skeyinit -s.

If the authentication
was successful, the user is then prompted for their secret
passphrase. In our example the passphrase is “fred is dead”:

[Updating zaphod with sha1]
Enter secret passphrase: 
Again secret passphrase:

ID zaphod skey is otp-sha1 99 dorm23705
Next login password: MASK OMEN BOOM IRMA SMUG TORE

The account is now initialised, and skeyinit responds with the next
challenge and corresponding password. You don’t need to know these at
this stage but it’s comforting to know that everything is working.

let’s try logging in. We ssh as normal, except we append ‘:skey’ to
the username. This tells ssh that we wish to use S/Key

$ ssh -l zaphod:skey

The server then
responds with a challenge:

otp-sha1 98 dorm23705
S/Key Password: 

using our favourite S/Key generator, we generate the password for
this session. This simply involves supplying the generator with the
challenge, which consists of the sequence number (“98”)
and seed (“dorm23705”), the hash type (‘SHA1’),
and the secret passphrase (“fred is dead”).

How these are supplied
to the generator depends entirely on generator used. For example, if
you are logging in from a OpenBSD machine, you will probably use the
skey(1) command line tool. In this case the command issued would be:

skey-sha1 98 dorm23705

which will then prompt
you for the passphrase.

If, however, you are
using vejotp, the challenge can be stored in the Java device’s memory
and so the most you will need to supply is the passphrase.

Whichever S/Key
generator you choose, the password in this case will be:


Type this at the “S/Key
Password” prompt and, all being well, you’re in!

next time you wish to login, the challenge will be slightly
different. The seed (“dorm23705”) will remain the same,
however the sequence number will be decreased by one (“97”).
You’ll see that the password generated in response to this challenge
will be completely different:


If you use a BSD and
are concerned about security, then this simple, brilliant system is
already there for you. It is not a replacement for SSH and other
forms of encrypted protocols, but it does provide additional security
for a very small amount of extra effort. It also impresses the suits
who, at last, have been forced to take security seriously.

Leave a Reply