Skip to content

Commit

Permalink
chore: temp code for hmac debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderPostma committed Dec 11, 2024
1 parent d377985 commit 1dccd80
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 34 deletions.
2 changes: 2 additions & 0 deletions packages/jwt-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"generate-plugin-schema": "sphereon dev generate-plugin-schema"
},
"dependencies": {
"@noble/curves": "1.7.0",
"@noble/hashes": "1.6.1",
"@sphereon/ssi-sdk-ext.did-utils": "workspace:*",
"@sphereon/ssi-sdk-ext.identifier-resolution": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/jwt-service/src/agent/JwtService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class JwtService implements IAgentPlugin {
try {
debug(`JWE Encrypt: ${JSON.stringify(args, null, 2)}`)

let alg = jweAlg(args.alg) ?? jweAlg(protectedHeader.alg) ?? 'ECDH-ES'
const alg = jweAlg(args.alg) ?? jweAlg(protectedHeader.alg) ?? 'ECDH-ES'
const enc = jweEnc(args.enc) ?? jweEnc(protectedHeader.enc) ?? 'A256GCM'
const encJwks =
recipientKey.jwks.length === 1
Expand Down
63 changes: 45 additions & 18 deletions packages/jwt-service/src/functions/JWE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
JwsPayload,
} from '../types/IJwtService'

import { p256 } from '@noble/curves/p256'
import { sha256 } from '@noble/hashes/sha256'
import { hmac } from '@noble/hashes/hmac'

export interface EncryptionResult {
ciphertext: Uint8Array
tag: Uint8Array
Expand All @@ -26,7 +30,6 @@ export interface EncryptionResult {
cek?: Uint8Array
}

import {createHmac} from 'crypto';

export const generateContentEncryptionKey = async ({
alg,
Expand Down Expand Up @@ -249,12 +252,11 @@ export class CompactJwtEncrypter implements JweEncrypter {
const iv = base64ToBytes(ivB64)
const ciphertext = base64ToBytes(ciphertextB64)

// If this is a content encryption key, we can use it as the HMAC key
if (this.recipientKey instanceof Uint8Array) {
// Log the HMAC calculation
verifyHmac(iv, ciphertext, this.recipientKey)
if (this._alg?.startsWith('ECDH')) {
const derivedKey = await deriveEcdhKey(this.recipientKey as CryptoKey)
verifyHmacEcdh(iv, ciphertext, derivedKey)
}

return jwt
}

Expand Down Expand Up @@ -385,18 +387,43 @@ export function toWebCryptoCiphertext(ciphertext: string, tag: string): Uint8Arr
return u8a.concat([base64ToBytes(ciphertext), base64ToBytes(tag)])
}

function verifyHmac(iv: Uint8Array, ciphertext: Uint8Array, macKey: Uint8Array) {
const hmac = createHmac('sha256', macKey)
hmac.update(new Uint8Array([...iv, ...ciphertext]))
const computedHash = hmac.digest()

console.log('Computed HMAC:', u8a.toString(computedHash, 'hex'))

// Here, replace `expectedAuthTag` with the actual authentication tag from the JWE
const expectedAuthTag = new Uint8Array() // Placeholder, replace with actual value
if (u8a.equals(computedHash, expectedAuthTag)) {
console.log('HMAC verification succeeded!')
} else {
console.error('HMAC verification failed!')
async function deriveEcdhKey(publicKey: CryptoKey): Promise<Uint8Array> {
// Extract public key coordinates
const jwk = await crypto.subtle.exportKey('jwk', publicKey)
if (!jwk.x || !jwk.y) {
throw new Error('Invalid public key format')
}

// Convert base64url coordinates to bytes
const xBytes = base64ToBytes(jwk.x)
const yBytes = base64ToBytes(jwk.y)

// Create point from coordinates
const point = p256.ProjectivePoint.fromAffine({
x: BigInt('0x' + u8a.toString(xBytes, 'hex')),
y: BigInt('0x' + u8a.toString(yBytes, 'hex'))
})

// Generate ephemeral key pair
const ephemeralPrivate = p256.utils.randomPrivateKey()
//const ephemeralPoint = p256.getPublicKey(ephemeralPrivate)

// Compute shared secret
const sharedPoint = point.multiply(BigInt('0x' + u8a.toString(ephemeralPrivate, 'hex')))
const sharedSecret = u8a.fromString(sharedPoint.x.toString(16), 'hex')

// Derive key using concat KDF as per JOSE spec
const derivedKey = await crypto.subtle.digest('SHA-256', sharedSecret)

return new Uint8Array(derivedKey)
}

function verifyHmacEcdh(iv: Uint8Array, ciphertext: Uint8Array, derivedKey: Uint8Array) {
const hmacKey = hmac.create(sha256, derivedKey)
const data = new Uint8Array([...iv, ...ciphertext])
const computedHmac = hmacKey.update(data).digest()

console.log('ECDH Derived Key:', u8a.toString(derivedKey, 'hex'))
console.log('Computed HMAC:', u8a.toString(computedHmac, 'hex'))
}
Loading

0 comments on commit 1dccd80

Please sign in to comment.