起因:一个写 App 的人,自己密码在裸奔
我平时做鸿蒙应用开发,理论上对安全这块应该有点感觉。但有一天手机借给朋友,看见他随手翻了一下备忘录——那一刻挺难受的,里面存着几个明文密码,完全没有任何保护。
然后我去找加密工具。试了几个,加密出来要么是一串 Base64 乱码,要么是看不懂的符号。问题是:乱码本身就是一种信号。别人一眼扫到那串东西,第一反应就是「哦,这里有个被加密的东西」,好奇心反而更重了。
我想要的是:加密完之后,看起来什么都没发生。
所以我自己做了一个,叫密语盒子,先上了鸿蒙版。
核心思路:两层设计
第一层是真正的加密。
底层用 AES-GCM + PBKDF2,密钥派生迭代次数设得比较高,暴力破解成本很大。鸿蒙这边调用的是系统原生 @ohos.security.cryptoFramework API,不是自己造轮子,相对放心。整个流程完全离线,密钥不上传任何服务器。
第二层是视觉伪装。
加密出来的字节,不直接给你看乱码,而是用一套「字谱」映射成汉字。字谱本质上是一张对照表——你自己定义用哪些汉字表示哪些字节值。比如把「天地人和风云月星……」组成一套字谱,加密结果就是由这些字排列成的文字,看起来像诗、像随笔,就是不像密文。
用密码「bilibili」对「今晚8点老地方见」加密,输出大概是这样:
风地云天月人星和地风云月天人星地风云天地月星人和云风
外人扫一眼,最多觉得「这人在写什么奇怪的东西」,不会联想到「这是加密信息」。这和主流加密工具的思路刚好相反——不是「把内容藏起来」,而是「让内容看起来不像在藏东西」。
鸿蒙开发过程里踩的坑
选择先做鸿蒙版,这个决定我想了挺久。鸿蒙生态还在建设阶段,很多东西搜文档,要么找不到,要么找到了是旧版本写法,要么找到发现根本不能用。ArkTS 写起来有点 TypeScript 的感觉,上手不算难,但周边工具链有时候让人头疼。
加密那块系统 API 够用,问题不大。字谱管理是我自己设计的数据结构,支持保存多套字谱,不同场景隔离使用。
有个坑当时没想到:字谱里的字符集必须保证没有重复,不然解码会产生歧义。 听起来简单,但用户编辑字谱时随手输入重复字符是很自然的事情,App 得在合适时机给出提示。最后我选了实时校验,重复字符直接高亮,保存时也做二次拦截。逻辑写起来比预想的碎,边界情况一个个列出来处理了七八种。
下面是字谱校验的核心逻辑片段,ArkTS 写的:
checkDuplicateChars(chars: string): number[] {const seen = new Map<string, number>();const duplicateIndexes: number[] = [];for (let i = 0; i < chars.length; i++) {const ch = chars[i];if (seen.has(ch)) {duplicateIndexes.push(i);const firstIdx = seen.get(ch)!;if (!duplicateIndexes.includes(firstIdx)) {duplicateIndexes.push(firstIdx);}} else {seen.set(ch, i);}}return duplicateIndexes;
}
实时检测的思路就这样,拿到重复下标之后在 UI 层做高亮,体验比保存时报错要顺很多。
编解码的完整流程如下:
- 加密:明文 → AES-GCM 加密 → 字节流 → 字谱映射 → 汉字密文
- 解密:汉字密文 → 字谱逆映射 → 字节流 → AES-GCM 解密 → 明文
两步独立可测,调试还好,最麻烦的就是各种用户乱输的边界场景。
我自己真的在用的几个场景
备忘录存密码:重要密码全部用密语加密后,以「正常备注」的形式存在备忘录里。即使手机被人翻到,看到的也只是一段汉字。
共享文档里夹私人备注:多人协作文档里想留一条只有自己能看的记录,加密后贴进去,其他协作者看到的就是一段汉字,不会起疑心。比发朋友圈安全得多——发圈还可能有人追问「你在写啥」,反而更显眼。
和朋友约定专属字谱:两个人用同一套字谱 + 同一个密码,截图发圈也不怕,有点像古代「暗语传书」的感觉,极客味挺重。
客观说:差在哪、好在哪
不藏着说缺点:下载量现在还很少,没有经过大规模验证;字谱编辑对新手有一定门槛,需要花时间理解;鸿蒙平台用户基数比 iOS/Android 小,受众有限。
好的地方主要两点:视觉伪装这件事,我在同类工具里真的没看到有人做,防御的场景和常规加密工具完全不同;完全离线加上字谱开放编辑,灵活性足够高,自己定义字谱加上自己的密码,双重混淆,外人想破解需要同时搞清楚字谱规则和加密密钥。
目前鸿蒙版已经上架,版本 1.2.0,鸿蒙应用市场搜「密语盒子」可以找到。
有想聊字谱校验逻辑细节的,或者鸿蒙 cryptoFramework API 踩了哪些具体的坑,评论里说一声,下一篇单独写。
