MySQL存储身份证号码需采用 对称加密+哈希辅助索引 方案,兼顾安全与查询性能,具体实现分存储和查询两部分: 一、加密存储核心方案1. 双向加密存储原始数据使用MySQL内置的AES-256加密(需密钥),将身份证号转为密文存储:• 建表时定义`VARBINARY`类型字段(如`id_card_enc`),长度适配AES-256加密后的数据(身份证18位需至少256字节);• 加密函数:`AES_ENCRYPT(身份证号, 密钥, 随机IV)`(推荐随机IV,避免密文重复);• 示例:`INSERT INTO user (id_card_enc) VALUES (AES_ENCRYPT('110101199003071234', 'my_secure_key', UNHEX(SHA2('random_iv', 256))));` 2. 哈希辅助索引实现精准查询对身份证号做加盐哈希(如HMAC-SHA256),生成固定长度哈希值存入索引字段(如`id_card_hash`):• 哈希函数:`HMAC(身份证号, 盐值, 'SHA256')`;• 建表时添加`BINARY(32)`类型字段并创建索引(`INDEX idx_id_card_hash (id_card_hash)`);• 示例:`INSERT INTO user (id_card_hash) VALUES (HMAC('110101199003071234', 'salt_123', 'SHA256'));` 二、查询实现方法1. 精准查询(推荐)对查询条件先做相同哈希运算,直接匹配哈希索引字段(无需解密,性能高):• 示例:`SELECT * FROM user WHERE id_card_hash = HMAC('查询的身份证号', 'salt_123', 'SHA256');` 2. 需解密的查询(如显示原始号)使用`AES_DECRYPT`解密密文(需密钥),但不建议在SQL中硬编码密钥:• 示例:`SELECT CAST(AES_DECRYPT(id_card_enc, 'my_secure_key') AS CHAR) AS id_card FROM user WHERE id = 1;` 3. 模糊查询(性能较低,需谨慎)若需模糊匹配(如查某地区身份证),需先解密再过滤:• 示例:`SELECT * FROM user WHERE CAST(AES_DECRYPT(id_card_enc, 'my_secure_key') AS CHAR) LIKE '1101%';` 三、安全注意事项1. 密钥管理:密钥需在应用层配置(如环境变量),避免SQL硬编码;2. 算法选择:禁用MD5/SHA1(易破解),优先AES-256+HMAC-SHA256;3. 传输安全:数据库连接需启用SSL/TLS,防止密文传输泄露;4. 权限控制:仅授权必要用户访问加密字段,避免未授权解密。