为了生成一个32个字符的令牌来访问我们的API,我们目前用途:
$token = md5(uniqid(mt_rand(), true));
我读到过这种方法在密码学上不安全,因为它是基于系统时钟的,openssl_random_pseudo_bytes
是一个更好的解决方案,因为它更难预测。
如果是这种情况,那么等效的代码会是什么样子?
我想是这样的,但我不知道这是否正确...
$token = md5(openssl_random_pseudo_bytes(32));
还有什么长度是有意义的,我应该传递给函数?
5条答案
按热度按时间r6l8ljro1#
以下是正确的解决方案:
e1xvtsh32#
如果你想使用openssl_random_pseudo_bytes,最好使用CrytoLib的实现,这将允许你生成所有的字母数字字符,在openssl_random_pseudo_bytes周围粘贴bin 2 hex只会导致你得到A-F(大写)和数字。
将path/to/替换为您放置cryptolib.php文件的位置(您可以在GitHub上找到它:https://github.com/IcyApril/CryptoLib)
完整的CryptoLib文档可在以下网址获得:https://cryptolib.ju.je/。它涵盖了很多其他的随机方法,级联加密和哈希生成和验证;但如果你需要就在那里
cbwuti443#
如果你有一个加密安全的随机数生成器,你不需要散列它的输出。事实上你不想。就用
其中$BYTES是您想要的数据字节数。MD5有一个128位的哈希,所以16字节就可以了。
顺便说一下,你在原始代码中调用的函数没有一个是加密安全的,大多数都是有害的,即使与其他安全的函数结合使用,只使用一个函数也是不安全的。MD5有安全问题(尽管对于此应用程序,它们可能不相关)。Uniqid不仅默认不生成加密随机字节(因为它使用系统时钟),而且传入的附加熵是使用线性同余生成器组合的,这在加密上是不安全的。事实上,这可能意味着人们可以猜测您的所有API密钥,即使他们不知道您的服务器时钟的值。最后,mt_兰德(),你使用的额外熵,也不是一个安全的随机数生成器。
xmjla07d4#
另一个选项是使用ircmaxell(https://github.com/ircmaxell/RandomLib)中的RandomLib
安装:
composer require ircmaxell/random-lib
示例中等强度
nhhxz33t5#
可靠的密码只能由ascii字符a-zA-Z和数字0-9组成。要做到这一点,最好的方法是只使用加密安全的方法,如PHP7中的random_int()或random_bytes()。Rest函数为base64_encode()只能作为支持函数使用,以使字符串可靠并将其更改为ASCII字符。
**mt_兰德()**是不安全的,并且非常旧。对于任何字符串,必须使用random_int()。从二进制字符串你应该使用base64_encode()使二进制字符串可靠或bin 2 hex,但你会削减字节只有16个位置(值)。See my implementation of this functions.它使用所有语言。