0

When this function is called the first time, it will return a hash value based on a part of the current timestamp.

function getAccessKey(){
    $code = '';
    $curTime = time();
    $code = md5(substr($curTime,0,7)); 
    return $code;
}

The value returned will change sometime between 1 and 1000 seconds relative to the first time it is called.

I don't know if this is possible, but I am looking for a way to control the time interval at which the string value changes, WITHOUT storing the timestamp of the original function call. For example, I would like to invalidate the access key (change the string) 90 seconds from the time of the original call. Has anyone used an algorithm that does something like this?

Thanks

Edit: Just to clarify - the above method will be used by 3rd parties as an API call, that will allow them to build a "passwordless login" link. I do not want them to have to store any data or make any secondary API calls to use this. I just want the returned access key code to work for 90 seconds from the time it is requested, and then fail to work after 90 seconds from the request. I'm not concerned about the type of encryption used at this point, just pondering the ability to invalidate the string after a specific time interval.

Jason Fingar
  • 3,358
  • 1
  • 21
  • 27
  • 1
    You can't just using md5 – jeremy Sep 10 '12 at 20:57
  • you cannot "revert" a hash back to its original values. You could use an actual bi-directional encryption (aes?) to create a 'garbage' string but leave the original contents recoverable... or you store the original timestamp as well. – Marc B Sep 10 '12 at 20:57
  • 1
    ... or you can append a timestamp to your hash (but you still need to use it as a part of incoming string to verify it) – zerkms Sep 10 '12 at 20:58
  • 1
    Are you persisting this timestamp value somewhere (database, session, etc.) – Mike Brant Sep 10 '12 at 20:58

3 Answers3

0

I guess I don't understand the need to encrypt anything. Why not just use:enter code here

function getAccessKey($duration_in_secs) {
    $expiration = time() + $duration_in_secs;
    $_SESSION['access_key_expiry'] = $expiration;
}

Then just check your session variable to make sure the current time is less than the time of expiry.

Mike Brant
  • 70,514
  • 10
  • 99
  • 103
0

How about something like this (I didn't add all the necessary checks and validations, it's just a proof of concept. Instead of md5() any other hashing function can be used, it doesn't change anything):

function getAccessKey($ttl)
{
    $somePrivateKey = 'foobar';

    $expirationTime = time() + $ttl;


    $code = md5($somePrivateKey . $expirationTime) . base_convert($expirationTime, 10, 16); 
    return $code;
}

function verifyKey($key)
{
    $somePrivateKey = 'foobar';

    $hash = substr($key, 0, 32);
    $expirationTime = base_convert(substr($key, 32), 16, 10);

    return md5($somePrivateKey . $expirationTime) == $hash && time() <= $expirationTime;
}

$key = getAccessKey(90);

var_dump(verifyKey($key));
zerkms
  • 249,484
  • 69
  • 436
  • 539
0

Why not using encryption ?

I was inspired by this question which make possible to securely work with expiration date.

$time = time() + 90;
$key = "a private password";

echo "Expiration time = {$time}<br/>";

$code = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $time, MCRYPT_MODE_CBC, md5(md5($key))));

echo "Sharable encrypted code = {$code}<br/>";

(....... and after some time, your $code is coming back)

$time = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($code), MCRYPT_MODE_CBC, md5(md5($key))), "\0");

echo "Decoded time is {$time}...";

if ($time < time()) {
    echo "Code has expired<br/>";
} else {
    echo "Code is OK<br/>";
}

This will output :

Expiration time = 1347312816
Sharable encrypted code = ioVqtqZud+iexObaGBF418i0gHKHshjsy+mj+oM4KMw=
Decoded time is 1347312816...Code is OK

With such a method you need two functions :

// returns a code valid $duration seconds
function createKey($duration) {
    $key = "a private password";
    $time = time() + $duration;
    $code = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $time, MCRYPT_MODE_CBC, md5(md5($key))));
    return $code;
}

// returns true if code is still valid
function checkKey($code)
{
    $key = "a private password";
    $time = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($code), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
    return ($time >= time());
}
Community
  • 1
  • 1
Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153