使用使用SJCL的RNCryptor。我试图解密十六进制消息,但使用CBC模式时,事情变得奇怪。显然,当使用CBC时必须声明一个谨防语句,我得到一个错误。
function KeyForPassword(password, salt) {
console.log("Creating key...");
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);
};
function decrypt(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);
var hmac_salt = sjcl.bitArray.bitSlice(message, 10 * 8, 18 * 8);
var hmac_key = _this.KeyForPassword(password, hmac_salt);
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));
// .equal is of consistent time
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 = sjcl.mode.cbc.decrypt(aes, ciphertext, iv);
return decrypted.toString(CryptoJS.enc.Utf8);
};
在盐、密钥和哈希值方面,所有内容都与Python端的加密匹配。但是我得到这个错误:
TypeError: Cannot read property 'CBC mode is dangerous because it doesn't protect message integrity.' of undefined
我认为该方法已被弃用,所以我试图使用这个CryptoJS方法:
var decrypted = CryptoJS.AES.decrypt(ciphertext, encryption_key, {iv:iv});
这只是返回一个空字符串。
我觉得我真的很接近了,只是最后一部分需要一些帮助,谢谢。
SJCL
如果你在GitHub上查看配置,CBC不包括在预构建的sjcl.js中。您必须在页面中单独包含CBC文件(core/CBC .js),否则您需要操作配置文件以在启用的模块列表中添加CBC。
CryptoJS
decrypted
不是空字符串。CryptoJS.<cipher>.decrypt()
返回一个WordArray
对象,sigBytes
为负数。该属性表示WordArray
预期包含的字节数。负数表示出了问题。它不一定总是一个负数
可能有很多问题:
- 您没有正确的密钥。
- 您没有正确切片的密文。
-
ciphertext
不是一个OpenSSL格式化的字符串或者不是一个CipherParams
对象。尝试通过{ciphertext: ciphertext}
代替。 - key和IV格式不正确:它们应该是
WordArray
对象。
正如Artjom b所说,cbc.js和bitArray.js(解密的必要部分和我缺少的东西)一样是需要的。原来的代码现在可以正常工作了。
就像Rob Napier指出的那样,关于PBKDF2迭代计数,它很慢。然而,对于这种情况(解密),10K计数工作得很快,但是对于加密,我在1000次迭代中使用CryptoJS的PBKDF2来补充kdf(使用sjcl的bitArray错误)。