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

加密结果看起来像正常汉字——我做了一个加密工具(密语盒子开发笔记)

起因:加密工具用起来太显眼了

我一直有个习惯,把常用账号密码备注在手机便签里。后来有次把手机递给朋友看照片,他顺手划了两下,正好滑到了那个便签页。密码没泄露,但那一刻我意识到一个问题——

传统的加密方式,加密结果要么是Base64乱码,要么是一堆看不懂的符号,它本身就在告诉别人:这里有秘密。

我试过好几个密码备注类App,要么云同步让我不放心,要么加密之后的文本贴到便签里一眼就知道是密文。说实话,这种「看起来被加密」的东西,在某些场景下防护效果很有限——它会引起别人的注意,反而适得其反。


思路:让密文「伪装」成普通文字

真正想要的效果是:加密之后,结果看起来就是一段普通的汉字,外人完全感觉不出来这是密文。

这个思路来自古老的隐写术(steganography)和替换密码(substitution cipher)的结合。我的设计是这样的:

  1. 先用 AES-GCM + PBKDF2 对原文做真正的强加密,得到密文字节流
  2. 再用一套「字谱」,把每个字节映射到一个汉字上
  3. 最终输出的是一串汉字——看起来像某种奇怪但「正常」的文字内容

字谱是可以自己编辑的。你可以设置一套用生僻字的字谱,也可以用某个特定字符集。两个人约定同一套字谱 + 同一个密码,才能互相解读。

解密方向反过来:输入密码 + 密文汉字串,先反查字谱还原字节流,再 AES-GCM 解密,得到原文。


ArkUI 实现:鸿蒙端的核心加密调用

这个App是用 ArkTS + ArkUI 做的鸿蒙原生版本。鸿蒙的 @ohos.security.cryptoFramework 提供了 AES-GCM 的原生支持,PBKDF2 做密钥派生,整个加密流程完全本地运行,没有任何网络请求。

核心加密调用大概长这样:

// 用 PBKDF2 从密码派生 AES 密钥
const spec: cryptoFramework.PBKDF2Spec = {algName: 'PBKDF2',password: password,salt: saltUint8Array,iterations: 100000,keySize: 32
};
const kdf = cryptoFramework.createKdf('PBKDF2|SHA256');
const secretKey = await kdf.generateSecret(spec);// AES-GCM 加密
const cipher = cryptoFramework.createCipher('AES256|GCM|NoPadding');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, secretKey, params);
const encryptedData = await cipher.doFinal(plainTextBlob);

迭代次数设了 100000 次,在手机上大概几百毫秒能完成,对用户来说感知不到延迟,但对暴力破解来说成本就很高了。


字谱设计:这里踩了不少坑

字谱这块其实试了三套方案,最后全删了重做。

最开始的想法是直接用 Unicode 汉字区间做映射,一个字节对应一个汉字,简单粗暴。问题是某些生僻字在不同字体下显示有问题,而且256个汉字如果是随机选的,凑在一起读起来毫无意义。

「毫无意义」这四个字才是真正的问题所在。随机选出的256个字拼出来大概长这样:「腙鼢蛑犟獾鬣貘魃鲯疸螬虻骺橛龋」——没有任何语义,一眼就能判断「这不是正常的人写出来的文字」。「不像人话」本身就是一种暴露。

后来调整成:字谱支持完全自定义,用户自己输入一组汉字作为字符集。这样做有两个好处:

  • 可以选常见字,让密文读起来更接近自然语言
  • 两个人约定字谱,安全性额外依赖字谱本身的保密,双重保险

多套字谱可以保存,每套字谱起个名字,比如「日记模式」「和朋友聊天用」,在不同语境切换。


典型使用场景

场景一:手机备忘录存密码

把账号密码用密语加密后,贴到便签里。别人翻到只会看到一行汉字,完全不会意识到这是密文。自己解密的时候打开App,输入密码,一键还原。

场景二:把东西放在公开地方存着

有时候写了点东西,想放在公开地方存着,但不想让随便什么人都能读懂。用密语加密后发出去,外人看是一段看似普通的文字,自己知道密码才能读回来。

场景三:和朋友约定字谱聊天

说实话这个场景更偏极客趣味,实用性没那么强,但好玩。两个人约定同一套字谱,发的消息截图也看不出内容。


关于「安全性」这件事

我想直接说清楚:密语盒子的安全性来自两层。

第一层是 AES-GCM 本身,这是目前对称加密的标准方案,密钥强度够的情况下暴力破解不现实。

第二层是「视觉混淆」——加密结果不像密文。这一层不增加数学意义上的密码强度,但在现实场景中确实有用:大多数偷窥行为不是专业攻击者,他们看到「普通汉字」就不会往加密方向想。

两层叠加,对日常隐私保护来说够用了。

没有账号、没有云同步、密钥不存储也不上传——这几点我从设计之初就没打算妥协。


目前只做了鸿蒙版,华为应用市场搜「密语盒子」能找到,App ID 是 com.xun.xxsecret,1.2.0版本,还在更新。

http://www.jsqmd.com/news/683848/

相关文章:

  • # 034、AutoSAR OTA软件更新设计与实现:从深夜告警到量产落地
  • CF1810G题解
  • 从原理图到代码:手把手教你用STM32F103C8T6最小系统板驱动矩阵键盘做密码锁
  • 如何彻底告别网盘限速:8大平台直链下载助手完全指南
  • 从设计动机,决策链一步步推出 Shared ptr
  • 2026年上海五大GEO优化服务商深度盘点TOP机构 - GEO优化
  • Mplus链式中介实战:从模型设定到效应检验的完整指南
  • DeepSeek V4 这周发!梁文锋扛不住了
  • 别再让NextCloud后台任务卡住了!Docker版保姆级Cron配置指南(附两种方法对比)
  • Qwen3.5-4B-Claude-Opus应用场景:高校编程课程助教——自动批改思路点评
  • Boss-Key老板键:终极窗口隐身术,5秒保护你的数字隐私空间
  • Alteryx:别让“集成难、数据乱” 吃掉AI回报
  • 从‘光速不变’到‘光速可变’:聊聊光纤色散对5G前传和数据中心互联的实际影响
  • KEIL下载程序无法运行,调试后却正常运行。
  • 无硬件学LVGL—定时器篇:基于Web模拟器+MicroPython速通GUI开发
  • 【App Service】排查App Service中发送Application Insights日志数据问题的神级脚本: Test-AppInsightsTelemetryFlow.ps1
  • 少儿中国舞老师的教学经验重要吗?
  • 从Blender到Vulkan:用tiny_obj_loader在C++中高效解析OBJ模型(附完整代码)
  • 裁剪到市!全球17种土地类型数据集(全球/中国/分省/分市/Tif)
  • 电路板振动如何“看”得见?揭秘DIC技术在模态分析中的实战应用
  • RWKV7-1.5B-world实战手册:huggingface-hub 0.27.1与transformers 4.48.3版本锁死验证
  • L1-019 谁先倒
  • 别再只调包了!手把手带你用Python复现DeepSort核心匹配逻辑(附完整代码)
  • 机器学习规模化实践:从规则引擎到生产部署
  • 告别龟速下载!手把手教你用清华镜像离线安装PyTorch 2.2.0 + CUDA 11.8(3DGS环境必备)
  • Phi-3-mini-4k-instruct-gguf效果惊艳:在HumanEval Python代码生成任务中通过率超72%
  • UIAbility生命周期全解析
  • 2026年Flutter热更新主流方案盘点与选型指南
  • 别再混淆了!一文讲透POCV文件、LVF库与AOCV在项目中的真实使用场景
  • 紫光同创PGL50H开发板PCIE通信实战:从IP核安装到设备识别的保姆级避坑指南