1

我正在尝试使用具有某些属性的 SUNpkcs11 通过 ECDH 生成共享密钥:

CKA_TOKEN= false
CKA_SENSITIVE=true
CKA_EXTRACTABLE=true"
CKA_ENCRYPT=true"

虽然我的基本密钥已将 CKA_DERIVE、SENSITIVE 等设置为 true,但这样做时会出现模板不一致的错误:

Performing ECDH key agreement
java.security.ProviderException: Could not derive key
    at sun.security.pkcs11.P11ECDHKeyAgreement.engineGenerateSecret(P11ECDHKeyAgreement.java:144)
    at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:586)

Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_SENSITIVE
    at sun.security.pkcs11.wrapper.PKCS11.C_GetAttributeValue(Native Method)
    at sun.security.pkcs11.P11ECDHKeyAgreement.engineGenerateSecret(P11ECDHKeyAgreement.java:139)

而 ECC 密钥是使用 HSM 预先生成的。

4

1 回答 1

0

SunPKCS11P11ECDHKeyAgreement类总是希望返回派生共享密钥的字节作为 generateSecret() 方法的结果。为了做到这一点,必须将派生的秘密标记为非敏感和可提取的,否则 HSM 将拒绝透露原始字节。这就是CKR_ATTRIBUTE_SENSITIVE错误消息的含义 - Java 尝试访问派生密钥的原始字节,但它被标记为敏感。

JavaKeyAgreement类确实支持将返回Keyobject的 generateSecret() 版本,但您必须传递算法字符串"TlsPremasterSecret"(其他任何内容都将被 P11ECDHKeyAgreement 类拒绝)。这通常会停止密钥的使用,因为当您尝试使用它时,它会因为算法错误而被拒绝。(更不用说这个密钥是原始共享密钥,它应该在用作加密密钥之前通过 KDF/散列传递)。

因此,您唯一的选择是通过在 PKCS#11 配置文件中添加如下行来将派生密钥标记为非敏感和可提取:

attributes(generate,CKO_SECRET_KEY,CKK_GENERIC_SECRET) = {
  CKA_SENSITIVE = false
  CKA_EXTRACTABLE = true
}
于 2019-04-16T19:23:41.500 回答