PHP中hex2bin与使用PASSWORD_DEFAULT算法的password_hash是否等价?相关代码验证及原理疑问
问题拆解与解答
1. password_verify($sel, $password)的返回结果?
答案是:不会返回true,大概率返回false,甚至可能触发错误。
原因很简单,咱们顺着代码里的变量流转看:
$token = random_bytes(32);:生成的是32字节的原始二进制数据(不是人类可读的十六进制字符串,里面可能包含任意字节值,包括不可打印字符)。$sel = hex2bin($token);:hex2bin()的作用是把十六进制格式的字符串转换成二进制数据,但你给它传的是原始二进制的$token——这根本不是合法的十六进制字符串(随机二进制里几乎肯定有不符合十六进制规则的字节),所以这个调用会直接抛出警告,$sel会变成false或者无效的乱码数据。password_hash($token, PASSWORD_DEFAULT);:这里是把原始二进制的$token作为明文密码,生成对应的哈希值。
当你用password_verify($sel, $password)时,$sel要么是错误的转换结果,要么是false,和原始的$token完全不匹配,所以验证必然失败,返回false。
哦对了,如果你是手滑写成$sel = bin2hex($token);(把二进制转十六进制),那验证还是会失败——因为password_verify会拿$sel(十六进制字符串)和哈希时用的$token(原始二进制)做比对,两者内容完全不同,自然验证不通过。只有当你用完全相同的明文去验证时,才会返回true。
2. 验证过程的核心原理
PHP的password_hash()和password_verify()是一套专门用于密码哈希的安全工具,核心逻辑是这样的:
password_hash()会自动生成一个随机盐值(salt),然后把盐值和明文密码一起,通过指定的哈希算法(比如默认的bcrypt)生成哈希字符串。最终返回的哈希字符串里包含了盐值和算法信息,不需要你单独存储盐值。password_verify()会先从传入的哈希字符串里解析出盐值和算法,然后用同样的算法把待验证的明文和盐值重新哈希,最后把新生成的哈希和原哈希做比对——如果完全一致,就返回true,否则返回false。
这里的关键是:必须用和哈希时完全相同的明文去验证。不管是把二进制转十六进制,还是做其他编码转换,只要明文内容变了,验证就会失败。
3. password_hash和bin2hex功能相同吗?
完全不相同,两者根本不是一类工具:
bin2hex()是字符串编码转换函数,作用是把二进制数据转换成十六进制格式的字符串,只是做数据格式的转换,没有任何哈希或加密操作,你还能通过hex2bin()把转换后的字符串转回去。password_hash()是密码哈希函数,它会对输入的明文进行加盐哈希处理,生成不可逆的安全哈希值,专门用于存储密码——你永远没法从生成的哈希值反推出原始明文。
内容的提问来源于stack exchange,提问作者Hello Hello
相关产品推荐
相关产品推荐

