这个问题已经在 StackExchange 网络中被问过几次了,但是对于我的特定目标,我找不到解决方法。
我有一个使用 AES(高级加密标准)加密的私钥。我拥有的所有数据如下:
- 密码
- iv(初始化向量)
- v(我认为是版本,但我不确定)
- 伊特
- 密码:“aes”
- 盐
- 电脑断层扫描
例如,我有以下由test
以下代码test
生成的密码密文:斯坦福 Javascript 加密库
{"iv":"d2zscEJjWILOCfbgR8vrIg==",
"v":1,
"iter":1000,
"ks":128,
"ts":64,
"mode":"ccm",
"adata":"",
"cipher":"aes",
"salt":"fD0VonCNcWQ=",
"ct":"s7giov0Y59RCPu33"}
但我无法通过以下方式解密我自己的加密私钥:斯坦福 Javascript 加密库,所以我想使用 OpenSSL。OpenSSL 的问题是“糟糕的魔法数字”错误,假设我想解密提到的密文以获得test
如下消息:
openssl aes-128-cbc -d -iter 1000 -S 7C3D15A2708D7164 -iv 776CEC7042635882CE09F6E047CBEB22 -k test -in cipher.txt -out message.txt
但我得到了“糟糕的魔法数字”错误。
我有访问过这个答案但我无法解决这个问题,可能是我没有正确使用命令。我不知道如何正确使用|
(管道)和echo
。我的命令如下:
echo s7giov0Y59RCPu33 | base64 -d | openssl aes-128-cbc -d -iter 1000 -S 7C3D15A2708D7164 -iv 776CEC7042635882CE09F6E047CBEB22 -k test -out message.txt -in
答案1
“Salt”和“iterations”是特定密钥派生函数(KDF)的参数,因此您还需要知道使用了哪个 KDF 来从密码派生密钥。
SJCL 库默认使用 PBKDF2-SHA256。幸运的是,
openssl enc
如果您指定该-iter
选项,它也会使用。但请记住,它是最近添加到 OpenSSL CLI 中的;旧版本仅支持旧版 EVP_BytesToKey 算法。(如果您使用 libcrypto,无论如何都需要您调用 KDF,因此无论版本如何,您仍然可以使用 PBKDF2 - 尽管您可能需要自己重新实现它。)
openssl enc
要求输入包含一个标头,由 ASCII 值Salted__
(即“魔法数字”)和 KDF 的 8 字节盐组成。此功能为 CLI 用户提供了便利,因为它允许单个文件同时携带盐和数据。但是,SJCL“ct”参数仅包含原始密文,因此您必须使用该
-nosalt
选项让 OpenSSL 接受它。(与 SJCL 一样,OpenSSL libcrypto 库也适用于原始数据。)
最后,您必须使用正确的密码模式。(没有模式的分组密码只能加密一个块,因此您永远不要使用“仅 AES”——您可以将其与某种模式相结合以链接加密,从而产生 AES-CBC、AES-OFB、AES-GCM 等。)
SJCL 使用 AES128-CCM,但您尝试使用 AES128-CBC 进行解密。这行不通;解密时必须使用完全相同的模式,否则您只会得到垃圾。
不幸的是,
openssl enc
似乎不支持像 CCM 或 GCM 这样的“AEAD”模式。(它们受最新的 libcrypto 版本支持,但需要稍微不同的界面。)
建议:不要使用openssl
命令行工具;而是使用加密库编写自己的解密工具。(例如,Perl 和 CryptX。