Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert number to ArrayBuffer

I'm trying to decrypt data on the browser using the AES-CTR algo. The WebCrypto API requires the counter to be passed as a BufferSource. How do I convert the counter (a number) to the expected input (a byte array)?

I'm using an all zero IV, so the counter starts at 0. Let's say I'm trying to decrypt data where counter = 445566. How do I convert 445566 into an 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)

EDIT: After digging around some crypto libraries, I ended up using this. It seems to do what I want, but no idea on correctness, performance, etc.

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
}
like image 839
Eric Guan Avatar asked Apr 08 '19 23:04

Eric Guan


2 Answers

There is an one-liner solution for IE10+ :)

new Int32Array([n]).buffer
like image 101
Burak Büyükatlı Avatar answered Sep 19 '22 08:09

Burak Büyükatlı


This is what I use:

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
}
like image 22
Khoi Avatar answered Sep 17 '22 08:09

Khoi