2

我有一个主密钥,并希望将其多样化/派生为其他密钥(在 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

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

4

1 回答 1

0

您应该使用CKM_DES3_ECB_ENCRYPT_DATA而不是CKM_DES3_ECB.

奇怪的是,您没有收到错误,因为CKM_DES3_ECB不应允许密钥派生(请参阅 PKCS#11 v2.40 中的表 68)。

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

祝你的项目好运!


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

免责声明:我不是加密专家,所以请验证我的想法。

于 2019-09-24T21:54:27.450 回答