I have a master key and want to diversify/derive it into other keys (inside an HSM). After following this answer I have this code:
final java.security.Key key = token.getKeyStore().getKey(baseKeyAlias, null);
iaik.pkcs.pkcs11.objects.Key baseKey = ((iaik.pkcs.pkcs11.provider.keys.IAIKPKCS11SecretKey) key).getKeyObject();
DESSecretKey derived3DESKeyTemplate = new DESSecretKey();
SecretKey derivedKeyTemplate = derived3DESKeyTemplate;
derivedKeyTemplate.getLabel().setCharArrayValue(derivedKeyAlias.toCharArray());
derivedKeyTemplate.getId().setByteArrayValue(derivedKeyAlias.getBytes());
derivedKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getKeyType().setLongValue(PKCS11Constants.CKK_DES2);
derivedKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getWrap().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getUnwrap().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getDerive().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getExtractable().setBooleanValue(Boolean.TRUE);
derivedKeyTemplate.getPrivate().setBooleanValue(Boolean.FALSE);
derivedKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
byte[] derivationData = DatatypeConverter.parseHexBinary("45525448555200749916");
KeyDerivationStringDataParameters param = new KeyDerivationStringDataParameters(derivationData);
Mechanism mechanism = new Mechanism(PKCS11Constants.CKM_DES3_ECB);
mechanism.setParameters(param);
final Key deriveKey = session.deriveKey(mechanism, baseKey, derivedKeyTemplate);
System.out.println("deriveKey successful!");
As you can see I am using a PKCS#11 wrapper (IAIK). The problem is the derivation generating different keys with the same derivation data. Is this an expected behaviour?
I think the derived keys are different each time because I am encrypting a known value with this key and the results are different every time:
byte[] data = DatatypeConverter.parseHexBinary("01020304050607080C7D8B973D588B478000000000000000");
Mechanism m = new Mechanism(PKCS11Constants.CKM_DES3_ECB);
session.encryptInit(m, deriveKey);
byte[] bytes;
bytes = session.encrypt(data);
System.out.println(DatatypeConverter.printHexBinary(bytes));
first run of key derivation and value encription
deriveKey successful!
encrypt using deriveKey: 7C4BB979F26FC78831CC83AB378E7B1D8E2F2D73B140D25D
second run of key derivation and value encription
deriveKey successful!
encrypt using deriveKey: F1CE8649333EA10E63B13DB3733CD55FFB010A63C6CEC7F2
third run of key derivation and value encription
deriveKey successful!
encrypt using deriveKey: A8D801BC1C0142B9E77576AEA0FBE677915E47144B6DCF3C
As far as I know the derivation is the encryption of data (derivation data) with a base key. This encrypted value is then converted to another key (derived key) and thus this value should be the same if the derivation data and base key are the same, this answer explain this steps.