开发者

Generating one-time tokens via mcrypt in php?

i will be providing api keys to my partner sites and they will be using code that i give them to to generate "tokens".

these tokens will be automatically present on forms which the partner sites' users will click on and reach my site. when they reach my site, i will need to validate that they indeed came from a partner site.

how do i validate this? the apikey will be secret, but what is presented in the form will NOT be, so it must not be possible for smart users to reverse engineer my algorithm.


EDITA

Option1: I get teh client page to send across md5($apikey.$time) AND $time (in plaintext). When i get it, i use time and my copy of apikey to generate md5($apikey.$time). if it matches and is within 1 hour (or whatever), i let the request proceed.

Option2: I already have $userid,开发者_运维百科 $requestcommandoption coming in as well. I can do the following:

$input = $userid.'-'.$requestcommandoption.'-'.$time;

$encrypted_data = mcrypt_ecb (MCRYPT_3DES, $apikey, $input, MCRYPT_ENCRYPT);

when i get it at my end, i can do:

$decrypted_data = mcrypt_ecb (MCRYPT_3DES, $apikey, $encrypted_data, MCRYPT_DECRYPT);

and then check the 2 inputs if they are the same, and the 3rd if its within 1 hour?


EDITB

How secure does this sound? (code borrowed from http://onlamp.com/pub/a/php/2001/07/26/encrypt.html?page=3)

// on client
$apikey="test123";
$userid = '577';
$requestcommandoption = 'delete-all';
$time = mktime();
echo "time = $time<p>";

$input = $userid.'-'.$requestcommandoption.'-'.$time;

// Encryption Algorithm
$cipher_alg = MCRYPT_RIJNDAEL_128;

// Create the initialization vector for added security.
$iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher_alg, MCRYPT_MODE_ECB), MCRYPT_RAND);

// Encrypt $string
$encrypted_string = mcrypt_encrypt($cipher_alg, $apikey, $input, MCRYPT_MODE_CBC, $iv);

$transmitted = bin2hex($encrypted_string);

// sent from client    to server
print "Encrypted string: ".$transmitted."<p>";


// received on server    
$encrypted_string = pack("H*" , $transmitted);
$decrypted_string = mcrypt_decrypt($cipher_alg, $apikey, $encrypted_string, MCRYPT_MODE_CBC, $iv);

print "Decrypted string: $decrypted_string";


Looks as if you're implementing something similar to open authentication - the process twitter/facebook etc use for enabling partner sites.

I'd recommend that you take a look at oAuth - http://oauth.net/ - there are plenty of libraries and php samples.

If you really want to do something simple, then assuming you've got a record of the API keys you've handed out, I would write the client script so that it makes an md5 hash of the key with another bit of information on the form - a username for example (lets call the hashed string the request key and the username the username), and I'd include an identifier for the partner (which we'll call partner_id).

So when the form submits it has the requestkey, username and partner_id.

When your server receives the request you can look up the secret key for the partner using the partner_id, then md5 the secret key you've got, with the supplied user name and see if it matches the md5 key sent with the form.

@frank...

[Adding this as a result of your comment]

In order to make the key that is sent over the wire disposable, you can get the client web page to request a temporary session key - your server generates one (using a combination of date + time + a secret word), saves it as a temp key in the partners table (alongside their permanent key) and sends it back to the client. The client app then MD5's this with the permanent key and submits this with the form. You then look up the permanent and temp keys and hash them together and compare the result with the hash you've been sent.

does that seem ok?


What about GUIDs? Of course, you would have to track the issued GUIDs.

http://php.net/manual/en/function.com-create-guid.php


You should check out OAuth and OAuth 2 standards. They're widely used for authorization and many APIs (Facebook, Twitter, etc.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜