gpt4 book ai didi

php - 使用PHP安全地加密MySQL数据库中静态的客户详细信息

转载 作者:行者123 更新时间:2023-12-04 20:24:52 25 4
gpt4 key购买 nike

我正在使用PHP开发一个应用程序,该程序将一些客户详细信息存储在MySQL数据库中。 (姓名,电子邮件地址,电话号码,邮寄地址)我没有存储任何“敏感”信息,例如银行/信用卡详细信息,SSN / SIN,DOB等。仅是基本的客户详细信息。

但是,尽管显然会有安全防范措施,但是如果黑客获得了数据库的副本,我希望有一种体面且相对简单的方法来使此数据变得非常难以使用(通过对其进行加密)。

我已经读到,在MySQL查询中执行加密的安全性较差,因为加密密钥将缓存在数据库的查询日志中。

因此,不建议这样:

UPDATE customers SET email = AES_ENCRYPT('me@gmail.com', SHA2('encryption key here', 512));


我已经查看了关于Stack Overflow的许多问题以及其他资源。但是,许多建议至少有5年的历史了,而PHP 7.2(及更高版本)现在可能有更简单的最佳实践。

我已经看过 Defuse,但是我倾向于避免在并非绝对需要它们的第三方库中使用。 (我更喜欢理解代码并将其最小化,以满足我的需求。)

通过查看PHP文档( https://www.php.net/manual/en/function.openssl-encrypt.php),我发现该用户提供了建议,该建议看起来相当简单容易实现:

--- Create Two Random Keys And Save Them In Your Configuration File ---
<?php
// Create The First Key
echo base64_encode(openssl_random_pseudo_bytes(32));

// Create The Second Key
echo base64_encode(openssl_random_pseudo_bytes(64));
?>
--------------------------------------------------------
<?php
// Save The Keys In Your Configuration File
define('FIRSTKEY', 'Lk5Uz3slx3BrAghS1aaW5AYgWZRV0tIX5eI0yPchFz4=');
define('SECONDKEY', 'EZ44mFi3TlAey1b2w4Y7lVDuqO+SRxGXsa7nctnr/JmMrA2vN6EJhrvdVZbxaQs5jpSe34X3ejFK/o9+Y5c83w==');
?>
--------------------------------------------------------
<?php
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;
}
?>
--------------------------------------------------------
<?php
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;
}
?>


您认为这相当安全吗?我以为我可能会改用AES-256-GCM,因为我认为GCM比CBC更好。

这样的加密是否满足我的需求? (同样,不会存储高度敏感的客户详细信息,并且“希望”这种安全级别(静态加密数据库字段)仍然是多余的。)

如果我跳过hash_hmac sha3-512部分而只使用openssl_encrypt函数怎么办?

最佳答案

我已经看过Defuse,但是我倾向于避免在并非绝对需要它们的第三方库中使用。 (我更喜欢理解代码并将其最小化,以满足我的需求。)


由于您的问题标题是使用PHP安全地加密MySQL数据库中静态的客户详细信息,因此我将不得不将答案分为两部分。

在保护客户数据的背景下,您(和其他任何人)将收到的建议是使用可信赖的库。

即使对于专家来说,密码学也很难做到正确。就在本月,发生了攻击against many low-level cryptography libraries。但是,我多年来在PHP社区中推荐的库(即libsodium)仍然不受这些攻击的影响(大多是by design)。

我和其他专家推荐的库旨在最大程度地提高安全性,最大程度地减少误用的可能性,并且易于审核。避免使用这些建议是因为您不想使用第三方库,尤其对于密码学而言,这是一个危险的立场。

如果您对“避免使用第三方库”的渴望恰好比保护客户更为重要,那么您可能应该告诉客户您在做什么,为什么做,以及安全行业的传统常识;这样他们就可以决定是否仍然要成为您的客户。

相反,如果您说出某种效果:“这是出于我自己的自我教育,没有现实世界的生产系统”,那么那是完全独立的事情。毕竟是Writing crypto to learn is a good thing

使用PHP + MySQL安全加密静态的客户详细信息

建议:使用CipherSweet

composer require paragonie/ciphersweet:^2


请记住,答案的这一部分是“我需要保护客户数据”。您不希望安装第三方库的愿望需要解决。保护客户是当务之急。

CipherSweet比 Defuse更进一步:除了解决“对称静态数据加密”问题以外,Cip​​herSweet还解决了“我想加密数据但仍在搜索数据”问题。

CipherSweet是可插入的;我们提供了两个后端( FIPSCryptoModernCrypto),但提供了一个接口,如果有人需要编写自己的接口,可以使用该接口。 (例如,如果由于某种原因需要SHA3和AES-GCM,则可以编写自己的 FIPSCrypto变体。)


CipherSweet文档为 available online

它的目的不仅是解释幕后情况,还指导开发人员安全地使用它。如果您遇到任何麻烦,请随时寻求帮助。


如果您确定不需要任何“可搜索”位,则仍可以使用CipherSweet,而无需为简单的AEAD接口创建盲索引。

另外,Defuse和 Halite是不错的选择。

但是重要的是,除非您是能够重新创建这些第三方库中的一个而不会意外引入漏洞的密码学工程师(例如:定时攻击或AES-CBC + HMAC,但忘记在身份验证中包含IV标签计算),那么您几乎应该肯定使用第三方库。

没有客户参与,我只想学习


我发现该用户提供了建议,该建议看起来相当简单容易实现:


您提供的代码不安全。具体来说,这部分代码没有涵盖HMAC标签计算中的IV:


$first_encrypted = openssl_encrypt($data, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$second_encrypted = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);



请注意 $first_encrypted如何传递给 hash_hmac()但不是 $iv吗?这是一个可利用的漏洞。

这是概念证明的利用:

// Encrypt a message    
$ciphertext = secured_encrypt('{"is_admin":0,"user_id":12345}');

$decoded = base64_decode($ciphertext);
$extractedIv = mb_substr($decoded, 0, 16, '8bit');
$flip = "\x00\x00\x00\x00\x00\x00\x00\x00" .
"\x00\x00\x00\x00\x01\x00\x00\x00";
$extractedIv = $extractedIv ^ $flip;

// Put alternative IV in place of existing IV.
$spliced = $extractedIv . mb_substr($decoded, 16, null, '8bit');
$reEncoded = base64_encode($spliced);

// Decrypt message
$decrypted = secured_decrypt($reEncoded);

var_dump($decrypted, json_decode($decrypted, true));


您应该看到以下内容:

string(30) "{"is_admin":1,"user_id":12345}"
array(2) {
["is_admin"]=>
int(1)
["user_id"]=>
int(12345)
}


因此,CBC + HMAC对开发人员来说是危险的。

using libsodium相比,要想使CBC + HMAC更加安全,您更容易学习 authenticated并学习如何在其提供的原语之上编写自己的高级协议。

如果要修复他们的代码,则需要进行这些更改。

补丁的secure_encrypt()

- $second_encrypted = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
+ $second_encrypted = hash_hmac('sha3-512', $iv . $first_encrypted, $second_key, TRUE);


补丁的secure_decrypt()

- $second_encrypted_new = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
+ $second_encrypted_new = hash_hmac('sha3-512', $iv . $first_encrypted, $second_key, TRUE);


您的问题的答案


我以为我可能会改用AES-256-GCM,因为我认为GCM比CBC更好。


AES-GCM优于CBC,因为GCM为 about 2^36 messages under a given key for AES-GCM,而CBC不是。

但是,您只能加密 。如果这不足以实现您的目标,那么AES-GCM也不适合。


这样的加密是否满足我的需求? (同样,不会存储高度敏感的客户详细信息,并且“希望”这种安全级别(静态加密数据库字段)仍然是多余的。)


如果不是因为我上面披露的漏洞,那就可能是。


如果我跳过hash_hmac sha3-512部分而只使用openssl_encrypt函数怎么办?


如果您切换到AES-GCM或libsodium,则只能放心使用它。未经身份验证的加密永远不应该被信任。

关于php - 使用PHP安全地加密MySQL数据库中静态的客户详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com