XYZ
XYZ

Reputation: 83

How to derive a AES key with ANSI X9.63 in Java?

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.

  1. 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.

  2. 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).

Upvotes: 0

Views: 913

Answers (1)

XYZ
XYZ

Reputation: 83

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;
    }

Upvotes: 0

Related Questions