java messagedigest的php等价物

zfciruhq  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(545)

**结束。**此问题需要详细的调试信息。它目前不接受答案。
**想改进这个问题吗?**更新问题,使其成为堆栈溢出的主题。

11天前关门了。
改进这个问题
我正在尝试用php实现java函数。本质上是messagedigest java类。
我对密码学有点陌生,所以我想详细了解一下为什么最终的解决方案是有效的。
这是java代码

import java.math.BigInteger;
import java.security.MessageDigest;

String password = "xxxxxxx";
MessageDigest m = MessageDigest.getInstance("sha-256");
m.update(password.getBytes(), 0, password.length());
return new BigInteger(1, m.digest()).toString(16);

目前在php我正在做

use phpseclib\Math\BigInteger as Math_BigInteger;

$password = "xxxxxxx";
$sha_password = hash('sha256', unpack("C*",$password), true);
return new Math_BigInteger($sha_password, 16);

目前这将不会有相同的输出,请一些帮助。。。为什么?

camsedfj

camsedfj1#

您的java代码在这行中有一个bug:

m.update(password.getBytes(), 0, password.length());

字符串的字节表示不一定与字符串中的字符数具有相同的字节数。由于使用unicode,一个字符可以编码成多个字节。要使用整个密码而不仅仅是其中的一部分,请改用以下密码:

m.update(password.getBytes());

但这仍然不够,因为java代码在不同的环境中可能表现不同。您需要显式指定编码。在我的测试中 m.update(password.getBytes("UTF-8")); 很好地建立了与php代码的兼容性。
由于java代码生成十六进制编码的摘要,因此应使用以下php代码:

$password = "xxxxxxx";
$sha_password = hash('sha256', $password, false);

产生

7b70d3ab4c7641542e1f158b458eeae7cfb7bdb815d4110cc6178bafcfdf43f8

安全注意事项:
通过一轮哈希运算来运行密码通常是不够的。今天的暴力工具每秒可以检查数十亿个密码。您应该根据您的用例使用pbkdf2或scrypt。

相关问题