我正在尝试使用AES-CTR算法解密浏览器上的数据。 WebCrypto API要求计数器作为BufferSource传递。如何将计数器(数字)转换为预期输入(字节数组)?
我正在使用全零IV,所以计数器从0开始。假设我正在尝试解密其中counter = 445566的数据。如何将445566转换为ArrayBuffer?
const key = // retrieve decryption key
const encrypted = // retrieve encrypted data
const iv = new ArrayBuffer(16)
// iv is all zeros. I need it to represent 445566, how?
const algo = {
name: 'AES-CTR',
counter: iv,
length: 128
}
const decrypted = await crypto.subtle.decrypt(algo, key, encrypted)
编辑:在挖掘一些加密库后,我最终使用了这个。它似乎做我想要的,但不知道正确性,性能等。
function numberToArrayBuffer(value) {
const view = new DataView(new ArrayBuffer(16))
for (var index = 15; index >= 0; --index) {
view.setUint8(index, value % 256)
value = value >> 8;
}
return view.buffer
}
不确定这是否有用。但只是交叉检查代码的真实性。
我写了一些测试用例,首先将数字转换为数组缓冲区,并使用数组缓冲区值将其解码为相同。
var hex = 445566..toString(16);
var buffer = new ArrayBuffer(16);
var dataView = new DataView(buffer);
dataView.setInt32(0, '0x'+ hex);
console.log(dataView.getInt32(0)); //445566
//Using the uint16array data generated by the above code
var data = [0, 6, 204, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var buf = new ArrayBuffer(16);
var view = new DataView(buf);
data.forEach(function (b, i) {
view.setUint8(i, b % 256);
});
var num = view.getInt32(0);
console.log(num);//445566
function numberToArrayBuffer(value) {
const view = new DataView(new ArrayBuffer(16))
for (var index = 15; index >= 0; --index) {
view.setUint8(index, value % 256)
value = value >> 8;
}
return view.buffer
}
console.log(numberToArrayBuffer(445566)) // Uint8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 204, 126]
结果都是一样的。只是你的代码以大端格式生成结果,并以小端格式生成。
所以你所遵循的方法是正确的。至于表现,我认为没有太大的影响
你不需要做任何事情,ArrayBuffer
被初始化为所有零值的字节,这当然也代表使用静态无符号,大端编码的数值零 - 这是在CTR模式下表示计数器的常用方法。
以下是仅具有指定大小的ArrayBuffer
返回值的说明:
一个指定大小的新
ArrayBuffer
对象。其内容初始化为0。
所以,你走了,你准备好了,不知道它。我唯一能做的就是评论缓冲区中的计数器已被初始化为零,以供下一个开发人员使用(实际上可能是你在几年内)。
请注意,如果从不对同一个键重复计数器,则CTR模式是安全的。为此,通常通过简单地将前8个字节初始化为随机值,将随机数(对于左手,最重要的一侧采用未知数量的字节)通常设置为随机值。因此,您不需要为此进行任何数字编码。
如果nonce由32位或64位计数器本身组成,则只需对其进行编码。