当前位置: 首页 > news >正文

应用密码零改造方案一

对 userInfo 表的 phone 字段实现加密和解密的完整 MySQL 方案,加密后的数据以字符串形式存储:

一.测试截图

密文显示:

在这里插入图片描述

解密显示:

在这里插入图片描述

二.实现步骤

1. 确保字段长度足够

由于加密后的字符串可能比原数据更长,需调整 phone 字段长度(例如 varchar(255) 足够存储 AES 加密后的 Base64 字符串):

-- 保持原表结构不变(phone 字段为 varchar(255))
CREATE TABLE `userInfo` (
  `card` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

2. 定义加密密钥

在 MySQL 会话中设置用户变量(示例密钥为 my_secret_key_123,实际生产环境应使用安全密钥):

SET @encryption_key = 'my_secret_key_123'; -- 密钥长度需符合 AES 要求(如 16/24/32 字节)

3. 创建触发器实现自动加密

3.1 INSERT 触发器

插入数据时自动加密 phone 字段并转换为 Base64 字符串:

DELIMITER $$

CREATE TRIGGER before_userInfo_insert
BEFORE INSERT ON userInfo
FOR EACH ROW
BEGIN
    -- 加密并转换为 Base64 字符串
    SET NEW.phone = TO_BASE64(AES_ENCRYPT(NEW.phone, @encryption_key));
END$$

DELIMITER ;
3.2 UPDATE 触发器

更新数据时自动加密 phone 字段:

DELIMITER $$

CREATE TRIGGER before_userInfo_update
BEFORE UPDATE ON userInfo
FOR EACH ROW
BEGIN
    SET NEW.phone = TO_BASE64(AES_ENCRYPT(NEW.phone, @encryption_key));
END$$

DELIMITER ;

4. 查询时自动解密

使用 AES_DECRYPTFROM_BASE64 函数解密数据:

SELECT 
    card, 
    CAST(AES_DECRYPT(FROM_BASE64(phone), @encryption_key) AS CHAR) AS decrypted_phone 
FROM userInfo;

5. 验证测试

插入加密数据
INSERT INTO userInfo (card, phone) 
VALUES ('card_001', '13800138000'); 
查询数据(明文显示)
SELECT 
    card, 
    CAST(AES_DECRYPT(FROM_BASE64(phone), @encryption_key) AS CHAR) AS phone 
FROM userInfo;

输出

+----------+-------------+
| card     | phone       |
+----------+-------------+
| card_001 | 13800138000 |
+----------+-------------+

6. 完整操作流程示例

步骤 1:插入数据(自动加密)
-- 插入数据(明文)
INSERT INTO userInfo (card, phone) VALUES ('card_002', '13900139000');

-- 直接查询表数据(查看密文)
SELECT * FROM userInfo;

输出(加密后的 Base64 字符串):

+----------+----------------------------------+
| card     | phone                            |
+----------+----------------------------------+
| card_002 | k4lWZ3sD4Tz7X1X8hJjKbQ==        | -- 示例值,实际值更长
+----------+----------------------------------+
步骤 2:解密查询
SELECT 
    card, 
    CAST(AES_DECRYPT(FROM_BASE64(phone), @encryption_key) AS CHAR) AS phone 
FROM userInfo;

输出

+----------+-------------+
| card     | phone       |
+----------+-------------+
| card_002 | 13900139000 |
+----------+-------------+

注意事项

  1. 密钥管理

    • 示例中硬编码密钥不安全,生产环境应通过外部配置或密钥管理服务动态注入密钥。
    • 密钥需符合 AES 算法要求(如 16/24/32 字节长度)。
  2. 字段长度

    • Base64 编码会增加约 33% 的长度,需确保 phone 字段足够长(如原数据 11 位,加密后至少需 varchar(24))。
  3. 性能影响

    • 高频写入场景中,触发器可能增加数据库负载。
  4. 编码一致性

    • 必须统一使用 TO_BASE64FROM_BASE64 确保编码/解码一致。

扩展方案:存储过程管理加密

DELIMITER $$

-- 加密存储过程
CREATE PROCEDURE InsertEncryptedUser(
    IN p_card VARCHAR(255),
    IN p_phone VARCHAR(255)
)
BEGIN
    INSERT INTO userInfo (card, phone)
    VALUES (p_card, TO_BASE64(AES_ENCRYPT(p_phone, @encryption_key)));
END$$

-- 解密存储过程
CREATE PROCEDURE GetDecryptedUsers()
BEGIN
    SELECT 
        card, 
        CAST(AES_DECRYPT(FROM_BASE64(phone), @encryption_key) AS CHAR) AS phone 
    FROM userInfo;
END$$

DELIMITER ;

-- 调用示例
CALL InsertEncryptedUser('card_003', '15900159000');
CALL GetDecryptedUsers();

总结

操作方法
自动加密通过 BEFORE INSERT/UPDATE 触发器调用 AES_ENCRYPT + TO_BASE64
手动解密查询时使用 FROM_BASE64 + AES_DECRYPT 并转换为 CHAR
安全增强避免硬编码密钥,结合应用层或外部服务管理密钥

按此方案实现后,phone 字段在存储时自动加密为字符串,查询时手动解密,满足字符串存储需求。

以下是触发器相关命令:

#删除触发器

DROP TRIGGER IF EXISTS before_insert_userInfo;

#查看所有触发器

SHOW TRIGGERS LIKE 'userInfo';

希望这篇文章对你有所帮助!如果觉得不错,别忘了点赞收藏哦!

http://www.dtcms.com/a/106956.html

相关文章:

  • DLML正则化
  • 【前端知识】Vue当中目录别名@的使用
  • leetcode515 在每个树行中找最大值
  • mac air m系列arm架构芯片安装虚拟机 UTM+debian 浏览器firefox和chrome
  • Bugku-贝斯手
  • 【Linux篇】自主Shell命令行解释器
  • Spring 核心技术解析【纯干货版】- XVIII:Spring 网络模块 Spring-WebSocket 模块精讲
  • ray.rllib-入门实践-12-2:在自定义policy中注册使用自定义model(给自定义model新增参数)
  • js中判断对象是否包含某个属性(元素)
  • C++ 编程指南33 - 使用模板来表达适用于多种参数类型的算法
  • 【力扣hot100题】(041)将有序数组转换为二叉搜索树
  • Mysql连接池报错
  • 春晚魔术[蓝桥]
  • 查看 Linux 版本 Debian 飞牛os
  • Opencv计算机视觉编程攻略-第七节 提取直线、轮廓和区域
  • HCIA/HCIP基础知识笔记汇总
  • USC安防平台视频存储 RK3588
  • 问题大集10-git使用commit提交中文显示乱码
  • 深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本
  • 【数据结构】图论进阶:生成树、生成森林与权值网络的终极解析
  • PyTorch中如何向已有预训练模型新增层
  • Go 语言语法精讲:从 Java 开发者的视角全面掌握
  • 架构设计基础系列:CQRS架构模式
  • 中级:Git面试题全攻略
  • AI提示词:知识探索专家
  • PyQt学习记录
  • python 项目怎么通过docker打包
  • 前端面试题之CSS中的box属性
  • 【Python使用】嘿马云课堂web完整实战项目第1篇:项目概述,项目背景【附代码文档】
  • EasyExcel在Linux上运行正常,在Docker中导出FontConfiguration.getVersion错误(不额外安装fontconfig)