javascript 将数字转换为ArrayBuffer

11dmarpk  于 5个月前  发布在  Java
关注(0)|答案(5)|浏览(90)

我正在尝试使用AES-CTR算法解密浏览器上的数据。WebCrypto API要求将计数器作为BufferSource传递。如何将计数器(数字)转换为预期的输入(字节数组)?
我使用的是全零IV,所以计数器从0开始。假设我试图解密计数器= 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
}

3ks5zfa0

3ks5zfa01#

有一个一行程序的解决方案为IE10+:)

new Int32Array([n]).buffer

字符串

ndasle7k

ndasle7k2#

这是我用途:

const bytesArray = (n) => {
  if (!n) return new ArrayBuffer(0)
  const a = []
  a.unshift(n & 255)
  while (n >= 256) {
    n = n >>> 8
    a.unshift(n & 255)
  }
  return new Uint8Array(a).buffer
}

字符串

fgw7neuy

fgw7neuy3#

不确定这是否有帮助。但只是为了交叉检查代码的真实性。
我写了一些测试用例,首先将数字转换为数组缓冲区,然后使用数组缓冲区的值将其解码为相同的值。

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]

字符串
两个结果都是一样的,只是你的代码产生的结果是大端格式,而我的是小端格式。
所以你的做法是对的,至于业绩我觉得影响不大

r7s23pms

r7s23pms4#

您不需要做任何事情,ArrayBuffer被初始化为所有值为零的字节,这当然也表示静态无符号,大端编码中使用的数字值零-这是CTR模式下表示计数器的常见方式。
下面是ArrayBuffer的返回值的描述,只有一个指定的大小:
指定大小的新ArrayBuffer对象。其内容初始化为0。
所以你去,你准备好了,而不知道它。唯一的事情我肯定会做的是 * 注解 *,缓冲区中的计数器已被初始化为零,为下一个开发人员(实际上可能是你在几年内)。
请注意,CTR模式是安全的,如果计数器从来没有重复相同的密钥。为此,nonce(它需要一个未知数量的字节到 * 左手 *,最高有效侧)通常被设置为一个随机值,通常通过简单地初始化前8个字节为随机值。所以你也不需要做任何数字编码。
如果随机数本身由32或64位计数器组成,则只需要对它进行编码。

qzlgjiam

qzlgjiam5#

const uIntToBytes = (num, size, method) => {
   const arr = new ArrayBuffer(size)
   const view = new DataView(arr)
   view[method + (size * 8)](0, num)
   return arr
}

const toBytes = (data, type) =>
   type == "u8"  ? uIntToBytes(data, 1, "setUint") :
   type == "u16" ? uIntToBytes(data, 2, "setUint") :
   type == "u32" ? uIntToBytes(data, 4, "setUint") :
   type == "u64" ? uIntToBytes(BigInt(data), 8, "setBigUint")
                 : `Not Sure about type - ${type}`

字符串
使用方法:
第一个月

相关问题