PHP哈希hash('sha256', md5("password"))的Java等价实现问题
问题原因
PHP的hash('sha256', md5("password"))执行逻辑是:
- 对密码做MD5哈希,得到十六进制字符串(32个字符)
- 将这个十六进制字符串作为输入,计算其SHA256哈希
而你使用的Java代码DigestUtils.sha256Hex(DigestUtils.md5("password"))逻辑是:
- 对密码做MD5哈希,得到原始字节数组(16字节)
- 直接对这个字节数组做SHA256哈希
两者的输入对象完全不同,因此哈希结果必然不一致。
正确的Java实现
基于Apache Commons Codec的实现
先将MD5哈希结果转为十六进制字符串,再对该字符串计算SHA256哈希:
import org.apache.commons.codec.digest.DigestUtils; public class HashConverter { public static void main(String[] args) { String password = "password"; // 获取MD5的十六进制字符串 String md5HexStr = DigestUtils.md5Hex(password); // 对MD5十六进制字符串计算SHA256哈希 String targetHash = DigestUtils.sha256Hex(md5HexStr); System.out.println(targetHash); } }
纯JDK实现(无需第三方库)
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HexFormat; public class HashConverter { public static void main(String[] args) throws NoSuchAlgorithmException { String password = "password"; // 计算MD5并转为十六进制字符串 MessageDigest md5Digest = MessageDigest.getInstance("MD5"); byte[] md5Bytes = md5Digest.digest(password.getBytes()); String md5HexStr = HexFormat.of().formatHex(md5Bytes); // 计算MD5十六进制字符串的SHA256哈希 MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); byte[] sha256Bytes = sha256Digest.digest(md5HexStr.getBytes()); String targetHash = HexFormat.of().formatHex(sha256Bytes); System.out.println(targetHash); } }
结果验证
以密码password为例,上述Java代码的执行结果与PHP的hash('sha256', md5("password"))输出完全一致:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

