S/Key is a one-time password scheme based on a one-way hash function. FreeBSD uses the MD4 hash for compatibility but other systems have used MD5 and DES-MAC. S/Key has been part of the FreeBSD base system since version 1.1.5 and is also used on a growing number of other operating systems. S/Key is a registered trademark of Bell Communications Research, Inc.
There are three different sorts of passwords which we will talk about in the discussion below. The first is your usual UNIX-style or Kerberos password; we will call this a "UNIX password". The second sort is the one-time password which is generated by the S/Key key program and accepted by the keyinit program and the login prompt; we will call this a "one-time password". The final sort of password is the secret password which you give to the key program (and sometimes the keyinit program) which it uses to generate one-time passwords; we will call it a "secret password" or just unqualified "password".
The secret password does not have anything to do with your UNIX password; they can be the same but this is not reccomended. S/Key secret passwords are not limted to 8 characters like UNIX passwords, they can be as long as you like. Passwords of six or seven word long phrases are fairly common. For the most part, the S/Key system operates completely independently of the UNIX password system.
Besides the password, there are two other pieces of data that are important to S/Key. One is what is known as the "seed" or "key" and consists of two letters and five digits. The other is what is called the "iteration count" and is a number between 1 and 100. S/Key creates the one-time password by concatenating the seed and the secret password, then applying the MD4 hash as many times as specified by the iteration count and turning the result into six short English words. These six English words are your one-time password. The login and su programs keep track of the last one-time password used, and the user is authenticated if the hash of the user-provided password is equal to the previous password. Because a one-way hash is used it is impossible to generate future one-time passwords if a sucessfully used password is captured; the interation count is decremented after each sucessfull login to keep the user and the login program in sync. When the iteration count gets down to 1 S/Key must be reinitialized.
There are four programs involved in the S/Key system which we will discuss below. The key program accepts an iteration count, a seed, and a secret password, and generates a one-time password. The keyinit program is used to initialized S/Key, and to change passwords, iteration counts, or seeds; it takes either a secret password, or an iteration count, seed, and one-time password. The keyinfo program examines the /etc/skeykeys file and prints out the invoking user's current iteration count and seed. Finally, the login and su programs contain the necessary logic to accept S/Key one-time passwords for authentication. The login program is also capable of disallowing the use of UNIX passwords on connections coming from specified addresses.
There are four different sorts of operations we will cover. The first is using the keyinit program over a secure connection to set up S/Key for the first time, or to change your password or seed. The second operation is using the keyinit program over an insecure connection, in conjunction with the key program over a secure connection, to do the same. The third is using the key program to log in over an insecure connection. The fourth is using the key program to generate a number of keys which can be written down or printed out to carry with you when going to some location without secure connections to anywhere.
To initialize S/Key for the first time, change your password, or change your seed while logged in over a secure connection (e.g., on the console of a machine or via ssh), use the keyinit command without any parameters while logged in as yourself:
% keyinit Adding unfurl: Reminder - Only use this method if you are directly connected. If you are using telnet or rlogin exit with no password and use keyinit -s. Enter secret password: Again secret password: ID unfurl s/key is 99 to17757 DEFY CLUB PRO NASH LACE SOFT
At the Enter secret password: prompt you should enter a password or phrase. Remember, this is not the password that you will use to login with, this is used to generate your one-time login keys. The "ID" line gives the parameters of your particular S/Key instance; your login name, the iteration count, and seed. When logging in with S/Key, the system will remember these parameters and present them back to you so you do not have to remember them. The last line gives the particular one-time password which corresponds to those parameters and your secret password; if you were to re-login immediately, this one-time password is the one you would use.
To initialize S/Key or change your secret password over an insecure connection, you will need to already have a secure connection to some place where you can run the key program; this might be in the form of a desk accessory on a Macintosh, or a shell prompt on a machine you trust. You will also need to make up an iteration count (100 is probably a good value), and you may make up your own seed or use a randomly-generated one. Over on the insecure connection (to the machine you are initializing), use the keyinit -s command:
% keyinit -s Updating unfurl: Old key: to17758 Reminder you need the 6 english words from the key command. Enter sequence count from 1 to 9999: 100 Enter new key [default to17759]: s/key 100 to 17759 s/key access password:
To accept the default seed (which the keyinit program confusingly calls a key), press return. Then before entering an access password, move over to your secure connection or S/Key desk accessory, and give it the same parameters:
% key 100 to17759 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: <secret password> CURE MIKE BANE HIM RACY GORE
Now switch back over to the insecure connection, and copy the one-time password generated by key over to the keyinit program:
s/key access password:CURE MIKE BANE HIM RACY GORE ID unfurl s/key is 100 to17759 CURE MIKE BANE HIM RACY GORE
The rest of the description from the previous section applies here as well.
Once you've initialized S/Key, when you login you will be presented with a prompt like this:
% telnet example.com Trying 10.0.0.1... Connected to example.com Escape character is '^]'. FreeBSD/i386 (example.com) (ttypa) login: <username> s/key 97 fw13894 Password:
As a side note, the S/Key prompt has a useful feature (not shown here): if you press return at the password prompt, the login program will turn echo on, so you can see what you are typing. This can be extremely useful if you are attempting to type in an S/Key by hand, such as from a printout. Also, if this machine were configured to disallow UNIX passwords over a connection from my machine, the prompt would have also included the annotation (s/key required), indicating that only S/Key one-time passwords will be accepted.
At this point you need to generate your one-time password to answer this login prompt. This must be done on a trusted system that you can run the key command on. (There are versions of the key program from DOS, Windows and MacOS as well.) The key program needs both the iteration count and the seed as command line options. You can cut-and-paste these right from the login prompt on the machine that you are logging in to.
On the trusted system:
% key 97 fw13894 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: WELD LIP ACTS ENDS ME HAAG
Now that you have your one-time password you can continue logging in:
login: <username> s/key 97 fw13894 Password: <return to enable echo> s/key 97 fw13894 Password [echo on]: WELD LIP ACTS ENDS ME HAAG Last login: Tue Mar 21 11:56:41 from 10.0.0.2 ...
This is the easiest mechanism if you have a trusted machine. There is a Java S/Key key applet, The Java OTP Calculator, that you can download and run locally on any Java supporting browser.
Sometimes you have have to go places where you do not have access to a trusted machine or secure connection. In this case, it is possible to use the key command to generate a number of one-time passwords before hand to be printed out and taken with you. For example:
% key -n 5 30 zz99999 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: <secret password> 26: SODA RUDE LEA LIND BUDD SILT 27: JILT SPY DUTY GLOW COWL ROT 28: THEM OW COLA RUNT BONG SCOT 29: COT MASH BARR BRIM NAN FLAG 30: CAN KNEE CAST NAME FOLK BILK
The -n 5 requests five keys in sequence, the 30 specifies what the last iteration number should be. Note that these are printed out in reverse order of eventual use. If you are really paranoid, you might want to write the results down by hand; otherwise you can cut-and-paste into lpr. Note that each line shows both the iteration count and the one-time password; you may still find it handy to scratch off passwords as you use them.
Restrictions can be placed on the use of UNIX passwords based on the host name, user name, terminal port, or IP address of a login session. These restrictions can be found in the configuration file /etc/skey.access. The skey.access(5) manual page has more info on the complete format of the file and also details some security cautions to be aware of before depending on this file for security.
If there is no /etc/skey.access file (this is the FreeBSD default), then all users will be allowed to use UNIX passwords. If the file exists, however, then all users will be required to use S/Key unless explicitly permitted to do otherwise by configuration statements in the skey.access file. In all cases, UNIX passwords are permitted on the console.
Here is a sample configuration file which illustrates the three most common sorts of configuration statements:
permit internet 192.168.0.0 255.255.0.0 permit user fnord permit port ttyd0
The first line (permit internet) allows users whose IP source address (which is vulnerable to spoofing) matches the specified value and mask, to use UNIX passwords. This should not be considered a security mechanism, but rather, a means to remind authorized users that they are using an insecure network and need to use S/Key for authentication.
The second line (permit user) allows the specified username, in this case fnord, to use UNIX passwords at any time. Generally speaking, this should only be used for people who are either unable to use the key program, like those with dumb terminals, or those who are uneducable.
The third line (permit port) allows all users logging in on the specified terminal line to use UNIX passwords; this would be used for dial-ups.