php 生成加密安全令牌

3htmauhk  于 2023-05-27  发布在  PHP
关注(0)|答案(5)|浏览(107)

为了生成一个32个字符的令牌来访问我们的API,我们目前用途:

$token = md5(uniqid(mt_rand(), true));

我读到过这种方法在密码学上不安全,因为它是基于系统时钟的,openssl_random_pseudo_bytes是一个更好的解决方案,因为它更难预测。
如果是这种情况,那么等效的代码会是什么样子?
我想是这样的,但我不知道这是否正确...

$token = md5(openssl_random_pseudo_bytes(32));

还有什么长度是有意义的,我应该传递给函数?

r6l8ljro

r6l8ljro1#

以下是正确的解决方案:

$token = bin2hex(openssl_random_pseudo_bytes(16));

# or in php7
$token = bin2hex(random_bytes(16));
e1xvtsh3

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

<?php
  require_once('path/to/cryptolib.php');
  $token = IcyApril\CryptoLib::randomString(16);
?>

完整的CryptoLib文档可在以下网址获得:https://cryptolib.ju.je/。它涵盖了很多其他的随机方法,级联加密和哈希生成和验证;但如果你需要就在那里

cbwuti44

cbwuti443#

如果你有一个加密安全的随机数生成器,你不需要散列它的输出。事实上你不想。就用

$token  = openssl_random_pseudo_bytes($BYTES,true)

其中$BYTES是您想要的数据字节数。MD5有一个128位的哈希,所以16字节就可以了。
顺便说一下,你在原始代码中调用的函数没有一个是加密安全的,大多数都是有害的,即使与其他安全的函数结合使用,只使用一个函数也是不安全的。MD5有安全问题(尽管对于此应用程序,它们可能不相关)。Uniqid不仅默认不生成加密随机字节(因为它使用系统时钟),而且传入的附加熵是使用线性同余生成器组合的,这在加密上是不安全的。事实上,这可能意味着人们可以猜测您的所有API密钥,即使他们不知道您的服务器时钟的值。最后,mt_兰德(),你使用的额外熵,也不是一个安全的随机数生成器。

xmjla07d

xmjla07d4#

另一个选项是使用ircmaxell(https://github.com/ircmaxell/RandomLib)中的RandomLib
安装:composer require ircmaxell/random-lib
示例中等强度

$factory = new Factory();
$factory->getMediumStrengthGenerator()->generateString(32);
nhhxz33t

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.它使用所有语言。

相关问题