How to use crypto.timingSafeEqual with strings

by
, posted

Node’s crypto.timingSafeEqual only works with buffers. To make it work with strings, you should convert the strings to UTF-16 buffers and then pass them to crypto.timingSafeEqual.

Here’s the code:

import { Buffer } from "node:buffer";
import * as crypto from "node:crypto";

function stringTimingSafeEqual(a, b) {
  const bufferA = Buffer.from(a, "utf16le");
  const bufferB = Buffer.from(b, "utf16le");
  return crypto.timingSafeEqual(bufferA, bufferB);
}

It’s important that you use UTF-16 because it’s the only encoding supported by Node that doesn’t lose some information along the way:

The only one that doesn’t lose data is utf16le, which is why you should use it here. (You could also use its legacy alias, ucs2, but I think this is less clear.)