I've knocked up the following script which does what the originator of this thread asked for.
First off, save the following as a script that you will be passing your user login variables to - specifically, "username" and "password".
<?PHP
# Simple Cypher / Encryption script
# 18.11.2005
# Author - Brit
# PHPBuilder thread ID - 10312506
# REQUIREMENTS: You must ensure you can read the key file"
# VARIABLES: This script expects to be passed POST variables "username" and "password"
/* The following should be altered as required. */
/* 1. The path to the keyfile which will hold the current key data (put trailing slash!) */
DEFINE("KEY_FILE","/path/to/docroot/");
/* 2. The name of the file you will use to store the key data */
DEFINE("KEY_FILE_NAME","keyfile.txt");
/* 3. The length of time, in hours, that a key is valid for */
DEFINE("EXPIRATION","72");
/* 4. Where does a user who successfully authenticates get sent to? */
DEFINE("REDIRECT_ON_SUCCESS","/thankyou.html");
/* 5. Administrative email options */
DEFINE("ADMIN_EMAIL","your@email.com");
DEFINE("ADMIN_SUBJECT","Message from simple cypher script");
DEFINE("ADMIN_FROM","Your server");
DEFINE("ADMIN_REPLY","do-not-reply@your-server.com");
/* 6. Send email if key file has expired and someone tries to use it? */
DEFINE("SEND_ADMIN_EMAIL",true);
/* 7. The error message displayed when a username and password combination fails */
DEFINE("ERROR_MSG","Error!");
/* 8. Output actual encrypted values to screen, for information */
DEFINE("SHOW_OUTPUT",false);
/*************************************************************************************/
/* The rest of the script which you shouldn't need to change, happens below this break
/*************************************************************************************/
/*************************/
/* Send email if enabled
/*************************/
function sendAdminEmail($msg)
{
/* Send an email to the nominated administrative contact, if this is enabled */
if(SEND_ADMIN_EMAIL)
{
$headers = sprintf("From: %s <%s>\r\n",ADMIN_FROM,ADMIN_REPLY);
mail(ADMIN_EMAIL,ADMIN_SUBJECT,$msg,$headers);
}
}
/*************************/
/* Check the key file
/*************************/
function checkKeyFile()
{
/* Make sure the file exists, and we can read it. */
if(!is_file(KEY_FILE.KEY_FILE_NAME) || !is_readable(KEY_FILE.KEY_FILE_NAME))
{
$msg = sprintf("Fatal error: cannot find/read key file at %s!\n",KEY_FILE.KEY_FILE_NAME);
sendAdminEmail($msg); /* Send email */
echo substr($msg,0,38);
die;
}
/* Make sure the key file is still valid. */
else
{
$key_file_modified = filemtime(KEY_FILE.KEY_FILE_NAME);
$key_file_expires = ((EXPIRATION*60*60)+$key_file_modified);
$time_now = date("U");
/* Key file has expired */
if($key_file_expires < $time_now)
{
$msg = "Fatal error: current key file has expired!";
sendAdminEmail($msg);
echo $msg;
die;
}
/* Key file is valid */
else
{
authenticateUser();
}
}
}
/*************************/
/* Encrypt a letter based on keyfile value
/*************************/
function returnLetterPosition($letter)
{
/* Open the key file and get the position marker */
$key_data = parse_ini_file(KEY_FILE.KEY_FILE_NAME);
$key_data_value = $key_data[key_value];
$key_data_fallback_value = $key_data[key_fallback];
/* Find the position of $letter in the array */
$character_array = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9");
$character_position = array_search($letter,$character_array);
/* This entire section now deals with the replacement of each $letter */
/* First just add the array position and the new key value */
$character_new_position = (($character_position-1)+$key_data_value);
/* If we're outside the array, go the other way instead */
if($character_new_position > count($character_array))
{
$character_new_position = ($character_position-$key_data_value);
}
/* If we're in the negatives, go back up again */
if($character_new_position < 0)
{
$character_new_position = (($character_new_position/$key_data_fallback_value)-$character_new_position);
}
/* Return the replacement letter */
return $character_array[$character_new_position];
}
/*************************/
/* Authenticate a user
/*************************/
function authenticateUser()
{
/* Make the POST data safe, strip tags and external white space */
foreach($_POST as $key => $val)
{
$_data[$key] = trim(strip_tags($val));
}
/* If we have both the username and password, check them */
if(isset($_data["username"]) && isset($_data["password"]) && strlen($_data["username"]) > 1 && strlen($_data["password"]) > 1)
{
/* Get the 'encrypted' version of the username */
$user_length = strlen($_data["username"]);
for($i=0;$i<$user_length;$i++)
{
$encrypted_username .= returnLetterPosition(substr($_data["username"],$i,1));
}
/* Show output at this stage for information, if option is true */
if(SHOW_OUTPUT)
{
$output = sprintf("<pre>Encrypted value for username %s is %s</pre>",$_data["username"],$encrypted_username);
echo $output;
die;
}
/* If the encrypted username matches the password, user is OK */
if($encrypted_username == $_data["password"])
{
header(sprintf("Location:%s",REDIRECT_ON_SUCCESS));
die;
}
/* If it doesn't, die. */
else
{
echo ERROR_MSG;
die;
}
}
/* If we're here, we were not given both username and password - so die. */
else
{
echo ERROR_MSG;
die;
}
}
/*************************/
/* Start everything off
/*************************/
checkKeyFile();
?>
Next, put a plain text file somewhere on your server, and make sure it looks like this (ensure that you name the file whatever you have defined KEY_FILE_NAME as):
** KEYFILE. THIS MUST BE A NUMBER BETWEEN 2 AND 45. **
** If you use a value of 1, no encryption will happen **
key_value = 45;
** Put a value between 2 and 10 here, it is used as a fallback measure later **
key_fallback = 4;
Next, simply point a form that takes the variables "username" and "password" at the main PHP script, and its done.
Some features of this script are:
Automatic expiration; (Define EXPIRATION) you can define how long keys are valid for, by entering the relevant number of hours.
Output mode; (Define SHOW_OUTPUT) which allows you to see the password for a given username.
Email to admin in case of expiration or missing key data file.
It should be fairly self explanatory!
Regards,
Brit.