我做了很多研究并提出了以下 php 代码。但我不是专业程序员,所以我只是问自己,如果这是正确的方法,我如何使用“openssl_encrypt()”和“hash_hmac()”这两个函数。
如果能从你们那里得到一些专业的反馈那就太好了。
这是迄今为止我的代码:
// Encryption Function
function secured_encrypt($data) {
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$method = "aes-256-cbc";
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);
$first_encrypted = openssl_encrypt($data,$method,$first_key, OPENSSL_RAW_DATA ,$iv);
$second_encrypted = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
$output = base64_encode($iv.$second_encrypted.$first_encrypted);
return $output;
}
function secured_decrypt($input) {
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$mix = base64_decode($input);
$method = "aes-256-cbc";
$iv_length = openssl_cipher_iv_length($method);
$iv = substr($mix,0,$iv_length);
$second_encrypted = substr($mix,$iv_length,64);
$first_encrypted = substr($mix,$iv_length+64);
$data = openssl_decrypt($first_encrypted,$method,$first_key,OPENSSL_RAW_DATA,$iv);
$second_encrypted_new = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
if (hash_equals($second_encrypted,$second_encrypted_new)) return $data;
return false;
}
我在 PHP 手册的评论中看到了它,并获得了很多赞成票,但事实是 SECONDKEY 根本不参与加密。它仅用于验证数据的哈希值。在该代码中,仅使用 FIRSTKEY 来加密和解密消息,这就是黑客解密消息所需的全部内容(因为 $iv 以纯文本形式包含在其中)。
只需使用 PHP 手册中提供的 $tag 和“aes-128-gcm”即可实现相同级别的数据身份验证(哈希验证),即:
<?php
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
// ENCRYPTION
$ciphertext = openssl_encrypt($plaintext, $cipher, base64_decode(FIRSTKEY), $options=0, $iv, $tag);
// DECRYPTION
//store $cipher, $iv, and $tag for decryption later
$original_plaintext = openssl_decrypt($ciphertext, $cipher, base64_decode(FIRSTKEY), $options=0, $iv, $tag);
echo $original_plaintext."\n";
}
?>
将 FIRSTKEY 与代码的其余部分分开存储可以提供您想要的额外安全层(在您提供的示例中可能没有其他内容)。是否将 $iv 和 $tag 与加密数据一起存储取决于您(因为我认为您没有通过公共通信渠道传递它)。您可以通过将 $iv 和 $tag 存储在另一个存储中(即另一台服务器上的单独数据库)来添加另一个级别的安全性。
请记住,无论您进行多少次加密,如果黑客可以通过访问您服务器的文件系统来对其进行反向工程,那么它们都是徒劳的。 IE。如果我可以访问您的服务器,我可以创建包含
<?php echo FIRSTKEY; ?>
的 PHP 文件 :D