PHP SRP php Secure Remote Password

PHP SRP php Secure Remote Password

If you don’t know what SRP is, then by all means – Find Out about SRP from the creators.. For a brief overview, it is a way to authenticate without sending a password plaintext or hashed. The method is similar in theory to public key cryptography in that math functions are used to calculate tokens help validate the identity of the user. There is an existing implementation that appears to work somewhat out of the box that can be found on another blog entitled: Secure Ajax: SRP Hermetic. I was able to get the code to work with some slight modifications to get the database code to work with mysql.

PHP SRP php Secure Remote Password – Details

The author of the blog post does a good job of outlining how to get started using the package so I encourage those interested to check out the blog, but I will provide details about how to modify the code to allow either postgres or mysql databases to work.

The first file we need to look at is in the config.php located in the hermetic/config folder. The default file contains a database connection string with full details specified inline in 1 string. I changed this so that there are variables used where the parameters are and created the variables such as follows.

$dbname = 'srp';
$dbuser = 'srp_user';
$dbpass = 'srp';
$host = '127.0.0.1';

$dbConnectString = 'host='.$host.' port='.$port.' dbname='.$dbname.' user='.$dbuser.' password='.$dbpass.';

I quickly realized that I needed some way to select between database types so I made a quick define pair such as the following:


define ( "__POSTGRES_DB__",1);
define ( "__MYSQL_DB__",1);

This can be checked by using the following code wherever the database connection needs to be queried or connected or closed.

if ( defined ( "__POSTGRES_DB__" ) ){
// postgres code
}else if ( defined ( "__MYSQL_DB__" ) ){
// mysql code
}

I found that the files I had to modify were: hermetic/php/include/storage.php as well as demo/php/user_service.php. The file storage.php contains the connection code as well as a simple select statement whereas the user_service.php file contains the user management code that is used by the files in demo/html such as generateverifier.html and usermanagement.html.

Readers should know that there are two javascript jquery versions included in the html files previously mentioned that can be removed individually depending on whether or not you want to use a local copy or the google code copy. NOTE: the local copy does not exist in the download at the time of this writing.

There were some caveats getting this code to work in a windows environment. For instance – there is no /dev/random in windows. To make up for this problem I made some changes.

function unix_random($bits){
	error_log("Before /dev/random");
	$f = fopen("/dev/urandom","r");
    $randomBytes = fread($f, $bits/8);
    fclose($f);
	error_log("After /dev/random");
	return $randomBytes ;
}

function windows_random($bits){
	$data = '\0';
	for ( $i = 0 ; $i < $bits / 8 ; $i++ ){
		$data .= pack("C",mt_rand(1, 0xFF));
	}
	return $data ;
}

function secure_random($bits) {
    $result = '';
    $digits = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
	if ( __PLATFORM__ == "unix" ){
		$randomBytes = unix_random($bits);
    }else if ( __PLATFORM__ == "windows" ){
		$randomBytes = windows_random($bits);
	}
 

This obviously means some things as far as the quality of the random generator but allows the implementation to work.

NOTE: Please see the link below for possible security implications.

The final change that was made is the change from memcache requirements to using another db table to store the session information. The modifications are spread between the storage.php file as well as the user_service.php file. The example code can be viewed below.

function srpStorePendingVerification($username, $A, $data) {
	// $cache = memcacheConnect();
	$db = dbConnect();
    $cacheKey = 'incompleteSrpSession'.$username.':'.$A;
	$resultset = mysql_query ( "INSERT INTO token VALUES ('".$cacheKey."','".$data."')", $db );
}

function srpRestorePendingVerification($username, $A) {
	// $cache = memcacheConnect();
	$db = dbConnect();
    $cacheKey = 'incompleteSrpSession'.$username.':'.$A;
	$resultset = mysql_query ( "SELECT * FROM token WHERE token='".$cacheKey."'", $db );
	$result = mysql_fetch_object($resultset);
    $serialData = $result->data;
	$resultset = mysql_query ( "DELETE FROM token WHERE token='".$cacheKey."'", $db );
    //$cache->delete($cacheKey);
    return $serialData;
}

function storeSessionInfo($sessionId, $info, $timeout) {
    //$cache = memcacheConnect();
	$db = dbConnect();
    $cacheKey = "srpSessionInfo".$sessionId;
	$resultset = mysql_query ( "INSERT INTO token VALUES ('".$cacheKey."','".json_encode($info)."')", $db );
    //$cache->set( $cacheKey, json_encode($info), 0,  $timeout);
}

function loadSessionInfo($sessionId) {
    //$cache = memcacheConnect();
	$db = dbConnect();
    $cacheKey = 'srpSessionInfo'.$sessionId;
	$resultset = mysql_query ( "SELECT * FROM token WHERE token='".$cacheKey."'", $db );
    //$info = $cache->get($cacheKey);
	$result = mysql_fetch_object($resultset);
    $info = json_decode($result->data);
    //$info = json_decode($info);
    return $info;
}

Check out the demo here

Information related to the security of mt_rand in php under certain conditions can be foundhere. These details were provided by the original author.

ttessier

About ttessier

Professional Developer and Operator of SwhistleSoft
This entry was posted in Uncategorized. Bookmark the permalink.

One Response to PHP SRP php Secure Remote Password

  1. Roy says:

    Uau!
    This is quite impressive to see the “sniffed” data…

Leave a Reply

Your email address will not be published. Required fields are marked *