Skip to content
This repository was archived by the owner on May 25, 2025. It is now read-only.

Commit c033774

Browse files
feat: timingSafeStringEqual
1 parent 7cfb199 commit c033774

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/security/crypto.util.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
encryptObject,
77
encryptRandomIVBuffer,
88
encryptString,
9+
timingSafeStringEqual,
910
} from './crypto.util'
1011

1112
const encKeyBuffer = Buffer.from(TEST_ENC_KEY, 'base64')
@@ -68,3 +69,15 @@ test('encryptObject, decryptObject', () => {
6869
// Should be deterministic:
6970
expect(encryptObject(obj1, encKeyBuffer)).toEqual(enc)
7071
})
72+
73+
test('timingSafeStringEquals', () => {
74+
const pw = 'hello!@#123'
75+
76+
expect(timingSafeStringEqual(undefined, pw)).toBe(false)
77+
expect(timingSafeStringEqual('', pw)).toBe(false)
78+
expect(timingSafeStringEqual('', '')).toBe(true)
79+
expect(timingSafeStringEqual('abc', 'abc')).toBe(true)
80+
expect(timingSafeStringEqual('abc', 'abd')).toBe(false)
81+
expect(timingSafeStringEqual(pw, pw)).toBe(true)
82+
expect(timingSafeStringEqual(pw, undefined)).toBe(false)
83+
})

src/security/crypto.util.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,20 @@ function getCryptoParams(secretKeyBuffer: Buffer): { key: Buffer; iv: Buffer } {
9393
const iv = md5AsBuffer(Buffer.concat([secretKeyBuffer, key]))
9494
return { key, iv }
9595
}
96+
97+
/**
98+
* Wraps `crypto.timingSafeEqual` and allows it to be used with String inputs:
99+
*
100+
* 1. Does length check first and short-circuits on length mismatch. Because `crypto.timingSafeEqual` only works with same-length inputs.
101+
*
102+
* Relevant read:
103+
* https://medium.com/nerd-for-tech/checking-api-key-without-shooting-yourself-in-the-foot-javascript-nodejs-f271e47bb428
104+
* https://codahale.com/a-lesson-in-timing-attacks/
105+
* https://github.com/suryagh/tsscmp/blob/master/lib/index.js
106+
*
107+
* Returns true if inputs are equal, false otherwise.
108+
*/
109+
export function timingSafeStringEqual(s1: string | undefined, s2: string | undefined): boolean {
110+
if (s1 === undefined || s2 === undefined || s1.length !== s2.length) return false
111+
return crypto.timingSafeEqual(Buffer.from(s1), Buffer.from(s2))
112+
}

0 commit comments

Comments
 (0)