PHP中的Bcrypt坏了?可以很容易地包含任何恶意负载


Bcrypt broken in PHP? Can easily include any malicious payload

盐:可以是任何东西
工作因素:可以是任何东西
以下所有内容都生成相同的哈希

$pad = base64_decode('/gB=');
$data = array(
    'LegitimatePayload',
    'LaterSwitchedToMaliciousPayload',
    'Abracadabra',
    'hatIsGoingOn',
    'CanBeAlmostAnything',
);
foreach($data as $str){
    echo crypt($pad.$str, '$2a$04$AnySaltHere')."<br>'n";
}


输出:

$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa

编辑:
这是一个前两个字节相同但哈希不同的字符串:
base64_decode('/gBJyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg===')
如果php在第一个NUL字节停止,那么如何解释呢?

所有字符串都有一个前缀,当通过base64_decode运行时,该前缀将产生一个0xfe字符和一个在0x00之后具有额外变化字符的0x00字符。由于标准密码将在0x00字符处停止,因此您的所有密码调用都只加密0xfe字符。

您只需调用即可验证

echo crypt("'376", '$2a$04$AnySaltHere')."<br>'n";

这将给出相同的结果。

我假设您错误地使用了base64_decode,意思是实际调用base64_encode

编辑:正如Roman所指出的,字符串

"/gBQyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg==="

实际上——尽管有相同的前缀——会完全加密到其他东西。这是因为该字符串实际上是无效的base64,base64_decode返回false。这导致字符串被加密到与空字符串相同的哈希值。

您没有提供任何有效的base64编码字符串,因此base64_decode可能只会对所有测试用例返回false,因此它会对它们进行相同的加密。为什么要使用base64_decode?

您可能想要base64_encode而不是base64_decode。它全部返回相同的原因是因为结果总是错误的。