fir*_*ire 75 php security openssl token
为了生成32个字符的令牌以访问我们目前使用的API,我们目前使用:
$token = md5(uniqid(mt_rand(), true));
Run Code Online (Sandbox Code Playgroud)
我已经读过这种方法不是加密安全的,因为它基于系统时钟,这openssl_random_pseudo_bytes将是一个更好的解决方案,因为它更难预测.
如果是这种情况,等效代码会是什么样的?
我推测这样的事情,但我不知道这是不对的......
$token = md5(openssl_random_pseudo_bytes(32));
Run Code Online (Sandbox Code Playgroud)
我应该传递给函数的长度是多少?
fir*_*ire 172
这是正确的解决方案:
$token = bin2hex(openssl_random_pseudo_bytes(16));
# or in php7
$token = bin2hex(random_bytes(16));
Run Code Online (Sandbox Code Playgroud)
mjs*_*jsa 10
如果你想使用openssl_random_pseudo_bytes,最好使用CrytoLib的实现,这将允许你生成所有字母数字字符,在openssl_random_pseudo_bytes周围粘贴bin2hex只会导致你得到AF(上限)和数字.
将path/to替换为您放置cryptolib.php文件的位置(您可以在GitHub上找到它:https://github.com/IcyApril/CryptoLib)
<?php
require_once('path/to/cryptolib.php');
$token = CryptoLib::randomString(16);
?>
Run Code Online (Sandbox Code Playgroud)
完整的CryptoLib文档可从以下网址获得:https://cryptolib.ju.je/ .它涵盖了许多其他随机方法,级联加密和哈希生成和验证; 但如果你需要它就在那里.
如果您有加密安全随机数生成器,则不需要对其输出进行散列.实际上你不想这样做.只是用
$token = openssl_random_pseudo_bytes($BYTES,true)
Run Code Online (Sandbox Code Playgroud)
但是,$ BYTES需要多个字节的数据.MD5有一个128位散列,所以16个字节就可以了.
作为旁注,您在原始代码中调用的函数都不是加密安全的,大多数都是有害的,即使与安全的其他函数结合使用,只使用一个函数会破坏不安全.MD5存在安全问题(尽管对于此应用程序,它们可能不相关).Uniqid默认情况下不会生成加密随机字节(因为它使用系统时钟),所传入的附加熵使用线性全等生成器进行组合,该生成器不具有加密安全性.事实上,它可能意味着即使他们不知道您的服务器时钟的价值,也可以猜测所有API密钥的访问权限.最后,mt_rand(),你用作额外熵,也不是一个安全的随机数发生器.