sunpkcs11 是否支持使用 ECDH 的派生密钥的 CK_sensitive 属性

do sunpkcs11 supports CK_sensitive attribute for derived key using ECDH

我正在尝试使用具有某些属性的 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 预先生成的。

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

JavaKeyAgreementclass确实支持version of generateSecret() that will return a Key object,但是你必须传递算法字符串"TlsPremasterSecret"(任何其他都会被拒绝P11ECDHKeyAgreement class)。这通常会阻止密钥的使用,因为当您尝试使用它时,它会因为算法错误而被拒绝。 (更不用说这个密钥是原始共享密钥,在用作加密密钥之前确实应该通过 KDF/hash 传递)。

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

attributes(generate,CKO_SECRET_KEY,CKK_GENERIC_SECRET) = {
  CKA_SENSITIVE = false
  CKA_EXTRACTABLE = true
}