getPayloadFor method
Implementation
@override
List<int>? getPayloadFor(
JsonWebKey? key,
JoseHeader header,
JoseRecipient recipient,
) {
if (key == null) {
return null;
}
var aad = sharedProtectedHeader?.toBase64EncodedString() ?? '';
if (additionalAuthenticatedData != null) {
aad += '.${String.fromCharCodes(additionalAuthenticatedData!)}';
}
if (header.encryptionAlgorithm == 'none') {
throw JoseException('Encryption algorithm cannot be `none`');
}
JsonWebKey cek;
if (header.algorithm == 'dir') {
cek = key;
} else if (header.algorithm != null &&
header.algorithm!.startsWith('ECDH-ES')) {
// ECDH-ES key agreement
final epk = header.ephemeralPublicKey;
if (epk == null) {
throw JoseException('Missing ephemeral public key (epk) in header');
}
final encAlgorithm = header.encryptionAlgorithm!;
final algId = ecdhAlgorithmId(header.algorithm!, encAlgorithm);
final keyLen = ecdhKeyDataLen(header.algorithm!, encAlgorithm);
final apu = header.agreementPartyUInfo != null
? Uint8List.fromList(
decodeBase64EncodedBytes(header.agreementPartyUInfo!))
: null;
final apv = header.agreementPartyVInfo != null
? Uint8List.fromList(
decodeBase64EncodedBytes(header.agreementPartyVInfo!))
: null;
final derivedKey = ecdhEsDecrypt(
recipientPrivateKey: key,
ephemeralPublicKey: epk,
algorithmId: algId,
keyDataLen: keyLen,
apu: apu,
apv: apv,
);
if (header.algorithm == 'ECDH-ES') {
// Direct key agreement — derived key IS the CEK
cek = JsonWebKey.fromJson({
'kty': 'oct',
'k': encodeBase64EncodedBytes(derivedKey),
'use': 'enc',
'key_ops': ['encrypt', 'decrypt'],
})!;
} else {
// ECDH-ES+A*KW — derived key unwraps the CEK
final unwrappedCekBytes = ecdhEsUnwrapKey(derivedKey, recipient.data);
cek = JsonWebKey.fromJson({
'kty': 'oct',
'k': encodeBase64EncodedBytes(unwrappedCekBytes),
'use': 'enc',
'key_ops': ['encrypt', 'decrypt'],
})!;
}
} else {
cek = key.unwrapKey(recipient.data, algorithm: header.algorithm);
}
var uncompressed = cek.decrypt(data,
initializationVector: initializationVector,
additionalAuthenticatedData: Uint8List.fromList(aad.codeUnits),
authenticationTag: authenticationTag,
algorithm: header.encryptionAlgorithm);
switch (header.compressionAlgorithm) {
case null:
return uncompressed;
case 'DEF':
return Inflate(uncompressed).getBytes();
default:
throw JoseException(
'Unsupported compression algorithm ${header.compressionAlgorithm}');
}
}