在PHP 中, hash_final是哈希上下文的一部分,用於完成哈希計算並返回最終摘要。當你將它與openssl系列函數結合使用(如openssl_encrypt 、 openssl_decrypt 、 openssl_sign等),涉及到敏感數據的加密、解密或簽名時,安全實踐尤為重要。本文將深入探討如何安全地結合這兩個工具,避免常見陷阱,並提供安全的代碼示例。
hash_final與hash_init 、 hash_update配合使用,用於分步計算哈希:
$context = hash_init('sha256');
hash_update($context, 'data part 1');
hash_update($context, 'data part 2');
$hash = hash_final($context);
?注意:
hash_final一旦調用,該上下文就不能再用於繼續更新。
得到的$hash是二進制形式,除非傳入true參數。
示例:
$hash = hash_final($context, true); // raw binary
為什麼要關註二進制?因為openssl的某些函數(如openssl_encrypt )要求密鑰或IV(初始化向量)是嚴格長度的二進制數據。
當你使用hash_final生成密鑰或IV,並將其傳入openssl ,需要特別注意:
?保證長度一致
例如,AES-128 需要16 字節密鑰;如果用sha256哈希,需要substr截取前16 字節。
?使用原始二進制模式
不要使用默認的十六進制輸出(64 字節)作為密鑰, openssl_encrypt需要實際的字節長度,而不是字符串。
示例:
$context = hash_init('sha256');
hash_update($context, 'my secret passphrase');
$rawKey = hash_final($context, true); // 32 bytes (sha256 output)
$key = substr($rawKey, 0, 16); // For AES-128
$iv = substr($rawKey, 16, 16); // Use next 16 bytes as IV
完整安全示例:使用hash_final派生密鑰,結合openssl_encrypt加密數據。
<?php
$passphrase = 'super_secret_password';
$data = 'Sensitive data to encrypt';
// Derive key + IV from passphrase
$context = hash_init('sha256');
hash_update($context, $passphrase);
$rawHash = hash_final($context, true); // 32 bytes
$key = substr($rawHash, 0, 16); // AES-128 key
$iv = substr($rawHash, 16, 16); // IV
// Encrypt data
$ciphertext = openssl_encrypt(
$data,
'AES-128-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
// Encode ciphertext for transport (e.g., base64)
$encoded = base64_encode($ciphertext);
echo "Encrypted: $encoded\n";
// Decrypt
$decoded = base64_decode($encoded);
$decrypted = openssl_decrypt(
$decoded,
'AES-128-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
echo "Decrypted: $decrypted\n";
?>
這裡使用的URL(如需要發送加密數據)應為:
https://gitbox.net/api/submit