fix(auth): secureCompare to reuse constantTimeEqual from @oslojs/crypto (#180)
This commit is contained in:
@@ -6,7 +6,9 @@
|
||||
* Tokens are opaque random values. We store only the SHA-256 hash in the database.
|
||||
*/
|
||||
|
||||
import { sha256 } from "@oslojs/crypto/sha2";
|
||||
import { hmac } from "@oslojs/crypto/hmac";
|
||||
import { sha256, SHA256 } from "@oslojs/crypto/sha2";
|
||||
import { constantTimeEqual } from "@oslojs/crypto/subtle";
|
||||
import { encodeBase64urlNoPadding, decodeBase64urlIgnorePadding } from "@oslojs/encoding";
|
||||
|
||||
const TOKEN_BYTES = 32; // 256 bits of entropy
|
||||
@@ -162,16 +164,11 @@ export function computeS256Challenge(codeVerifier: string): string {
|
||||
* Constant-time comparison to prevent timing attacks
|
||||
*/
|
||||
export function secureCompare(a: string, b: string): boolean {
|
||||
if (a.length !== b.length) return false;
|
||||
const text = new TextEncoder();
|
||||
const salt = crypto.getRandomValues(new Uint8Array(TOKEN_BYTES));
|
||||
const hash = (str: string) => hmac(SHA256, salt, text.encode(str));
|
||||
|
||||
const aBytes = new TextEncoder().encode(a);
|
||||
const bBytes = new TextEncoder().encode(b);
|
||||
|
||||
let result = 0;
|
||||
for (let i = 0; i < aBytes.length; i++) {
|
||||
result |= aBytes[i]! ^ bBytes[i]!;
|
||||
}
|
||||
return result === 0;
|
||||
return constantTimeEqual(hash(a), hash(b));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user