通过PHP中的mcrypt生成一次性令牌?

时间:2011-04-20 08:37:07

标签: php cryptography security encryption

我将向我的合作伙伴网站提供api密钥,他们将使用我提供给他们的代码来生成“令牌”。

这些代币将自动显示在合作伙伴网站的用户点击并访问我的网站的表单上。当他们到达我的网站时,我需要验证他们确实来自合作伙伴网站。

我该如何验证? apikey将是秘密的,但表单中的内容不会出现,因此智能用户无法对我的算法进行反向工程。


选项1:我通过md5($ apikey。$ time)和$ time(以纯文本格式)发送客户端页面。当我得到它时,我使用时间和我的apikey副本来生成md5($ apikey。$ time)。如果它匹配并且在1小时内(或其他),我让请求继续。

选项2:我已经有了$ userid,$ requestcommandoption。我可以做到以下几点:

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

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

当我得到它的时候,我可以做到:

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

然后检查2个输入是否相同,如果是1小时则检查第3个输入?


EDITB

这听起来有多安全? (从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";

3 个答案:

答案 0 :(得分:2)

GUID怎么样?当然,您必须跟踪已发布的GUID。

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

答案 1 :(得分:2)

您应该查看OAuthOAuth 2标准。它们被广泛用于授权和许多API(Facebook,Twitter等)

答案 2 :(得分:2)

看起来好像你正在实施类似于开放认证的东西 - 推特/ facebook等用于启用合作伙伴网站的过程。

我建议你看看oAuth - http://oauth.net/ - 有很多库和php样本。

如果你真的想做一些简单的事情,那么假设你已经记录了你发放的API密钥,我会编写客户端脚本,这样它就会产生一个md5哈希的密钥。表单上的信息 - 例如用户名(让哈希字符串称为请求密钥,用户名称称为用户名),并且我将包含合作伙伴的标识符(我们称之为partner_id)。

因此,当表单提交时,它具有requestkey,username和partner_id。

当您的服务器收到请求时,您可以使用partner_id查找伙伴的密钥,然后使用提供的用户名md5查找您获得的密钥,并查看它是否与表单一起发送的md5密钥匹配

... @frank

[根据您的评论添加此内容]

为了使通过一次性线路发送的密钥成为可用,您可以获取客户端网页以请求临时会话密钥 - 您的服务器生成一个(使用日期+时间+密码的组合),保存它作为合作伙伴表中的临时密钥(以及它们的永久密钥)并将其发送回客户端。然后客户端应用程序MD5使用永久密钥,并使用表单提交。然后,您查找永久密钥和临时密钥并将它们一起散列,并将结果与​​您已发送的哈希值进行比较。

看起来好吗?