先说结论
不算。Base64 是一种编码:用六十四个不惹事的字符,把任何数据重新写一遍,好让它穿过那些只为纯文本修的系统时不散架。它没有密钥,没有秘密,没有任何一种安全性质。要还原它,只需认出它,别的什么都不用。人要一眼,计算机要一毫秒。
这个问题仍然值得问,因为这场混淆到处都是,偶尔还很贵。base64 的字符串看着乱:cGFzc3dvcmQ= 对眼睛什么也不交代。而看着乱的东西,就被归进了“安全”那个抽屉。真有产品带着这样“保护”起来的密码出过厂。药方是一次学会的一组区别:编码是给机器的,加密是给秘密的,哈希是当指纹的。三件事,三样工具,护得住东西的只有一样。
编码:谁都能还原
编码改的是数据的写法,从不改它说了什么。邮件附件、样式表里嵌的图、网址里的令牌,处处都有一堆任意字节要过只认文本的路,base64 就是那身标准行头:三个字节进去,四个字符出来,用的是字母、数字加两个符号,末尾拿 = 补齐。认准末尾这个 =,往后你会发现 base64 无处不在。
定乾坤的性质是这一条:配方是公开的,倒着跑也一模一样。没有什么可知道的,也就没有什么可不知道的。网址里的百分号编码(空格写成 %20)、HTML 实体(&)、十六进制、反斜杠转义,都是同一个主意穿不同的衣服。这里的 Base64 编解码工具全都会说,双向都行,就在你自己的机器上。把捡到的字符串解开,和把它读一遍一样正当,因为编码从来就不是锁。
加密:持钥匙的人能还原
真护得住内容的是加密。它用一把密钥变换数据,数学摆的阵势是:没有密钥,逆变换不只是难,是算力够不着;有密钥,瞬间完成。秘密全住在密钥里,不住在方法里。算法是公开的,是标准,也正因如此才结实。
视觉上的混淆就咬在这儿,因为加密后的字节为了上路,照例要过一遍 base64:先让密钥搅乱,再穿上赶路的行头。两层,两件事。JSON Web Token 是课本级的例子:三段 base64 用点连着,前两段谁去试,都能解成能读的 JSON。天天有人把令牌贴进公开的网页解码器,只因为以为整个是封死的。老实的说法是:JWT 是一张带防伪签名的明信片,不是信封。
哈希:谁也还原不了
哈希只朝一个方向跑。多少数据都行,塞进 SHA-256,出来一个定长的数。同样的数据,每次同一个数;差一个比特的数据,一个面目全非的数。而从数回到数据的路,谁都没有,带不带钥匙都没有。它不是行头也不是锁,它是指纹。
正因如此,属于它的两件事它做得最对。核对下载的文件是不是发布者发布的那一个:对指纹。这活儿哈希与校验和工具在你机器上干,还有配套的指南。再有是存密码:运营得体的服务只存你密码的哈希,连它被偷走的数据库里也没有密码本身。哪家网站能把你忘掉的密码用邮件发回来,它就等于告诉你,它从来没做过哈希。哪份配置把密码写成 cGFzc3dvcmQ= 来“保护”,它就等于告诉你,它只做过编码。
在野外把三个认出来
对着眼前这串字符,有条管用的捷径:
- 解出来是能读的东西?那就是编码。字母数字,或许有
+和/,末尾常有=。丢进解码器看一眼。 - 解出来是一堆二进制噪声?那 base64 只是行头,底下的东西要么加密了,要么压缩了,要么压根不是文本。两种情况,编码都什么也告诉不了你。
- 定长、十六进制字符、从来解不开?64 个十六进制字符是 SHA-256 的身形,32 个是 MD5 的。哈希不解码,只有对得上和对不上。
每一个的实操教训各一句:保密的事,永远别托付给编码;平台带着现成的加密,永远别自己造;密码除了哈希,别用任何形式存。还有一层:你为了验证而去解码的那串字符,自己往往就是敏感的部分。调试中的令牌多半如此。所以这里的解码器跑在秘密本来就在的地方,你的机器上;所以往网页工具里粘贴到底意味着什么,另有自己的一页。