php - 使用 PHP 在数据库中进行加密数据搜索
问题描述
我有一个搜索功能,我正在升级以支持 AES 加密,而对于我的生活,我不知道我做错了什么。
我通过搜索框传递相同的查询,就像我在数据库端加密数据之前所做的那样,我没有返回任何 SQL 错误。它每次只显示零结果。
加密前的数据库示例:
*****************************************************
* Firstname * Surname * Telephone * Email *
*****************************************************
* Bob * Smith * 0193847 * bob@me.com *
* Jane * McBean * 0584383 * jane@mail.com *
*****************************************************
带加密的数据库示例:
*****************************************************
* Firstname * Surname * Telephone * Email *
*****************************************************
* 2d1c5749 * 82559acc* fa3bc41c5 * 759d082559 *
* 13c5802a * 070e76f8* 70e76f8fe * feaa0ac1635c *
*****************************************************
以前的工作(非加密)版本:
if(isset($_POST["search"]) && strlen($_POST["search"]) > 3) {
$Search = filter_var($_POST["search"], FILTER_SANITIZE_STRING);
$Search = strip_tags($Search);
$Search_String = filter_var($_POST["search"], FILTER_SANITIZE_STRING);
$Search = "%$Search%";
$Search_String = filter_var($Search_String, FILTER_SANITIZE_STRING);
if(strlen(empty($Search_String))){ $error[] = 'The search string is empty';}
if(!isset($error)) {
$Search_list = $dbconn->prepare("SELECT sql_calc_found_rows
event_candidate.id AS candidate_id,
event_candidate.firstname,
event_candidate.surname,
event_candidate.telephone,
event_candidate.email,
FROM event_candidate
WHERE CONCAT_WS(' ', event_candidate.firstname, event_candidate.surname, event_candidate.telephone, event_candidate.email) LIKE ?
");
$Search_list->execute(array($Search));
不返回任何内容的新代码:
$Search = filter_var($_POST["search"], FILTER_SANITIZE_STRING);
$Search = strip_tags($Search);
$Search_String = filter_var($_POST["search"], FILTER_SANITIZE_STRING);
$Search = "%".$Search."%";
$Search_list = $dbconn->prepare("SELECT sql_calc_found_rows
event_candidate_demo.id AS candidate_id,
event_candidate_demo.firstname,
event_candidate_demo.surname,
event_candidate_demo.telephone,
event_candidate_demo.email,
FROM event_candidate_demo
WHERE CONCAT_WS(' ', AES_DECRYPT(event_candidate_demo.firstname, UNHEX(:key)), AES_DECRYPT(event_candidate_demo.surname, UNHEX(:key)), AES_DECRYPT(event_candidate_demo.telephone, UNHEX(:key)), AES_DECRYPT(event_candidate_demo.email, UNHEX(:key))) LIKE ':search'
");
$Search_list->bindParam(':key', $Site_Key, PDO::PARAM_INT);
$Search_list->bindParam(':search', $Search, PDO::PARAM_STR);
$Search_list->execute();
因此,如果我搜索与 Bob 相关的任何内容,它将加载正确的记录,但是我对加密数据执行相同操作,并且它始终返回零结果。
我不确定是AES_DECRYPT
导致问题还是切换到BindParam
.
解决方案
加密后的数据变得类似于随机噪声。它也永远不会是相同的(如果你有错误的加密)
您的问题有两种解决方案:
- 从数据库中获取每一行,解密,比较。<--需要很多时间
- 存储散列键,并比较散列。<-- 不太安全,让猜测数据更容易
您将不得不根据敏感度、对速度的需要和风险评估选择两种弊端之一。
假设您使用选项 2,您将有两列用于名字
event_candidate.firstname,
event_candidate.firstname_hash,
在firstname
您存储加密名称的字段中。
在firstname_hash
你存储名字的哈希
您可以使用类似的东西hash('sha512', strtolower($unencrypted_name))
来加密哈希。
然后从中选择数据,然后您可以执行
$select = hash('sha512', strtolower($unencrypted_name));
$Search_list->bindParam(':search', $select, PDO::PARAM_STR);
但是,您只能进行完全匹配。整个名字需要匹配,额外的附带空格会阻碍匹配。
使用 hmacs 和其他方法,还有更安全的方法来散列它。我提供的示例只是为了说明基本概念。您将必须对数据进行自己的风险分析和敏感性。
推荐阅读
- django - 可以为 Django SQLite3 默认数据库创建 ArrayField 吗?
- heroku - 未找到 Heroku 自定义域 (404)
- angular - 如果我将访问令牌(JWT)存储在 Angular 项目的本地存储中,那有什么问题?
- javascript - 如何在 React TypeScript 中访问嵌套数据接口
- flutter - 如何在 Flutter 中添加 TextEditingController 并从动态 TextFormField 中获取文本值?
- jpa - 事务性不适用于 JPA saveAll
- c - 由于函数 asprintf 无法编译程序
- javascript - 如何将字符串输入到给定位置的数组中?
- c# - 如何使特定的 DataGridTemplate 列单元格只读
- python-3.x - Python3 - 数据库 sqlite3 - sqlite3.OperationalError:没有这样的列: