FEATURED · 精选文章

我放弃 MD5 了:在 MySQL 里用“噪音池”实现比彩虹表还头疼的加密

发布时间 / 2026/8/10 1:29:39
来源 / 创域科博编辑部
栏目 / 资讯中心
我放弃 MD5 了:在 MySQL 里用“噪音池”实现比彩虹表还头疼的加密 我放弃 MD5 了在 MySQL 里用“噪音池”实现比彩虹表还头疼的加密文章目录我放弃 MD5 了在 MySQL 里用“噪音池”实现比彩虹表还头疼的加密一、事情是怎么开始的二、先吐槽一下传统的加密方案1. MD5 和它的朋友们2. AES 和它的朋友们3. 我想要什么三、我的核心思路三重任意Three-Any四、一个具体的例子看完你就懂了五、那如果多插几个呢六、这样做有什么好处七、那实现起来有多复杂表结构就两张加密一行 SQL查询密码一行 SQL八、普通程序员 vs 我九、它真的安全吗十、那有没有缺点十一、实际使用体验十二、总结十三、源码地址十四、评论区一、事情是怎么开始的事情是这样的。有一天我在 WPS 里写 JS 宏本来只是想给 Excel 加点“防同事偷看”的小功能。结果写着写着脑子里突然蹦出一个念头“如果加密的时候每次结果都不一样那彩虹表是不是直接就废了”于是我放下 WPS打开 MySQL开始了这场“密码存得像个分布式系统”的折腾之旅。二、先吐槽一下传统的加密方案1. MD5 和它的朋友们MD5 这东西大家都知道。好处是快坏处是彩虹表到处都是碰撞虽然概率低但存在最重要的是同一个密码永远是同一个 MD5这就好比你每次照相都穿同一件衣服、站同一个位置、摆同一个姿势。黑客只要见过你一次下次一眼就能认出你。2. AES 和它的朋友们AES 很安全但要管密钥密钥丢了就凉了太重了我只是想存个密码不是要保护核弹发射井加密结果还是确定性的密钥不变结果不变3. 我想要什么我想要一种不需要密钥每次加密结果都不一样解密简单到离谱彩虹表看了想骂人的加密方式。三、我的核心思路三重任意Three-Any我给这套方案起了个名字叫“Three-Any Cipher”。所谓“三重任意”就是重数名称说明第一重任意位置噪音字符插在原文的哪个位置随机第二重任意数量插 1 个还是 5 个随机第三重任意字符插什么字符从原文没出现过的字符里随机挑说白了就是往原文里随机塞几个“垃圾字符”然后把“垃圾字符”的清单单独存起来。解密的时候把垃圾删掉剩下的就是原文。四、一个具体的例子看完你就懂了假设原文是q23wrr4加密的时候系统随机决定插入 1 个噪音字符插入字符K插在第 6 个字符后面结果变成q23wKrr4然后系统把[K]存进噪音列表。解密的时候q23wKrr4 去掉 K q23wrr4完成。五、那如果多插几个呢同一个原文q23wrr4如果系统这次随机插了 4 个噪音q23wrVrud4噪音列表[V, , d, u]解密的时候q23wrVrud4 去掉 V → q23wrrud4 去掉 → q23wrrud4 去掉 d → q23wrru4 去掉 u → q23wrr4完美还原。六、这样做有什么好处特性效果同一密码每次加密结果不同彩虹表“我存哪个”没有固定公式攻击者“我是谁我在哪”解密就是一个 REPLACE代码简单到令人发指密文不含高危字符SQL 注入“我进不去啊”不存在碰撞两个密码不可能产生同一个密文七、那实现起来有多复杂说出来你可能不信。表结构就两张-- 用户表没有密码字段CREATETABLEusers(uidVARCHAR(64)PRIMARYKEY,usernameVARCHAR(50),nicknameVARCHAR(50),created_atDATETIME);-- 密码碎片表就这两列CREATETABLEpwd_ciphertext(uidVARCHAR(64),ciphertextTEXT,noise_chars JSON);加密一行 SQLCALLsp_encrypt_and_store(uuid_001,admin,nick,q23wrr4);查询密码一行 SQLSELECTfn_decrypt_simple(uuid_001)AS密码;八、普通程序员 vs 我场景普通程序员我存密码INSERT INTO users (password) VALUES (123456)CALL sp_encrypt_and_store(...)查密码SELECT password FROM usersSELECT fn_decrypt_simple(uid)描述架构“我们用了 MD5 加盐”“我们实现了跨单元联合编译的分布式碎片化密码存储协议”简历上写“熟悉数据库操作”“设计并实现基于噪音池的 Three-Any 抗彩虹表加密模型”九、它真的安全吗我们来对比一下攻击方式MD5AESThree-Any彩虹表能攻破常见密码不能但需要密钥不能没有固定映射碰撞攻击存在碰撞极难不存在密钥泄露不涉及全完蛋不需要密钥已知明文攻击能推导规律不能不能同事路过偷看能看到密文能看到密文能看到乱码十、那有没有缺点当然有。这世界上没有完美的方案。缺点说明密文比原文长原文 7 个字符密文可能 11 个需要额外存储噪音列表多一个 JSON 字段目前只支持 ASCII 字符中文还没支持下次升级如果噪音列表丢了密文就永远解不开了但这不就是安全感的代价吗十一、实际使用体验我已经在 MySQL 里跑了一段时间效果如下-- 添加用户CALLsp_encrypt_and_store(uuid_007,user7,nick7,q23wrr4);-- 查看结果SELECT*FROMpwd_ciphertextWHEREuiduuid_007;输出uidciphertextnoise_charsuuid_007q23wKrr4[“K”]-- 解密SELECTfn_decrypt_simple(uuid_007);-- 返回q23wrr4每次加密结果都不同但解密始终正确。十二、总结这套方案的核心理念就一句话“加密的时候随便造解密的时候认真删。”它不追求数学上的绝对安全而是通过“随机性 碎片化存储”来让攻击者根本不知道从哪下手。如果你也觉得传统加密太死板、彩虹表太猖狂、AES 太重、MD5 太老那不妨试试这个方案。十三、源码地址[GitHub 链接]你放上你自己的仓库地址就行十四、评论区如果你觉得这个方案有点意思欢迎在评论区留言讨论。如果你觉得这个方案很蠢也欢迎在评论区骂我。毕竟折腾才是程序员的浪漫。Peace. ✌️
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻