In the previous article we covered the Authentication Methods used while working with FreeRADIUS. This article by Dirk van der Walt, author of FreeRADIUS Beginner's Guide, teaches methods for storing passwords and how they work. Passwords do not need to be stored in clear text and it is better to store them in a hashed format. There are, however, limitations to the kind of authentication protocols that can be used when the passwords are stored as a hash which we will explore in this article.
(For more resources on this subject, see here.)
Username and password combinations have to be stored somewhere. The following list mentions some of the popular places:
The users file and the SQL database that can be used by FreeRADIUS store the username and password as AVPs. When the value of this AVP is in clear text, it can be dangerous if the wrong person gets hold of it. Let's see how this risk can be minimized.
To reduce this risk, we can store the passwords in a hashed format. A hashed format of a password is like a digital fingerprint of that password's text value. There are many different ways to calculate this hash, for example MD5 or SHA1. The end result of a hash should be a one-way fixed-length encrypted string that uniquely represents the password. It should be impossible to retrieve the original password out of the hash.
To make the hash even more secure and more immune to dictionary attacks we can add a salt to the function that generates the hash. A salt is randomly generated bits to be used in combination with the password as input to the one way hash function. With FreeRADIUS we store the salt along with the hash. It is therefore essential to have a random salt with each hash to make a rainbow table attack difficult. The pap module, which is used for PAP authentication, can use passwords stored in the following hash formats to authenticate users:
Both MD5 and SSH1 hash functions can be used with a salt to make it more secure.
We will replace the Cleartext-Password AVP in the users file with a more secure hashed password AVP in this section.
There seems to be a general confusion on how the hashed password should be created and presented. We will help you clarify this issue in order to produce working hashes for each format.
A valuable URL to assist us with the hashes is the OpenLDAP FAQ:
http://www.openldap.org/faq/data/cache/419.html
There are a few sections that show how to create different types of password hashes. We can adapt this for our own use in FreeRADIUS.
Crypt password hashes have their origins in Unix computing. Stronger hashing methods are preferred over crypt, although crypt is still widely used.
#> perl -e 'print(crypt("passme","salt")."n");'
[pap] Using CRYPT password "sa85/iGj2UWlA"
The MD5 hash is often used to check the integrity of a file. When downloading a Linux ISO image you are also typically supplied with the MD5 sum of the file. You can then confirm the integrity of the file by using the md5sum command.
We can also generate an MD5 hash from a password. We will use Perl to generate and encode the MD5 hash in the correct format that is required by the pap module. The creation of this password hash involves external Perl modules, which you may have to install first before the script can be used. The following steps will show you how:
#! /usr/bin/perl -w
use strict;
use Digest::MD5;
use MIME::Base64;
unless($ARGV[0]){
print "Please supply a password to create a MD5 hash from.n";
exit;
}
my $ctx = Digest::MD5->new;
$ctx->add($ARGV[0]);
print encode_base64($ctx->digest,'')."n";
chmod 755 4088_04_md5.pl
./4088_04_md5.pl passme
"alice" MD5-Password := "ugGBYPwm4MwukpuOBx8FLQ=="
[pap] Using MD5 encryption.
This is an MD5 password with salt. The creation of this password hash involves external Perl modules, which you may have to install first before the script can be used.
#! /usr/bin/perl -w
use strict;
use Digest::MD5;
use MIME::Base64;
unless(($ARGV[0])&&($ARGV[1])){
print "Please supply a password and salt to create a salted
MD5 hash from.n";
exit;
}
my $ctx = Digest::MD5->new;
$ctx->add($ARGV[0]);
my $salt = $ARGV[1];
$ctx->add($salt);
print encode_base64($ctx->digest . $salt ,'')."n";
chmod 755 4088_04_smd5.pl
./4088_04_smd5.pl passme salt
Remember that you should use a random value for the salt. We only used salt here for the demonstration.
"alice" SMD5-Password := "Vr6uPTrGykq4yKig67v5kHNhbHQ="
[pap] Using SMD5 encryption.