Hash 扩展
PHP 的 Hash 扩展提供了丰富的哈希算法支持,包括 MD5、SHA 系列、HMAC 等。它允许以统一的方式计算各种哈希值,也支持增量式哈希计算。
前置知识
阅读本节前,建议先了解:OpenSSL 扩展
hash() 函数
php
<?php
declare(strict_types=1);
// 常用哈希
echo "MD5: " . hash('md5', 'hello') . PHP_EOL;
echo "SHA1: " . hash('sha1', 'hello') . PHP_EOL;
echo "SHA256: " . hash('sha256', 'hello') . PHP_EOL;
echo "SHA384: " . hash('sha384', 'hello') . PHP_EOL;
echo "SHA512: " . hash('sha512', 'hello') . PHP_EOL;
// 获取所有可用算法
$algos = hash_algos();
echo "支持 " . count($algos) . " 种算法" . PHP_EOL;
// 常用安全哈希
echo "SHA3-256: " . hash('sha3-256', 'hello') . PHP_EOL;
echo "Blake2b: " . hash('blake2b', 'hello') . PHP_EOL;HMAC
php
<?php
declare(strict_types=1);
// HMAC 计算消息认证码
$key = 'my-secret-key';
$message = 'Hello World';
$hmac = hash_hmac('sha256', $message, $key);
echo "HMAC-SHA256: {$hmac}" . PHP_EOL;增量哈希
php
<?php
declare(strict_types=1);
// 逐步计算大文件的哈希
$ctx = hash_init('sha256');
hash_update($ctx, '第一部分数据');
hash_update($ctx, '第二部分数据');
hash_update($ctx, '第三部分数据');
$hash = hash_final($ctx);
echo "增量 SHA256: {$hash}" . PHP_EOL;
// 流式哈希大文件
$ctx = hash_init('sha256');
$fp = fopen('/path/to/large.file', 'rb');
while (!feof($fp)) {
hash_update($ctx, fread($fp, 8192));
}
fclose($fp);
$fileHash = hash_final($ctx);
echo "文件哈希: {$fileHash}" . PHP_EOL;hash_equals() 时序安全比较
php
<?php
declare(strict_types=1);
// 防止时序攻击的比较
$storedToken = 'abc123def456';
$providedToken = 'abc123def457';
// 错误:使用 === 可能泄漏信息
// if ($providedToken === $storedToken) {}
// 正确:使用 hash_equals
if (hash_equals($storedToken, $providedToken)) {
echo "Token 匹配" . PHP_EOL;
} else {
echo "Token 不匹配" . PHP_EOL;
}最佳实践
- 密码存储用 password_hash,不要用 hash()
- 使用 SHA-256+ 进行数据校验,避免 MD5/SHA1
- 大文件用增量哈希:避免内存溢出
- Token 比较用 hash_equals:防止时序攻击
下一节
继续学习:Sodium 扩展