doushu7588 2018-05-02 10:49
浏览 69
已采纳

使用PHP在数据库中进行加密数据搜索

I have a search function that I am upgrading to support AES Encryption and for the life of me I don't know what I'm doing wrong.

I am passing the same queries through a search box as I did before I encrypted the data on the database side and I'm not returning any SQL errors. It just shows zero results every time.

Example of the database before encryption:

*****************************************************
* Firstname * Surname * Telephone * Email           *
*****************************************************
* Bob       * Smith   * 0193847   * bob@me.com      *
* Jane      * McBean  * 0584383   * jane@mail.com   *
*****************************************************

Example of the database with encryption:

*****************************************************
* Firstname * Surname * Telephone * Email           *
*****************************************************
* 2d1c5749  * 82559acc* fa3bc41c5 * 759d082559      *
* 13c5802a  * 070e76f8* 70e76f8fe * feaa0ac1635c    *
*****************************************************

The previous working (non encrypted) version:

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));

New code that doesnt return anything:

    $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();

So if i searched for anything realted to Bob it would load the correct record, however I do the same with the encrypted data and it always returns zero results.

I'm not sure if it's the AES_DECRYPT causing the issue or the switch to BindParam.

  • 写回答

2条回答 默认 最新

  • dpjuppr1361 2018-05-02 12:08
    关注

    Data when encrypted becomes to resemble random noise. It will also never be the same(if it does you have bad encryption)

    There are two solutions for your problem:

    1. Fetch each row from the database, decrypt, compare. <-- Takes a lot of time
    2. Store hashed keys, and compare hashes. <-- Way less secure, makes guessing data easier

    You will have to chose one of the two evils depending on the sensitivity, need for speed and risk assesment.

    Say you go with option 2 you would have two columns for the first name

    event_candidate.firstname,
    event_candidate.firstname_hash,
    

    in the firstname field you store the encrypted name.
    in the firstname_hash you store the hash of the firstname

    You can use something like hash('sha512', strtolower($unencrypted_name)) to encrypt the hash.

    Then to select data from it you can then do

    $select = hash('sha512', strtolower($unencrypted_name));
    
    $Search_list->bindParam(':search', $select, PDO::PARAM_STR);
    

    However, you can then only do exact matches. The entire firstname needs to match, an extra incidental space can obstruct a match.

    There are even more secure ways to hash it, using hmacs and other methods. The sample I provided is just to illustrate the base concept. You will have to perform your own risk analysis and sensitivity of the data.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘