火眼金睛:如何肉眼识别Base64编码的JSON、证书与私钥
最后修改于2025年8月5日
我在家庭实验室工作时,检查了一个本应包含加密内容的文件,该文件可以安全地提交到Github仓库。文件内容如下:
1
2
3
4
5
6
7
8
9
|
{
"serial": 13,
"lineage": "24d431ee-3da9-4407-b649-b0d2c0ca2d67",
"meta": {
"key_provider.pbkdf2.password_key": "eyJzYWx0IjoianpHUlpMVkFOZUZKcEpSeGo4UlhnNDhGZk9vQisrR0YvSG9ubTZzSUY5WT0iLCJpdGVyYXRpb25zIjo2MDAwMDAsImhhc2hfZnVuY3Rpb24iOiJzaGE1MTIiLCJrZXlfbGVuZ3RoIjozMn0="
},
"encrypted_data": "ONXZsJhz37eJA[...]",
"encryption_version": "v0"
}
|
嗯?密钥提供者?密码密钥?在加密文件中?这听起来不太对劲。问题是这个文件是通过获取密码、从中派生密钥,然后用该密钥加密内容生成的。我不知道派生密钥可能是什么样子,但它可能就是那个长的难以理解的字符串。
我请一位同事看了一下,他说:“哦,那个?看起来像是Base64编码的JSON。试试看里面有什么。”
我半信半疑,但试了一下,居然成功了!
终端窗口
1
2
|
$ echo "eyJzYWx0IjoianpHUlpMVkFOZUZKcEpSeGo4UlhnNDhGZk9vQisrR0YvSG9ubTZzSUY5WT0iLCJpdGVyYXRpb25zIjo2MDAwMDAsImhhc2hfZnVuY3Rpb24iOiJzaGE1MTIiLCJrZXlfbGVuZ3RoIjozMn0=" | base64 -d
{"salt":"jzGRZLVANeFJpJRxj8RXg48FfOoB++GF/Honm6sIF9Y=","iterations":600000,"hash_function":"sha512","key_length":32}
|
我不敢相信同事能即时解码Base64字符串,于是问道:“你是怎么发现的?是因为末尾的等号填充吗?但你怎么知道它是Base64编码的JSON,而不仅仅是一个Base64字符串?”
他回答说:
每当你看到ey,那就是{",然后如果后面跟着一个字母,你会得到J后面跟着一个字母。
我在终端中做了几个测试,他是对的!你可以用肉眼识别Base64编码的JSON,而且不需要即时解码!
终端窗口
1
2
3
4
5
6
7
8
9
10
|
$ echo "{" | base64
ewo=
$ echo "{\"" | base64
eyIK
$ echo "{\"s" | base64
eyJzCg==
$ echo "{\"a" | base64
eyJhCg==
$ echo "{\"word\"" | base64
eyJ3b3JkIgo=
|
但还有更好的!正如tyzbit在fediverse上报道的,你甚至可以用肉眼识别Base64编码的证书和私钥!它们都以LS开头,这让人想起“TLS证书”中的LS。
终端窗口
1
2
|
$ echo -en "-----BEGIN CERTIFICATE-----" | base64
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
|
勘误
正如Hacker News上的gnabgib和athorax所指出的,这实际上检测的是PEM格式(常用于证书)的前导破折号,而以---开头的YAML文件也会产生相同的结果。
终端窗口
1
2
|
$ echo "---\n" | base64
LS0tXG4K
|
这不是万无一失的方法!
感谢Davide和Denis向我展示这个简单但非常有用的技巧,感谢tyzbit用证书和私钥完善了它!