是否可以使用 PHP 加密数据mcrypt
并使用 MySQL 在数据库中解密AES_DECRYPT
?目前,我在 PHP 上使用RIJNDAEL_128
for 。mcrypt
我还确保数据库中的加密字段具有 data type blob
。然而,AES_DECRYPT
使用正确的密钥仍然返回NULL
。关于如何让它工作的任何建议?
3 回答
我在这里找到了一些很好的帮助
请注意,这适用于纯文本中最多 65519 个字符的加密文本。(如果没有 UTF-8 编码可能会更多)
要加密的 PHP 代码:
// MySQL uses 16 bytes key for 128 encryption/decryption
$key = "ABCDEF0123456789";
$plaintext = "This string was AES-128 / EBC / ZeroBytePadding encrypted.";
// Optionally UTF-8 encode
$plaintext_utf8 = utf8_encode($plaintext);
// Find out what's your padding
$pad_len = 16 - (strlen($plaintext_utf8) % 16);
// Padd your text
$plaintext_utf8 = str_pad($plaintext_utf8, (16 * (floor(strlen($plaintext_utf8) / 16) + 1)), chr($pad_len));
// Encryption
mt_srand();
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, false);
// Generates a warning about empty IV but it's Ok
$ciphertext = mcrypt_generic($td, $plaintext_utf8);
mcrypt_generic_deinit($td);
$ciphertext = mysql_real_escape_string($ciphertext);
// Store in MySQL
$mysqli = new mysqli("localhost", "test", "test", "test");
$mysqli->set_charset("utf8");
$mysqli->query("insert into test(content) value ('$ciphertext')");
$mysqli->close();
要搜索的 SQL 查询string was
:
SELECT CAST(AES_DECRYPT(content,'ABCDEF0123456789') AS CHAR) AS content
FROM test
WHERE CAST(AES_DECRYPT(content,'ABCDEF0123456789') AS CHAR) like '%string was%';
输出是:
This string was AES-128 / EBC / ZeroBytePadding encrypted.
注意:MySQL 表由以下人员创建:
create table test (
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
content blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
如果您RIJNDAEL_128
在 PHP 端使用 mcrypt 进行加密,那么我建议您在 PHP 端进行解密。不久前,当涉及到我的一个申请的学生证号码时,我遇到了同样的问题。我选择反对让数据库进行任何类型的加密/解密。我强烈建议将其留给一个系统(在本例中为 mcrypt)。原因是现在您可以减少可能出错的“移动”部件,从而更轻松地进行维护并更轻松地记录审计跟踪。您的数据库应该用于存储数据(不足为奇),因此只需确保数据库中的长度适合您所存储的内容。
希望这能回答你的问题/以某种方式帮助你,因为这就是我会这样做/实际上正在这样做。
现在,如果您需要查看一些有关其工作原理的代码,请询问。根据我的理解,虽然我认为您知道如何进行加密/解密,但您只是在询问数据库是否应该解密信息。
如果您希望您的解决方案可扩展到许多用户,那么在搜索期间解密数据库中的数据似乎是个问题。
我建议您查找旧宝石“绽放过滤器”。它通常用于拼写检查器,但也可用于加速数据库中的搜索。 https://en.wikipedia.org/wiki/Bloom_filter
布隆过滤器是位掩码。您需要创建一系列不同的散列函数,这些函数生成与布隆过滤器大小相同的散列,但每个散列函数只设置一个随机位。
然后,您通过这些散列函数运行一个单词(字符串)并将这些位添加到您的过滤器中。现在过滤器“知道”你的话。
过滤器是紧凑的,因为单词可以在过滤器中相互重叠。
要检查一个单词是否在过滤器中,您只需在其上运行散列函数并检查是否所有位都使用二进制 AND 操作在过滤器中设置。MySQL 支持二进制操作。
您永远不能从过滤器中删除一个单词,因为这些位可以是多个单词的一部分。
文本永远无法从布隆过滤器中恢复。
布隆过滤器永远不会给出假阴性,但它可以给出假阳性。如果您得到误报,那么您的过滤器与您的数据集(存储在过滤器中的单词)相比太小,或者您的散列函数不够好。需要多少个散列函数取决于数据的大小,尝试 5-20。
提示!您还可以向您的布隆过滤器添加成对的单词或三组单词。