我想知道是否有可能使用AES_CMAC机制进行密钥派生。
我有一个AES主密钥( key ),我想生成一个AES密钥: key2 = AES_CMAC( key,data)。当然,我只想得到key2的持有者,而不是值。
当我这样做的时候:
public long derive_key(long key, byte[] data, String label) {
long p_key = -1L;
CK_MECHANISM mec = new CK_MECHANISM();
mec.mechanism = PKCS11Constants.CKM_AES_CMAC;
SecretKey keyTemplate = new AESSecretKey();
fill(keyTemplate, label);
((AESSecretKey) keyTemplate).getValueLen().setLongValue(16L);
((AESSecretKey) keyTemplate).getValue().setByteArrayValue(data);
CK_ATTRIBUTE[] attr = iaik.pkcs.pkcs11.objects.Object.getSetAttributes(keyTemplate);
return cryptoki.C_DeriveKey(ckiSession, mec, key, attr, true);我得到CKR_MECHANISM_INVALID错误。
而且我不能使用cryptoki.C_Sign(...)因为它输出键值。
谢谢!
发布于 2021-02-10 09:00:19
CKM_AES_CMAC机制不能用于密钥派生(参见表here)。
在我看来,在不公开任何中间结果的情况下,通过标准的PKCS#11机制实现CMAC键派生是不可能的(请参阅下面的方法,该方法会将几个中间结果泄露给SW)。
考虑到CMAC works的方式,您没有办法执行子密钥派生(条件异或和逐位移位)和最后一个输入块调整。
在我看来,您有以下选择:
祝你的项目好运!
理论上,如果您不介意在SW中公开E(k,0)、子密钥和一个中间结果,您可以:
通过CKM_AES_ECB计算E(k,0)的
中计算子密钥
CKM_AES_MAC的输入数据块m_{1}..m_{n-1}的MAC
中使用适当的子密钥调整最后一个输入数据块m_{n} (如果块不完整,还要使用ISO 9797-1填充方法2
CKM_AES_CBC_ENCRYPT_DATA导出密钥,其中IV等于计算的CBC-MAC,数据等于调整后的最后一个块
不要这样做!(尽管这可能比在SW中做所有事情都要好)。
免责声明:我不是密码专家,所以请确认我的想法。
发布于 2021-05-29 00:45:10
PKCS#11确实定义了CKMSP800-108_COUNTER_KDF(以及_FEEDBACK_KDF和DOUBLE_PIPELINE_KDF),它允许您使用AES_CMAC作为底层算法。这能满足你的需求吗?可能还有其他密钥派生机制,让您也可以使用CMAC。
但一个更普遍的问题是,你试图实现什么目标。通常,派生是在具有附加要求的较大方案的要求之后完成的。如果您特别要求CMAC,我怀疑您还有其他要求需要满足?
https://stackoverflow.com/questions/66122396
复制相似问题