I'm attempting to write code to decrypt a JWE token in PHP, as the existing libraries don't support the algorithm I need (A128CBC+HS256
, it's a deprecated algorithm).
My issue is I can't understand how to generate the content encryption key which uses a "Concatenation Key Derivation Function" (see section 5.8.1 here: http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf). The symbols and explanation of the function goes over my head.
I'm getting my values based on JOSE JSON web algorithms draft 06.
So far, the relevant portion of my code looks like this:
// Derive CBC encryption & integrity keys
$shaSize = 256;
$encryptionKeySize = $shaSize / 2;
$integrityKeySize = $shaSize;
// Calculate the key derivation using Concat KDF for the content
// encryption key
$encryptionSegments = [
$masterKey, // Z
$encryptionKeySize, // keydatalen
$this->packInt32sBe($encryptionKeySize) . utf8_encode('A128CBC+HS256'), // AlgorithmID
$this->packInt32sBe(0), // PartyUInfo
$this->packInt32sBe(0), // PartyUInfo
'Encryption', // SuppPubInfo
$this->packInt32sBe(1), // SuppPrivInfo
];
// Calculate the SHA256 digest
$cek = hex2bin(hash('sha256', implode('', $encryptionSegments)));
Possibly relevant, my function for getting a big endian integer:
public function packInt32sBe($n)
{
if (pack('L', 1) === pack('N', 1)) {
return pack('l', $n);
}
return strrev(pack('l', $n));
}
The only variable not shown here is $masterKey
which is the decrypted content master key.