Created
December 29, 2023 15:27
-
-
Save 0xBigBoss/5680dcb89243c43fe86936a5374d4bc9 to your computer and use it in GitHub Desktop.
Verify a digital signature using ECDSA and Web Crypto API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export async function verifySignature({ | |
authenticatorData, | |
clientDataJSON, | |
r, | |
s, | |
x, | |
y, | |
}: { | |
authenticatorData: string | |
clientDataJSON: string | |
r: string | |
s: string | |
x: bigint | |
y: bigint | |
}): Promise<boolean> { | |
// Step 1: Decode the data | |
const authenticatorDataArray = new Uint8Array(Buffer.from(authenticatorData.slice(2), 'hex')) | |
const clientDataHash = new Uint8Array( | |
await crypto.subtle.digest('SHA-256', Buffer.from(clientDataJSON)) | |
) | |
const signatureBuffer = new Uint8Array(Buffer.from(r.slice(2) + s.slice(2), 'hex')) | |
// Combine clientDataJSON and authenticatorData into a single ArrayBuffer for verification | |
const dataBuffer = new Uint8Array(clientDataHash.length + authenticatorDataArray.length) | |
dataBuffer.set(clientDataHash, 0) | |
dataBuffer.set(authenticatorDataArray, clientDataHash.length) | |
// Convert BigInts to Uint8Array | |
const x64 = Buffer.from(x.toString(16), 'hex').toString('base64url') | |
const y64 = Buffer.from(y.toString(16), 'hex').toString('base64url') | |
const publicKey = { | |
kty: 'EC', | |
crv: 'P-256', | |
x: x64, | |
y: y64, | |
ext: true, | |
} | |
const importedKey = await crypto.subtle.importKey( | |
'jwk', | |
publicKey, | |
{ | |
name: 'ECDSA', | |
namedCurve: 'P-256', | |
}, | |
true, | |
['verify'] | |
) | |
// Step 3: Verify the signature | |
try { | |
return await crypto.subtle.verify( | |
{ | |
name: 'ECDSA', | |
hash: { name: 'SHA-256' }, | |
}, | |
importedKey, | |
signatureBuffer, | |
dataBuffer | |
) | |
} catch (error) { | |
console.error('Signature verification failed', error) | |
return false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment