加密/解密二进制数据加密-js



我无法使用Crypto-JS成功加密二进制消息。我的数据在数组缓冲区中。我在 Angular 工作,我已经进行了一个简短的测试,效果很好。我正在与 WiFi 设备通信。以下测试使用简单的字符串工作正常,这证明加密和传输都正常工作。

var iv_hexString = this.buf2hex([146, 66, 191, 151, 23, 3, 113, 119, 231, 131, 133, 112, 79, 32, 114, 136]);
var key_hexString = this.buf2hex([123, 217, 20, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 115, 222, 209, 241, 24, 175, 144, 175, 53, 196, 29, 24, 23, 17, 218, 131, 226, 53, 209]);
var key = CryptoJS.enc.Hex.parse(key_hexString);
var iv = CryptoJS.enc.Hex.parse(iv_hexString);
console.log('iv  = ' + iv);
console.log('key = ' + key);
let cli_verify = CryptoJS.AES.encrypt("1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff", key, {
mode: CryptoJS.mode.CTR,
iv: iv,
padding: CryptoJS.pad.NoPadding
});
console.log('Cipher Text = ', cli_verify.ciphertext.toString());

// Test by decoding some shit here. 
var decrypted = CryptoJS.AES.decrypt(cli_verify, key, {
mode: CryptoJS.mode.CTR,
iv: iv,
padding: CryptoJS.pad.NoPadding
});
console.log('Decrypted Output = ', decrypted.toString(CryptoJS.enc.Utf8));

这工作正常:

[ng] [console.log]: "iv  = 9242bf9717037177e78385704f207288"
[ng] [console.log]: "key = 7bd9140b181a552d72b81ba22573ded1f118af90af35c41d181711da83e235d1"
[ng] [console.log]: "Cipher Text = " "de3cfe57c4d6fc5a8218b9eb801ebd49d3bd6cbf9ecd1b62656be424c09ba1d72b8ea3b6f304752b514ff4dc086a63a5349534e08e110f4855108a8d96804af3"
[ng] [console.log]: "Decrypted Output = " "1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff"

问题是我的数据不在字符串中。它是二进制的,因此很难作为字符串传输。我对另一端的代码没有任何控制权,它需要这种格式。我的数据可能包含 256 个代码中的任何一个:

let myMessage = new Uint8Array([0x0a, 0x11, 0x00, 0xff, 0x30, 0x53, 0x22, 0x6a, 0x8f, 0x05, 0x16, 0x15, 0x88, 0xb5]);

谁能建议我如何格式化它,以便它将被 crypto-js 接受。在代码0x30的情况下,这当然是"0"。非常好。这很适合一根绳子。0x11和0x00:不太好!我尝试了以下方法:

var devPublic_hexString = this.buf2hex(this.device_Public_Key);
let cli_verify = CryptoJS.AES.encrypt(this.hex2a(devPublic_hexString), key, {
mode: CryptoJS.mode.CTR,
iv: iv,
padding: CryptoJS.pad.NoPadding
});
hex2a(hexx) {
var hex = hexx.toString();//force conversion
var str = '';
//for (var i = 0; (i < hex.length && hex.substr(i, 2) !== '00'); i += 2)
for (var i = 0; (i < hex.length); i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}

仔细观察十六进制转储,有一些很好的线索:

预期结果 另一面:

5CFA82944E 79 6408 9C 0B 9A 4D D8 8F 06 C539AD C0 919B C7 CC 6A 0A 86 81 DD 5DAD 0B03

实际结果另一面:

5C C3 BA C2 82 C2 944E 79 6408 C29C 0BC29A 4DC3 98 C28F 06C3 85 39 C2 AD C380C2 91 C2

等。我厌倦了加粗匹配位,但你可以看到模式。问题是所有的 c2 和 c3 代码都是关于什么的?为什么0xfa与牛巴混淆?0x98和0xd8一样?还有0xc5 0x85...还有0xC0 0x80...这与使用解码错误的非法字符串有关吗?如何使用此库来获取我的二进制数据?

您的问题源于这样一个事实,即来自crypto-jsWordArray将处理输入,因为 UTF-8 字符串和代码点转换将发生。您需要使用单字节编码,例如 Latin-1。以下是在某些表示形式之间进行转换的方法:

const arrayToString = arr => arr.reduce((str, code) => str + String.fromCharCode(code), '');
const original = new Uint8Array([0x0a, 0x11, 0x00, 0xff, 0x30, 0x53, 0x22, 0x6a, 0x8f, 0x05, 0x16, 0x15, 0x88, 0xb5]);
const originalString = arrayToString(original);
// -> Hex 0a1100ff3053226a8f05161588b5
const encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Latin1.parse(originalString), 'secret');
const encryptedArray32 = Uint32Array.from(encrypted.ciphertext.words);
const encryptedArray8 = new Uint8Array(encryptedArray32.buffer);
// -> Hex f6b58e23281ed5323e80d22e6fb94752
const decryptedString = CryptoJS.AES.decrypt(encrypted, 'secret').toString(CryptoJS.enc.Latin1);
const decryptedArray8 = Uint8Array.from(Buffer.from(decryptedString, 'latin1'));
// -> Hex 0a1100ff3053226a8f05161588b5

你来了:

function hexdump(buffer, blockSize) {
blockSize = blockSize || 16;
var lines = [];
var hex = "0123456789ABCDEF";
for (var b = 0; b < buffer.length; b += blockSize) {
var block = buffer.slice(b, Math.min(b + blockSize, buffer.length));
var addr = ("0000" + b.toString(16)).slice(-4);
var codes = block.split('').map(function (ch) {
var code = ch.charCodeAt(0);
return " " + hex[(0xF0 & code) >> 4] + hex[0x0F & code];
}).join("");
codes += "   ".repeat(blockSize - block.length);
var chars = block.replace(/[x00-x1Fx20x80-x9F]/g, '.');
chars +=  " ".repeat(blockSize - block.length);
lines.push(addr + " " + codes + "  " + chars);
}
document.write("<pre>"+lines.join("n")+"</pre>");
}
test_data=String.fromCharCode.apply(null, Uint8Array.from({length:256},(v,k)=>k++));
encrypted_data=CryptoJS.AES.encrypt(btoa(test_data), "secret");
decrypted_data=atob(CryptoJS.AES.decrypt(encrypted_data, "secret").toString(CryptoJS.enc.Utf8));
hexdump(decrypted_data)
<html> 
<head> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
</head> 
<body>
</body> 
</html>

最新更新