PGP与Fluu的密码管理

Fluu喜欢解谜.Fluu在初中为了能够和隔壁班的王浩(化名,他的真名和Fluu有两个字完全一样)用加密信息传输报文,研究了一系列的密码.(后来被认定为传统密码,几乎不具有安全性)

比如模拟钟表的时针分针建立密码表,使用音标符号代替单词进行加密(王浩想出来的,Fluu英语不好不会解密,只记得大家把 is 加密成 ehs),使用化学元素的元素名对应相对原子质量进行加密(Fluu想出来的,到现在还在用,不过更多用在娱乐场景中,比如发了篇檄文不想让正主直接看到)

元素加密法

元素加密法, $\color{red}—-红色是不存在的元素$

速译表
$\color{yellow}A$ $Cm~248$ 锔 $Ga~70$ 镓 $Lu~175$ 镥
$\color{red}A~5$ $Cn~285$ 鿔 $Gd~157$ 钆 $Lv~293$ 𫟷
$Ac~227$ 锕 $Co~60$ 钴 $Ge~73$ 锗 $\color{yellow}M$
$Ag~108$ 银 $Cr~52$ 铬 $\color{yellow}H$ $\color{red}M~67$
$Al~27$ 铝 $Cs~133$ 铯 $H~1$ 氢 $Mc~288$ 镆
$Am~243$ 镅 $Cu~64$ 铜 $He~4$ 氦 $Md~258$ 钔
$Ar~41$ 氩 $\color{yellow}D$ $Hf~179$ 铪 $Mg~24$ 镁
$As~75$ 砷 $D~2$ 氘 $Hg~201$ 汞 $Mn~55$ 锰
$At~210$ 砹 $Db~268$ 𬭊 $Ho~165$ 钬 $Mo~96$ 钼
$Au~197$ 金 $Ds~281$ 𫟼 $Hs~277$ 𬭶 $Mt~276$ 鿏
$\color{yellow}B$ $Dy~163$ 镝 $\color{yellow}I$ $\color{yellow}N$
$B~11$ 硼 $\color{yellow}E$ $I~127$ 碘 $N~14$ 氮
$Ba~137$ 钡 $\color{red}E~8$ $In~115$ 铟 $Na~23$ 钠
$Be~9$ 铍 $Er~167$ 铒 $Ir~192$ 铱 $Nb~93$ 铌
$Bh~270$ 𬭛 $Es~252$ 锿 $\color{yellow}J$ $Nd~144$ 钕
$Bi~211$ 铋 $Eu~152$ 铕 $\color{red}J~15$ $Ne~20$ 氖
$Bk~247$ 锫 $\color{yellow}F$ $\color{yellow}K$ $Nh~284$ 鿭
$Br~80$ 溴 $F~19$ 氟 $K~39$ 钾 $Ni~59$ 镍
$\color{yellow}C$ $Fe~56$ 铁 $Kr~84$ 氪 $No~259$ 锘
$C~12$ 碳 $Fl~289$ 𫓧 $\color{yellow}L$ $Np~237$ 镎
$Ca~40$ 钙 $Fm~257$ 镄 $\color{red}L~180$ $\color{yellow}O$
$Cd~112$ 镉 $Fr~223$ 钫 $La~139$ 镧 $O~16$ 氧
$Ce~140$ 铈 $\color{yellow}G$ $Li~7$ 锂 $Og~295$ 鿫
$Cf~251$ 锎 $\color{red}G~90$ $Lr~262$ 铹 $Os~190$ 锇
$Cl~36$ 氯 --- --- ---
--- --- --- ---
表格 背面
--- --- --- ---
$\color{yellow}P$ $Rb~85$ 铷 $Sn~119$ 锡 $\color{yellow}V$
$P~31$ 磷 $Re~186$ 铼 $Sr~88$ 锶 $V~51$ 钒
$Pa~231$ 镤 $Rf~265$ 𬬻 $\color{yellow}T$ $\color{yellow}W$
$Pb~207$ 铅 $Rg~280$ 𬬭 $T~3$ 氚 $W~184$ 钨
$Pd~106$ 钯 $Rh~103$ 铑 $Ta~181$ 钽 $\color{yellow}X$
$Pm~145$ 钷 $Rn~222$ 氡 $Tb~159$ 铽 $\color{red}X~107$
$Po~209$ 钋 $Ru~101$ 钌 $Tc~98$ 锝 $Xe~131$ 氙
$Pr~141$ 镨 $\color{yellow}S$ $Te~128$ 碲 $\color{yellow}Y$
$Pt~195$ 铂 $S~32$ 硫 $Th~232$ 钍 $Y~89$ 钇
$Pu~244$ 钚 $Sb~122$ 锑 $Ti~48$ 钛 $Yb~173$ 镱
$\color{yellow}Q$ $Sc~45$ 钪 $Tl~204$ 铊 $\color{yellow}Z$
$\color{red}Q~29$ $Se~79$ 硒 $Tm~169$ 铥 $\color{red}Z~86$
$\color{yellow}R$ $Sg~271$ 𬭳 $Ts~294$ 鿬 $Zn~65$ 锌
$\color{red}R~37$ $Si~28$ 硅 $\color{yellow}U$ $Zr~91$ 锆
$Ra~226$ 镭 $Sm~150$ 钐 $U~238$ 铀 ---
速查表
$1~H$ $2~D$ $3~T$ $4~He$
$\color{red}5~A$ $7~Li$ $\color{red}8~E$ $9~Be$
$11~B$ $12~C$ $14~N$ $\color{red}15~J$
$16~O$ $19~F$ $20~Ne$ $23~Na$
$24~Mg$ $27~Al$ $28~Si$ $\color{red}29~Q$
$31~P$ $32~S$ $36~Cl$ $\color{red}37~R$
$39~K$ $40~Ca$ $41~Ar$ $45~Sc$
$48~Ti$ $51~V$ $52~Cr$ $55~Mn$
$56~Fe$ $59~Ni$ $60~Co$ $64~Cu$
$65~Zn$ $\color{red}67~M$ $70~Ga$ $73~Ge$
$75~As$ $79~Se$ $80~Br$ $84~Kr$
$85~Rb$ $\color{red}86~Z$ $88~Sr$ $89~Y$
$\color{red}90~G$ $91~Zr$ $93~Nb$ $96~Mo$
$98~Tc$ $101~Ru$ $103~Rh$ $106~Pd$
$\color{red}107~X$ $108~Ag$ $112~Cd$ $115~In$
$119~Sn$ $122~Sb$ $127~I$ $128~Te$
$131~Xe$ $133~Cs$ $137~Ba$ $139~La$
$140~Ce$ $141~Pr$ $144~Nd$ $145~Pm$
$150~Sm$ $152~Eu$ $157~Gd$ $159~Tb$
$163~Dy$ $165~Ho$ $167~Er$ $169~Tm$
$173~Yb$ $175~Lu$ $179~Hf$ $\color{red}180~L$
$181~Ta$ $184~W$ $186~Re$ $190~Os$
$192~Ir$ $195~Pt$ $197~Au$ $201~Hg$
$204~Tl$ $207~Pb$ $209~Po$ $210~At$
$211~Bi$ $222~Rn$ $223~Fr$ $226~Ra$
$227~Ac$ $231~Pa$ $232~Th$ $237~Np$
$238~U$ $243~Am$ $244~Pu$ $247~Bk$
$248~Cm$ $251~Cf$ $252~Es$ $257~Fm$
$258~Md$ $259~No$ $262~Lr$ $265~Rf$
$268~Db$ $270~Bh$ $271~Sg$ $276~Mt$
$277~Hs$ $280~Rg$ $281~Ds$ $284~Nh$
$285~Cn$ $288~Mc$ $289~Fl$ $293~Lv$
$294~Ts$ $295~Og$

Fluu在当时面临一个难题:密码存储.

当时的Fluu是没有自己电脑的,用手机存储密码来回粘贴1不安全2很麻烦,纸记又很容易丢,自己全记住又很容易忘.

最后Fluu创造了”公私钥法”来管理Fluu的所有密码(注意:这不是密码学的公私钥定义.为了还原Fluu当时喜欢学一个名词就乱用的性格,特地采用”公私钥”作为称谓)

“公私钥法”

首先自己记住一串很长的随机字符串作为公钥,比如(这里采用Fluu曾用过的密码)Fluu皇室战争账号的UID:

1
#288LP8Q9U

然后对这个公钥进行处理,比如变成

1
2
#288LP8Q9Uqq    记作 1111qq
#288lp8q9uwx 记作 0000wx

对公钥的大小写进行变换,从而达到”密码又安全又好记”的效果.

尝试攻击 :首先需要拿到公钥,然后还要知道哪一位是被修改的,然后还需要知道怎么修改,而且就算拿到私钥,存储的都是诸如 1111qq 之类不知所云的东西,生成逻辑必须全部理解才能成功攻破这一套密码.

不过现在的各大app都能手机重置密码了,这么做的成本已经远大于收益,所以Fluu认为这一套密码是很成功的,如果你不想用密码管理器的话.

但在2026年,Fluu要告别这一套系统了.

拥抱密码管理器

Fluu这几年用自创密码机制的感受就是,麻烦.

  • 这个密码系统的第一个缺点就是不被很好的支持.
    比如某些银行的登陆密码不能有 . 这个字符,然而登录的时候不会告诉你登录的时候不能输入 . ,导致你的公钥直接被废,造成额外的记忆量(去记哪些平台不能输入 .,哪些平台连 # 都不能输入)

  • 这个密码系统的第二个缺点就是更新很麻烦.
    你需要手动维护这么一个 Crypto.md 作为你的”私钥表”防止忘记,久而久之这个”私钥表”会越来越长,这个时候需要担心的往往不是密码长什么样,而是你当初是怎么登录的(比如用Google还是Github还是手机号还是邮箱,哪个邮箱),所以你还需要维护你的账户信息,造成额外的记忆量.

综上,这个密码机制虽然好处多多但还是干不过密码管理器,最后Fluu在26年2月1日从Chrome自带的密码管理器换上了bitwarden.
由于第一天用bitwarden,后续有什么感受再说吧.

这篇博文的主题就是密码管理,我认为此时提及bitwarden不是广告.

PGP & GPG

先来一段小历史:

某年,有个人想加密传输消息,所以创造了PGP(Pretty Good Privacy),然后广泛传播,但它是商业软件,不能自由使用.
后来,GNU开发了一个能兼容PGP的加密产品,名字叫GPG(GNU Privacy Guard).

所以PGP和GPG是两个非常相近的概念,至少体感上差不多.

笔者参考这篇文章安装了Windows的Kleopatra,开箱即用.

最后Fluu也是可以签名的人了,公钥链接.

签名/加密原理

最后附上一段加密/解密/签名/验证的原理.

有一个系统叫非对称加密系统,加密和解密用两个不同的钥匙.一个通俗的比喻就是,建筑队来你家装修需要你家门钥匙,但你不希望他们装修完了还能进你家门,所以你的钥匙和建筑队的钥匙是两种钥匙,你拿到的是私钥和公钥,建筑队拿到的是公钥.

那么我们重新解释一下上面的名词:
加密:你用你的私钥锁上门;同理建筑队能用公钥锁门.
解密:如果用私钥锁上门可以用公钥开门,如果用公钥锁上门可以用私钥开.
签名:你在屋子里留一张字条(描述你屋子的信息),然后用你的私钥锁门.
验证:建筑队公钥开门后看到字条,核对屋子里和你字条的描述一致,签名的验证就成功了,如果进了贼把你的屋子翻得一团乱不符合你的字条,那么签名将会失败.

实际密码实现和这个差不多,不过实际上签名只是验证文件有没有被篡改,所以并没有”锁门”,只是把锁锁好之后挂上了.

关于 hexo-blog-encrypt (upd20260220)

Fluu在逛互联网的时候发现有人对这个插件的能力表示质疑,一个最典型的论调是:

hexo是静态博客,密码也是静态的,那么加密没有意义.

首先需要了解一下hexo-blog-encrypt是什么东西,他使用 AES-CBC256 加密规范.
什么是 AES-CBC256 ?

先用一个例子讲一讲AES有多安全:

经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。现在,高级加密标准已然成为对称密钥加密中最流行的算法之一。
— 维基百科高级加密标准

美国政府都在用,所以应该相信他是安全的,不然我也没什么更好的证明方法,不妨直接解密Fluu的博客试试看能不能成功.

那么稍微详细一点,Fluu大致讲解一下AES的工作流程.

首先文章会被拆成16个bytes,每个byte是8个二进制位,也就是能表示256个数字.
然后密钥也是16个byte,少的会补足多的会叠加,总之密钥也会被整成16个bytes.
然后AES会进行很复杂的变换操作,包括但不限于行变换,抑或运算,映射运算(有一个S盒),而且这样的运算有好几轮(可逆),具体算法实现不讲,感兴趣可以查找网上的实现,这不是重点.
然后就加密完成了,得到了16个混乱的bytes.

一篇文章很长,显然不只有16个bytes,所以我们要分块进行加密.
如果每块都是一个密钥,直接加密,最后拼起来,这叫 ECB .
肯定有人能想到,这样的话如果两个块信息完全一致,加密的结果也会是一致的.
这会非常危险,写字可能感受不到,但如果加密一个白底的图片,比如Linux企鹅,那么相同的块加密结果相同,攻击者能看出大致轮廓来,信息就暴露了.

所以我们额外添加一点噪音,比如说上一个块加密的结果抑或上下一个还没加密的块,然后再抑或上 iv (一个固定的噪音),这样每个块就不会一样了(或者说极大概率不会一样了),这就是 CBC .
至此完整的加密流程就完成了.

但是还有人能发现,AES本身全是算法,没有任何”比较”的成分,也就是说随便输入一个密码都能完成解密.

这就是AES的高明之处了,只能通过解密出来的结果人为(或者上nlp机器学习)认定解密的结果有没有意义,但是只有密钥对了才能拿到作者的内容.

现在来讲讲hexo-blog-encrypt插件是怎么实现的:噪声 iv 写死,然后对密钥”加盐”(也就是弄乱密钥),整成16bytes,再进行 AES-CBC256.

1
2
const keySalt = textToArray('hexo-blog-encrypt的作者们都是大帅比!');
const ivSalt = textToArray('hexo-blog-encrypt是地表最强Hexo加密插件!');

然后插件会在需要加密的博客内容前加上 <hbe-prefix></hbe-prefix> 标签,如果解密结果是这个,那么解密成功.
剩下的内容就没什么好说的了,加密,js脚本,密码验证.

现在讲一讲如何攻击这个插件.
首先看密钥的值域:一共256位bit,每一位bit都可以是1可以是0,那么值域是 $2^{256}$ ,也就是最坏需要 $2^{256}$ 次解密才能解密正确,这个数字大概是 $1.16\times 10^{77}$ .
现代计算机一秒能执行约 $3\times 10^8$ 次运算,假设1s能进行1次解密,按照一天10000s,一年1000天计算,足足要算 $1.16\times 10^{62}$ 年,所以直接攻击AES的方法是不可行的,真有这个算力完全可以去挖矿:比特币的原理是谁挖到了币就广播一下,然后大家更改到新区块上,通过长链鉴定谁的比特币是有效的.那么假设你有这么星际量的算力,足够干翻地球所有矿机,然后比特币会因为你的垄断暴跌,交易所瞬间拔电源(不能卖),引发市场对加密货币的恐慌,无数人爆仓上天台,你虽然挖到海量比特币但是大家不承认就变成了电子垃圾,因为比特币的初衷就是”去中心化”,下一步就是黑灰产找到了你希望你洗一洗他们的钱(加密洗钱的路被你堵死了不找你找谁),或者攻击政府的网站,视奸时代来临力,每个上网的人只能获取有限公共的服务,然后就是人类回归柜台和无线电时代…

所以与其猜加密的密钥,不如去猜文章的密码是什么,毕竟网上真的有很多密码设置 123456 的人,如果这样的人很少的话Fluu不会开这篇文章讲自己的故事的.

至于密钥怎么猜…那就很玄学了,不知道,反正肯定比直接猜密钥要便捷.

特别注意,插件的密钥会被混淆的,因为密钥也必须达到16bytes,所以填的密码是 123456 最后加密的不是 123456 ,是不好描述的神秘字符串,所以”加密的密钥”和”文章的密码”是两个东西,要稍微区分一下.

大家担心的破解问题无论何时都能发生而且都在发生,只是在你的服务器上检验对不对,和黑客自己检验对不对而已,没准给黑客惹毛了直接ddos你,得不偿失.

密码的意义也不是彻底断绝数据泄露,而是让数据的保险期尽可能拉长,让别人尽量看不出来你的内容,所以他是有意义的,而不是”反正能拿到源码,怎么加密都无所谓”,不然密码学也不会发展这么多年,也不会有Shadowsocks和GFW正在进行的大战,也不会有Trojan和Vmess等各种协议层出不穷.

关于 1Password(UPD20260225)

从V2ex论坛上发现1password涨价到 $47.88 一年(折合329.61),这下不能用了,bitwarden大赢特赢.
ref