You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中使用LIKE操作符查询MySQL加密数据?

解决MySQL加密数据无法使用LIKE模糊查询的问题

首先明确核心原因:你当前使用的AES-128-CBC属于分组对称加密算法,加密后的密文是与明文完全无关的随机字节序列(即使明文只有一个字符不同,密文也会完全不同),因此MySQL的LIKE操作符无法通过匹配密文的字符片段对应明文的模糊匹配需求,只能通过精确匹配密文查询对应明文。

先纠正你当前代码的安全问题

你代码中使用**固定IV(初始化向量)**是严重安全漏洞:相同明文+相同IV会生成完全相同的密文,攻击者可通过统计密文频率破解明文。正确做法是每次加密生成随机IV,代码修改如下:

修正后的加密代码

$key = 'MY KEY';
// 生成符合AES-128要求的16字节随机IV
$iv = openssl_random_pseudo_bytes(16);
$plaintext = 'Text for encryption';
// 执行加密
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
// 将IV和密文拼接后base64编码存储(IV需和密文一起保存,解密时要用)
return base64_encode($iv . $ciphertext);

修正后的解密代码

$encryptedData = base64_decode($storedValue);
// 从加密数据中提取前16字节的IV
$iv = substr($encryptedData, 0, 16);
// 提取剩余部分作为密文
$ciphertext = substr($encryptedData, 16);
$plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $iv);
return $plaintext;

针对模糊查询的解决方案

以下是几种可行方案,根据业务场景选择:

方案1:应用层全量解密过滤(适合小数据量场景)

将MySQL中所有加密数据拉取到应用层,解密后用代码实现模糊匹配。优点是无需修改数据库结构,缺点是数据量大时性能极低(全表扫描+批量解密)。

示例代码(PHP):

// 从数据库查询所有加密记录
$stmt = $pdo->query("SELECT id, encrypted_data FROM your_table");
$matches = [];
$keyword = '要匹配的关键词';

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 解密数据
    $encryptedData = base64_decode($row['encrypted_data']);
    $iv = substr($encryptedData, 0, 16);
    $ciphertext = substr($encryptedData, 16);
    $plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
    
    // 模糊匹配
    if (str_contains($plaintext, $keyword)) {
        $matches[] = $row;
    }
}

// 输出匹配结果
print_r($matches);

方案2:生成可模糊匹配的加密索引字段(适合中等数据量场景)

如果无法接受全量拉取,可生成明文的部分特征加密字段,比如:

  • 对明文的每个n-gram(比如2个字符的组合)生成哈希值,存储到数据库中
  • 查询时,将关键词生成对应的n-gram哈希,在数据库中用IN操作符匹配这些哈希值,缩小候选范围后再解密验证

注意:这种方法会泄露部分明文特征(比如字符组合频率),需要权衡安全性和查询需求。

方案3:使用可搜索加密算法(适合大数据量+高安全需求场景)

可搜索加密(Searchable Encryption)是专为加密数据查询设计的算法,分为对称可搜索加密(SSE)和非对称可搜索加密(ASSE)。你可以实现基于对称密钥的SSE方案:

  • 生成一个密钥用于生成搜索关键词的“陷门”(Trapdoor)
  • 加密明文时,同时生成每个关键词对应的陷门索引
  • 查询时,生成关键词的陷门,在数据库中匹配陷门索引,直接获取对应的加密记录

这种方法可在不解密整个数据集的情况下实现模糊或精确查询,但实现复杂度较高,需要对加密算法有一定了解。

方案4:放弃加密字段的模糊查询(最安全且简单的方案)

如果模糊查询不是核心需求,建议仅保留精确匹配功能,避免为了模糊查询引入安全风险或性能损耗。

内容的提问来源于stack exchange,提问作者Nilesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:08:27