字符码 128 以上 javascript 中的二进制字符串
Binary string in javascript above charcode 128
我正在尝试解密 OpenSSL AES 加密文件,为此我需要从文件开头读取 salt,并将其与密码一起提供给 CryptoJS openssl 密钥派生函数以获取派生密钥和iv.
可悲的是,CryptoJS 期望 salt 作为字符串,而 JS 中的字符串处理二进制数据很差。
超过 128 的字符在 JS 中被解释为 2 位(参见:Trouble with binary string in javascript above character code 128):
// if you wanna test it, openssl command to generate a file from any file :
// openssl enc -aes-256-cbc -in file.txt -out file.enc -k password
fs.readFile('file.enc', function(err, data) {
var Salted__ = data.toString("utf-8", 0, 8); // 'Salted__' prefix
var salt = data.toString("hex", 8, 16); // the actual salt I want to give to CryptoJS
// output in hex: 46d69efb7f57380b
var buf = new Buffer(salt, "hex");
console.log(buf);
// output <Buffer 46 d6 9e fb 7f 57 38 0b>, exactly what I want, but it is a buffer not a String object.
// the problem can be seen here:
var buf2 = new Buffer(buf.toString());
console.log(buf2);
// output <Buffer 46 d6 9e ef bf bd 7f 57 38 0b>
// as you can see, fb => ef bf bd
// fun fact, when I try to do it manualy, I get another result (that seem more logical to me):
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
console.log(new Buffer(str));
// output <Buffer 46 c3 96 c2 9e c3 bb 7f 57 38 0b>
// in this case (I've tryed it char by char to be sure):
// d6 => c3 96
// 9e => c2 9e
// fb => c3 bb
var derivedParams = CryptoJS.kdf.OpenSSL.execute(password, 256/32, 128/32, buf.toString());
console.log(derivedParams.key.toString());
console.log(derivedParams.iv.toString());
// output a wrong key and a wrong iv (I know what I should get using openssl enc -P option)
});
任何关于 JS 如何处理二进制字符串的帮助或解释将不胜感激:)
我找到了解决办法!
var salt = CryptoJS.enc.Hex.parse(salt);
CryptoJS.kdf.OpenSSL.execute(password, 256/32, 128/32, salt);
我正在尝试解密 OpenSSL AES 加密文件,为此我需要从文件开头读取 salt,并将其与密码一起提供给 CryptoJS openssl 密钥派生函数以获取派生密钥和iv.
可悲的是,CryptoJS 期望 salt 作为字符串,而 JS 中的字符串处理二进制数据很差。 超过 128 的字符在 JS 中被解释为 2 位(参见:Trouble with binary string in javascript above character code 128):
// if you wanna test it, openssl command to generate a file from any file :
// openssl enc -aes-256-cbc -in file.txt -out file.enc -k password
fs.readFile('file.enc', function(err, data) {
var Salted__ = data.toString("utf-8", 0, 8); // 'Salted__' prefix
var salt = data.toString("hex", 8, 16); // the actual salt I want to give to CryptoJS
// output in hex: 46d69efb7f57380b
var buf = new Buffer(salt, "hex");
console.log(buf);
// output <Buffer 46 d6 9e fb 7f 57 38 0b>, exactly what I want, but it is a buffer not a String object.
// the problem can be seen here:
var buf2 = new Buffer(buf.toString());
console.log(buf2);
// output <Buffer 46 d6 9e ef bf bd 7f 57 38 0b>
// as you can see, fb => ef bf bd
// fun fact, when I try to do it manualy, I get another result (that seem more logical to me):
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
console.log(new Buffer(str));
// output <Buffer 46 c3 96 c2 9e c3 bb 7f 57 38 0b>
// in this case (I've tryed it char by char to be sure):
// d6 => c3 96
// 9e => c2 9e
// fb => c3 bb
var derivedParams = CryptoJS.kdf.OpenSSL.execute(password, 256/32, 128/32, buf.toString());
console.log(derivedParams.key.toString());
console.log(derivedParams.iv.toString());
// output a wrong key and a wrong iv (I know what I should get using openssl enc -P option)
});
任何关于 JS 如何处理二进制字符串的帮助或解释将不胜感激:)
我找到了解决办法!
var salt = CryptoJS.enc.Hex.parse(salt);
CryptoJS.kdf.OpenSSL.execute(password, 256/32, 128/32, salt);