Encryption PKCS11 deriveKey每次返回不同的值

Encryption PKCS11 deriveKey每次返回不同的值,encryption,smartcard,pkcs#11,hsm,cryptoki,Encryption,Smartcard,Pkcs#11,Hsm,Cryptoki,我有一个主密钥,希望将其多样化/衍生为其他密钥(在HSM内)。在完成以下操作后,我得到了以下代码: final java.security.Key key = token.getKeyStore().getKey(baseKeyAlias, null); iaik.pkcs.pkcs11.objects.Key baseKey = ((iaik.pkcs.pkcs11.provider.keys.IAIKPKCS11SecretKey) key).getKeyObject(); DESSecr

我有一个主密钥,希望将其多样化/衍生为其他密钥(在HSM内)。在完成以下操作后,我得到了以下代码:

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!");        
如您所见,我使用的是PKCS#11包装器(IAIK)。问题在于,派生使用相同的派生数据生成不同的密钥。这是预期的行为吗

我认为派生密钥每次都不同,因为我使用此密钥加密已知值,每次结果都不同:

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));
首次运行密钥派生和值加密

deriveKey successful!
encrypt using deriveKey: 7C4BB979F26FC78831CC83AB378E7B1D8E2F2D73B140D25D
deriveKey successful!
encrypt using deriveKey: F1CE8649333EA10E63B13DB3733CD55FFB010A63C6CEC7F2
deriveKey successful!
encrypt using deriveKey: A8D801BC1C0142B9E77576AEA0FBE677915E47144B6DCF3C
第二次运行密钥派生和值加密

deriveKey successful!
encrypt using deriveKey: 7C4BB979F26FC78831CC83AB378E7B1D8E2F2D73B140D25D
deriveKey successful!
encrypt using deriveKey: F1CE8649333EA10E63B13DB3733CD55FFB010A63C6CEC7F2
deriveKey successful!
encrypt using deriveKey: A8D801BC1C0142B9E77576AEA0FBE677915E47144B6DCF3C
第三次运行密钥派生和值加密

deriveKey successful!
encrypt using deriveKey: 7C4BB979F26FC78831CC83AB378E7B1D8E2F2D73B140D25D
deriveKey successful!
encrypt using deriveKey: F1CE8649333EA10E63B13DB3733CD55FFB010A63C6CEC7F2
deriveKey successful!
encrypt using deriveKey: A8D801BC1C0142B9E77576AEA0FBE677915E47144B6DCF3C

据我所知,派生是使用基本密钥对数据(派生数据)进行加密。然后将此加密值转换为另一个密钥(派生密钥),因此,如果派生数据和基本密钥相同,则此值应相同。请解释此步骤。

您应该使用
CKM_DES3\u ECB_ENCRYPT_data
而不是
CKM_DES3\u ECB

奇怪的是,您没有得到一个错误,因为
CKM_DES3_ECB
不应该被允许进行密钥派生(参见PKCS#11 v2.40中的表68)

您的假设是正确的——此密钥派生算法必须为相同的派生数据(和主密钥)提供相同的密钥

祝你的项目好运


请注意:您的示例派生数据似乎具有固定的结构。这样(在ECB模式下使用DES)生成的DES密钥的第三部分将始终相同(即
80000000000000
的加密)。在将派生数据用于密钥派生之前,您可能希望对其进行散列(例如,使用SHA-256)。或者完全重新考虑这个算法

免责声明:我不是密码专家,请验证我的想法