Encrypting Passwords using crypt()
Theory:
Function: char * crypt (const char *key,
const char *salt)
The crypt function takes a password, key, as a
string, and a salt character array which
is described below, and returns a printable
ASCII string which starts with another salt.
It is believed that, given the output of the
function, the best way to find a key that
will produce that output is to guess values of
key until the original value of key is
found.
The salt parameter does two things. Firstly, it
selects which algorithm is used, the
MD5-based one or the DES-based one. Secondly, it
makes life harder for someone trying to
guess passwords against a file containing many
passwords; without a salt, an intruder can
make a guess, run crypt on it once, and compare
the result with all the passwords. With a
salt, the intruder must run crypt once for each
different salt.
For the MD5-based algorithm, the salt should
consist of the string $1$, followed by up to
8 characters, terminated by either another $ or
the end of the string. The result of crypt
will be the salt, followed by a $ if the salt
didn't end with one, followed by 22
characters from the alphabet ./0-9A-Za-z, up to
34 characters total. Every character in
the key is significant.
For the DES-based algorithm, the salt should
consist of two characters from the alphabet
./0-9A-Za-z, and the result of crypt will be
those two characters followed by 11 more from
the same alphabet, 13 in total. Only the first 8
characters in the key are significant.
The MD5-based algorithm has no limit on the
useful length of the password used, and is
slightly more secure. It is therefore preferred
over the DES-based algorithm.
When the user enters their password for the
first time, the salt should be set to a new
string which is reasonably random. To verify a
password against the result of a previous
call to crypt, pass the result of the previous
call as the salt.
The following short program is an example of how
to use crypt the first time a password is
entered. Note that the salt generation is just
barely acceptable; in particular, it is not
unique between machines, and in many
applications it would not be acceptable to let an
attacker know what time the user's password was
last set.*/
Function: char * crypt_r (const char *key, const
char *salt, struct crypt_data * data)
The crypt_r function does the same thing as
crypt, but takes an extra parameter which
includes space for its result (among other
things), so it can be reentrant.
data->initialized must be cleared to zero
before the first time crypt_r is called.
The crypt_r function is a GNU extension.
The crypt and crypt_r functions are prototyped
in the header crypt.h.
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// C program:
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
#include <stdio.h>
#include <time.h>
#include
<unistd.h>
#include
<string.h>
int main(void)
{
char
salt[] = "$1$abcdefgh"; /* This should be random */
char
*password;
printf("salt is : %s\n", salt);
/* Read in
the user's password and encrypt it. */
printf("##################################################################\n");
printf("Enter Original Password\n");
password =
crypt(getpass("Password:"), salt);
printf("##################################################################\n");
/* Print
the results. */
puts(password);
char
original_pass[50] = {0};
strcpy(original_pass, password);
printf("##################################################################\n");
char
*cur_passwd;
printf("Enter password same as original password\n");
cur_passwd
= crypt(getpass("Password:"), password);
/* Print
the results. */
puts(cur_passwd);
printf("##################################################################\n");
printf("\n\nCompare Now: Original password: %s Current Password: %s",
original_pass, cur_passwd);
if
(strcmp(original_pass, cur_passwd) == 0)
{
printf("\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("****************** PASSWORD MATCH
*****************\n");
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
} else {
printf("\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("\nCurrent Password and Original Password Don't
Match\n");
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
}
return 0;
}
Compilation:
gcc -o crypt crypt.c -lcrypt
Compilation:
gcc -o crypt crypt.c -lcrypt
Output:
Password match Case:
Neelkanth_221$ ./crypt
salt is : $1$abcdefgh
##################################################################
Enter Original Password
Password:
##################################################################
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Enter password same as original password
Password:
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Compare Now: Original password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1 Current Password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
****************** PASSWORD MATCH *****************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
salt is : $1$abcdefgh
##################################################################
Enter Original Password
Password:
##################################################################
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Enter password same as original password
Password:
$1$abcdefgh$e.zGC9egaBizsEd9YFd.C.
##################################################################
Compare Now: Original password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1 Current Password: $1$abcdefgh$e.zGC9egaBizsEd9YFd.C.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Current Password and Original Password Don't Match
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Neelkanth_221$ ./crypt
salt is : $1$abcdefgh
##################################################################
Enter Original Password
Password:
##################################################################
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Enter password same as original password
Password:
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Compare Now: Original password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1 Current Password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
****************** PASSWORD MATCH *****************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Password No-match Case:
Neelkanth_221$ ./cryptsalt is : $1$abcdefgh
##################################################################
Enter Original Password
Password:
##################################################################
$1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1
##################################################################
Enter password same as original password
Password:
$1$abcdefgh$e.zGC9egaBizsEd9YFd.C.
##################################################################
Compare Now: Original password: $1$abcdefgh$Qlx6NNORPMsnE3/ehfisr1 Current Password: $1$abcdefgh$e.zGC9egaBizsEd9YFd.C.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Current Password and Original Password Don't Match
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@