They are cloud and device team in my company, and sometime cloud side needs to send a sensitive information to the device. For this we are using SHA-512
key derivation function to derive a AES key and encrypt the payload. But device team wants to adopt PKCS#11 for making various operations happen on the device standardize, hence we need to change the way we are deriving a key on the cloud side, from SHA-512
to ECDH X9.63
.
In the device side, they are using C language with PKCS#11 library (C_DeriveKey
function). In Java, we don't have a straightforward way of using the C_DeriveKey
function to derive a key. They are some limitation on top of this, such that we cannot use any third party library that are not approved in the company. Since bouncy castle library is approved, I am looking for a way to use this to derive a key.
I found few way of deriving a key, but none of them output the desire AES key.
Using ECCDHwithSHA256KDF
key agreement algorithms and UserKeyingMaterialSpec
to perform the key agreement and the KDF in one go (reference: Apple eciesEncryptionCofactorVariableIVX963SHA256AESGCM vs BouncyCastle ECCDHwithSHA256KDF). This generated a different AES key when compared with the device side.
Using ECDHKEKGenerator
to derive a key. Same outcome as above, didn't match. Also, this is probably for envelope encryption, which is use to encrypt the key (ECDHKEK - ECDH key encryption key).
I found a function that generated the desire output using KDF2BytesGenerator
:
/**
* X9.63 key derivation function, derives AES session key from a secret
*/
public static byte[] deriveKeyWithANSIX963(byte[] sharedSecret) {
byte[] derivedOOEK = new byte[32];
SHA256Digest hash = new SHA256Digest();
KDF2BytesGenerator kdf = new KDF2BytesGenerator(hash);
// KDF parameters is (arg1 shared secret, arg2 iv)
kdf.init(new KDFParameters(sharedSecret, null));
kdf.generateBytes(derivedOOEK, (short) 0, 32);
return derivedOOEK;
}