我遇到了解密AES-CBC加密字符串的问题。我有解密该字符串的JS代码,但我需要在C++中完成。密钥是SHA512散列字符串,消息是Base64字符串。解密的JS代码:
CryptoJS.algo.AES.keySize = 32,
CryptoJS.algo.EvpKDF.cfg.iterations = 10000,
CryptoJS.algo.EvpKDF.cfg.keySize = 32;
var r = CryptoJS.AES.decrypt(message, key.toString());
我的C++代码不工作
x一个一个一个一个x一个一个二个x
也许我应该使用OpenSSL?
1条答案
按热度按时间flseospp1#
由发送的CryptoJS代码生成的密文无法由任何AES兼容库解密。这是由于以下行
其定义了用于密钥导出的32个字= 32 * 4 = 128字节的密钥大小。这不是有效的AES密钥大小,并且根本没有为AES定义导出的轮数(128字节为38轮,参见此处;AES仅定义10、12和14轮,具体取决于密钥大小)。因此,密文不符合AES。它可以使用CryptoJS解密,但不能使用任何符合AES的库解密,另请参阅CryptoJS问题#293。要使生成的密文与AES兼容,必须使用允许的AES密钥大小之一,例如,密钥大小为8个字= 32字节:
此外,请注意这行
导致与OpenSSL CLI不兼容,默认情况下,OpenSSL CLI在密钥派生中使用迭代计数1(这是此密钥派生弱的原因之一,请参见here)。
顺便说一句,这条线
完全被处理忽略并且也可以省略。
如果使用有效的AES密钥大小,例如8个字= 32字节:
密文可以通过编程来解密。正如注解中已经提到的,如果密钥材料作为字符串传递,CryptoJS将使用OpenSSL专有密钥派生函数
EVP_BytesToKey()
。这将在加密期间生成8字节salt,并使用salt和密码派生密钥和IV。默认情况下,这些用于在CBC模式下使用PKCS#7填充进行加密。OpenSSL将加密的结果格式化为Salted__的ASCII编码的串联,接着是8个字节的salt,最后是实际的密文,通常是Base64编码。解密时,必须将盐和密文分离,然后根据盐和口令确定密钥和IV,最后对密文进行解密。
因此,为了解密,需要
EVP_BytesToKey()
的实现,可以在Crypto文档中找到Cryptohere的这种实现,并且可以用来解密CryptoJS代码的密文(在固定密钥大小问题之后)的代码例如是: