G'day all,
I'm working through the creation of a cross-platform decryption implementation for CryptoKit's HPKE and wish to use the Sender & Recipient type.
I have been able to engineer the derived key, but the missing link is the nonce that is created and utilised by HPKE.Sender.seal()
. I understand that I could create the key exchange and sealed box by myself and set my own random nonce, but I want to be able to utilise the HPKE.Sender.seal()
functions to assist with this as well as create ciphertext data externally that can be opened with HPKE.Recipient.open()
.
By looking at Apple's open-source code available here, I can see that it seems to be exporting a key based on a "base_nonce" label on the context, which I think is what HPKE.Sender's exportSecret(context:outputByteCount:)
can achieve.
However using senders exportSecret(context:outputByteCount:) in the following way:
let noncedata = try hpkeSender.exportSecret(context: Data("base_nonce".utf8), outputByteCount: 12)
even just for one message (so the sequence number would be 0 and thus this data block unchanged), the AES-GCM implementation still returns a "cipher: message authentication failed" error. This is specifically in Go, but can be replicated in Python easily. I'm confident that the derived key is correct and is being fed to AES-GCM with the ciphertext correctly, and it's just the nonce generation that is not understood.