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 a0304d5 commit d377985
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
6 changes: 3 additions & 3 deletions 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)}`)

const alg = jweAlg(args.alg) ?? jweAlg(protectedHeader.alg) ?? 'ECDH-ES'
let 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 All @@ -91,8 +91,8 @@ export class JwtService implements IAgentPlugin {
const apu = apuVal ? u8a.fromString(apuVal, 'base64url') : undefined
const apvVal = protectedHeader.apv ?? args.apv
const apv = apvVal ? u8a.fromString(apvVal, 'base64url') : undefined

const pubKey = await importJWK(jwkInfo.jwk)
const pubKey = await importJWK(jwkInfo.jwk, !jwkInfo.jwk.alg ? alg : undefined)
const encrypter = new CompactJwtEncrypter({
enc,
alg,
Expand Down
49 changes: 46 additions & 3 deletions packages/jwt-service/src/functions/JWE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export interface EncryptionResult {
cek?: Uint8Array
}

import {createHmac} from 'crypto';

export const generateContentEncryptionKey = async ({
alg,
randomSource = defaultRandomSource,
Expand Down Expand Up @@ -192,13 +194,16 @@ export class CompactJwtEncrypter implements JweEncrypter {
const protectedHeader = {
...jweProtectedHeader,
alg: jweProtectedHeader.alg ?? this._alg,
enc: jweProtectedHeader.enc ?? this._enc,
enc: jweProtectedHeader.enc ?? this._enc
}

if (!protectedHeader.alg || !protectedHeader.enc) {
return Promise.reject(Error(`no 'alg' or 'enc' value set for the protected JWE header!`))
}

this.enc = protectedHeader.enc
this.alg = protectedHeader.alg

if (payload.exp) {
this.expirationTime = payload.exp
}
Expand All @@ -208,29 +213,51 @@ export class CompactJwtEncrypter implements JweEncrypter {
if (payload.aud) {
this.audience = payload.aud
}

const encrypt = new jose.EncryptJWT(payload).setProtectedHeader({
...protectedHeader,
alg: this.alg,
enc: this.enc,
enc: this.enc
})

if (this._alg!.startsWith('ECDH')) {
if (!this._keyManagementParams) {
return Promise.reject(Error(`ECDH requires key management params`))
}
encrypt.setKeyManagementParameters(this._keyManagementParams!)
}

if (this.expirationTime !== undefined) {
encrypt.setExpirationTime(this.expirationTime)
}

if (this.issuer) {
encrypt.setIssuer(this.issuer)
}

if (this.audience) {
encrypt.setAudience(this.audience)
}
return await encrypt.encrypt(this.recipientKey)

const jwt = await encrypt.encrypt(this.recipientKey)

// Extract components from the compact JWT
// @ts-ignore
const [protectedPart, encryptedKey, ivB64, ciphertextB64, tagB64] = jwt.split('.')

// Convert base64url components back to Uint8Arrays for HMAC verification
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)
}

return jwt
}


public static async decryptCompactJWT(jwt: string, key: KeyLike | Uint8Array, options?: JWTDecryptOptions) {
return await jose.jwtDecrypt(jwt, key, options)
Expand Down Expand Up @@ -357,3 +384,19 @@ export async function decryptJwe(jwe: JweJsonGeneral, decrypter: JweDecrypter):
export function toWebCryptoCiphertext(ciphertext: string, tag: string): Uint8Array {
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!')
}
}

0 comments on commit d377985

Please sign in to comment.