LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

你是怎么实现数据库加密数据的模糊查询的

admin
2025年6月13日 20:18 本文热度 29

做过金融项目或者政府项目的大佬肯定都实现过加密数据的模糊查询功能,大家都是怎么实现的呢?今天就来简单举例一些实现加密数据模糊查询的方案。
方案
查询效率
开发成本
安全性
适用场景
应用层内存过滤
❌ 极差
✅ 低
✅ 高
极小数据量
数据库函数解密
⭐️⭐️
⭐️⭐️
❌ 低
内部低安全需求
分词+密文索引
⭐️⭐️⭐️⭐️
⭐️⭐️⭐️
✅ 高
大多数业务场景
同态加密
❌ 差
⭐️⭐️⭐️⭐️
✅ 高
学术研究/高安全
可信执行环境(TEE)
⭐️⭐️⭐️
⭐️⭐️⭐️⭐️
✅ 高
金融级安全

方案1:应用层内存过滤

原理

  1. 全表查询加密数据

  2. 在内存中解密后过滤

// 伪代码示例:危险!仅用于演示问题public List<UserunsafeSearch(String keyword) {    List<User> allUsers = userRepository.findAll(); // 查出全部数据    return allUsers.stream()            .filter(user -> decrypt(user.getName()).contains(keyword))            .collect(Collectors.toList());}

致命缺陷

  • 数据量大时内存溢出(OOM)

  • 全表扫描性能灾难


方案2:数据库函数解密

MySQL示例

-- 使用AES_DECRYPT函数(需数据库存储密钥)SELECT * FROM users WHERE AES_DECRYPT(name_encrypted, 'secret_key'LIKE '%张%';

优缺点

  • ✅ 不改动业务代码

  • ❌ 密钥暴露在数据库

  • ❌ 无法使用索引(全表扫描)

Java安全写法

@Query(nativeQuery = true,       value = "SELECT * FROM users WHERE " +               "CONVERT(AES_DECRYPT(name_encrypted, ?1) USING utf8) LIKE ?2")List<UsersearchByName(String key, String keyword);


方案3:分词+密文索引(推荐)

1. 核心思路

  • 存储阶段
    将原始数据(如"张三丰")拆分为分词("张"、"三"、"丰"、"张三"、"三丰"),每个分词加密后单独存储。

  • 查询阶段
    用户输入"张"时,先加密"张"得到密文,再用密文去分词索引表查询。

2. 代码实现

(1). 增强版分词策略

// 引入中文分词器(需添加依赖)<dependency>    <groupId>com.janeluo</groupId>    <artifactId>ikanalyzer</artifactId>    <version>2012_u6</version></dependency>
public class EnhancedTokenizer {    public static List<StringsmartTokenize(String text) {        List<String> tokens = new ArrayList<>();        try (StringReader reader = new StringReader(text)) {            IKSegmenter seg = new IKSegmenter(reader, true);            Lexeme lex;            while ((lex = seg.next()) != null) {                tokens.add(lex.getLexemeText());                // 增加组合分词(如"张三丰"生成"张"、"三"、"丰"、"张三"、"三丰")                if (lex.getLength() > 1) {                    for (int i = 2; i <= lex.getLength(); i++) {                        tokens.add(text.substring(lex.getBeginPosition(),                                 lex.getBeginPosition() + i));                    }                }            }        }        return tokens.stream().distinct().collect(Collectors.toList());    }}

2. 双重加密索引表

// 索引表结构建议@Entity@Table(name = "user_search_index")public class SearchIndex {    @Id    @GeneratedValue    private Long id;
    @Column(name = "user_id")    private Long userId;
    @Column(name = "token_hash")  // 用于快速匹配    private String tokenHash;
    @Column(name = "token_cipher") // 用于精确验证    private String tokenCipher;
    // 使用不同密钥加密    public static SearchIndex create(Long userId, String token) throws Exception {        SearchIndex index = new SearchIndex();        index.setUserId(userId);        index.setTokenHash(AESUtil.encryptWithKey(token, "HASH_KEY"));        index.setTokenCipher(AESUtil.encryptWithKey(token, "CIPHER_KEY"));        return index;    }}

3. 智能查询流程

public List<UsersecureFuzzySearch(String keyword) throws Exception {    // 1. 生成候选分词    List<String> tokens = EnhancedTokenizer.smartTokenize(keyword);
    // 2. 并行加密提高性能    List<String> hashList = tokens.parallelStream()            .map(t -> {                try {                    return AESUtil.encryptWithKey(t, "HASH_KEY");                } catch (Exception e) {                    throw new RuntimeException(e);                }            })            .collect(Collectors.toList());
    // 3. 分页查询避免内存压力    Pageable page = PageRequest.of(0100);    List<Long> userIds = indexRepository            .findUserIdsByTokenHashes(hashList, page);
    // 4. 二次验证(防止哈希碰撞)    return userRepository.findAllById(userIds).stream()            .filter(user -> {                try {                    String decrypted = AESUtil.decrypt(user.getNameCipher());                    return decrypted.contains(keyword);                } catch (Exception e) {                    return false;                }            })            .collect(Collectors.toList());}


方案4:同态加密(学术级方案)

基于SEAL库的实现

// 添加依赖(微软SEAL库Java版)<dependency>    <groupId>com.microsoft.seal</groupId>    <artifactId>seal-jni</artifactId>    <version>3.7.2</version></dependency>
public class HomomorphicSearch {    public static void demo() throws Exception {        // 1. 初始化加密上下文        EncryptionParameters params = new EncryptionParameters(SchemeType.bfv);        params.setPolyModulusDegree(4096);        params.setCoeffModulus(CoeffModulus.BFVDefault(4096));        params.setPlainModulus(PlainModulus.Batching(409620));
        SEALContext context = new SEALContext(params);
        // 2. 生成密钥        KeyGenerator keyGen = new KeyGenerator(context);        PublicKey publicKey = keyGen.createPublicKey();        SecretKey secretKey = keyGen.secretKey();
        // 3. 加密数据        Encryptor encryptor = new Encryptor(context, publicKey);        Plaintext plain = new Plaintext("123"); // 要加密的数字        Ciphertext encrypted = new Ciphertext();        encryptor.encrypt(plain, encrypted);
        // 4. 在密文上计算(此处演示加法)        Evaluator evaluator = new Evaluator(context);        Ciphertext result = new Ciphertext();        evaluator.add(encrypted, encrypted, result); // 密文+密文
        // 5. 解密验证        Decryptor decryptor = new Decryptor(context, secretKey);        Plaintext decrypted = new Plaintext();        decryptor.decrypt(result, decrypted);        System.out.println(decrypted); // 应输出246    }}

现实限制

  • 仅支持有限运算(加减/乘)

  • 性能差(单次操作需100ms+)

  • 不支持字符串操作


方案5:可信执行环境(TEE)

基于Intel SGX的解决方案

// SGX加密区(enclave)内代码示例void ecall_fuzzy_search(const char* encrypted_query, size_t len) {    // 1. 解密查询条件    std::string query = decrypt_in_enclave(encrypted_query, len);
    // 2. 直接查询数据库(enclave内可见明文)    sqlite3* db;    sqlite3_open(":memory:", &db);    std::string sql = "SELECT * FROM users WHERE name LIKE '%" + query + "%'";
    // 3. 加密结果返回    encrypt_results(db_exec(sql));}

优势

  • 硬件级安全

  • 性能接近明文查询
    挑战

  • 需要特定硬件支持

  • 开发复杂度高


阅读原文:原文链接


该文章在 2025/6/14 16:36:35 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved