【发布时间】:2015-12-16 05:54:50
【问题描述】:
尝试使用使用 SJCL 的 RNCryptor-js 解密 AES。在记录每一端的所有步骤后,(另一端是RNCryptor-python)密钥、盐、HMAC 哈希,一切都匹配了。但是当我到达最后一步时:
var aes = new sjcl.cipher.aes(encryption_key);
sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]()
var decrypted = aes.decrypt(ciphertext, iv);
我得到错误:
sjcl.exception.invalid {toString: function, message: "invalid aes block size"}
这里是完整的代码:
PBKDF2:
this.KeyForPassword = function(password, salt) {
var hmacSHA256 = function (password) {
var hasher = new sjcl.misc.hmac(password, sjcl.hash.sha256);
this.encrypt = function () {
return hasher.encrypt.apply(hasher, arguments);
};
};
return sjcl.misc.pbkdf2(password, salt, 10000, 32 * 8, hmacSHA256);
};
解密(接受十六进制输入):
this.decrypt = function(password, message, options) {
message = sjcl.codec.hex.toBits(message);
options = options || {};
var version = sjcl.bitArray.extract(message, 0 * 8, 8);
var options = sjcl.bitArray.extract(message, 1 * 8, 8);
var encryption_salt = sjcl.bitArray.bitSlice(message, 2 * 8, 10 * 8);
var encryption_key = _this.KeyForPassword(password, encryption_salt, "decryption");
var hmac_salt = sjcl.bitArray.bitSlice(message, 10 * 8, 18 * 8);
var hmac_key = _this.KeyForPassword(password, hmac_salt, "decryption");
var iv = sjcl.bitArray.bitSlice(message, 18 * 8, 34 * 8);
var ciphertext_end = sjcl.bitArray.bitLength(message) - (32 * 8);
var ciphertext = sjcl.bitArray.bitSlice(message, 34 * 8, ciphertext_end);
var hmac = sjcl.bitArray.bitSlice(message, ciphertext_end);
var expected_hmac = new sjcl.misc.hmac(hmac_key).encrypt(sjcl.bitArray.bitSlice(message, 0, ciphertext_end));
if (! sjcl.bitArray.equal(hmac, expected_hmac)) {
throw new sjcl.exception.corrupt("HMAC mismatch or bad password.");
}
var aes = new sjcl.cipher.aes(encryption_key);
sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]()
var decrypted = aes.decrypt(ciphertext, iv);
return decrypted;
}
在定义decrypted 的倒数第二个语句中引发错误。
我查看了 sjcl 异常,看起来它正在寻找长度为 4 的输入,我猜它是一个 WordArray。我只是不知道如何获得有效的输入。就像我说的那样,密文、iv、hmac 标记、盐都在 javascript 端被正确分割。可能只是编码问题。
这个错误似乎也只发生在 json 上(格式:'{"key":"value"}'),当我尝试像“Hello, world”这样的东西时,我得到了一个没有错误的 4 字数组。
有什么建议吗?
【问题讨论】:
-
当您使用 JSON 时,如果您将代码设置为输出 ciphertext.length,那么长度是什么意思?
-
@WDS,
ciphertext.length为不同的 json 返回了不同的长度。较短的我得到 16,较长的:24,更长的:36。 -
如果我使用 Crypto-JS 代替最后一个解密步骤,我不会收到任何错误,但我会得到一个空的 WordArray。
-
我有点脱离我的元素,但似乎 Encrypt 和 Decrypt 函数一次只能处理一个块,并且您需要手动将密文拆分为单独的块,将每个块拆分为 4 个单词,一次将 4 个单词交给函数。 .NET 有方法可以在一组命令中处理任意长度的密文,但我猜你需要自己编写。作为测试,请尝试将您的密文 BitSlice 降低到 128 位并将其传递给解密函数。看看它是否会解密为纯文本的一部分。
-
好主意。尝试了拆分,我得到了一个单词数组,但由于某种原因我无法对其进行编码。 CryptoJS 和 sjcl Utf8 字符串化似乎都不起作用
标签: javascript python encryption rncryptor sjcl