@@ -240,7 +240,7 @@ export async function validateDpopConfiguration(
240240 // String concatenation at runtime makes the import path impossible to statically analyze
241241 // This is bundler-agnostic and works with webpack, Turbopack, Vite, esbuild, Rollup, etc.
242242 const cryptoModule = "cry" + "pto" ;
243- const { createPrivateKey, createPublicKey } = await import (
243+ const { createPrivateKey, createPublicKey, webcrypto } = await import (
244244 cryptoModule as any
245245 ) ;
246246
@@ -292,15 +292,27 @@ export async function validateDpopConfiguration(
292292 return { dpopKeyPair : undefined , dpopOptions : undefined } ;
293293 }
294294
295- // Convert NodeJS KeyObjects to CryptoKeys synchronously
296- // toCryptoKey requires an algorithm object, not a string
297- // Keys must be extractable for JWK thumbprint calculation
298- const privateKey = privateKeyNodeJS . toCryptoKey (
295+ // Convert NodeJS KeyObjects to Web Crypto CryptoKeys
296+ // Export to DER format then import via Web Crypto API
297+ const privateKeyDer = privateKeyNodeJS . export ( {
298+ type : "pkcs8" ,
299+ format : "der"
300+ } ) ;
301+ const publicKeyDer = publicKeyNodeJS . export ( {
302+ type : "spki" ,
303+ format : "der"
304+ } ) ;
305+
306+ const privateKey = await webcrypto . subtle . importKey (
307+ "pkcs8" ,
308+ privateKeyDer ,
299309 { name : "ECDSA" , namedCurve : "P-256" } ,
300310 true ,
301311 [ "sign" ]
302312 ) ;
303- const publicKey = publicKeyNodeJS . toCryptoKey (
313+ const publicKey = await webcrypto . subtle . importKey (
314+ "spki" ,
315+ publicKeyDer ,
304316 { name : "ECDSA" , namedCurve : "P-256" } ,
305317 true ,
306318 [ "verify" ]
0 commit comments