我的问题涉及在 Java (openjdk 11.0.12) 中使用 hsm。Hsm 应该用于签名目的,通过 SHA512 RSA 算法。以下很多句子我可能是错的,我是 HSM & co 的新手,所以我提前道歉。
据我了解,有三种方法:
1- 使用 SUNPKCS11 提供程序
2-使用供应商库(hsm 附带几个 jar,在我的情况下,nCipher 附带 nCipherKM.jar,它应该是供应商提供者。)
3- openssl(我们有一些 c 软件已经这样做了,我宁愿避免)
供应商库的使用真的很容易,至少在 Get info 调用之前,它会向 HardServer 发送一个未知参数,从而导致不可编组的异常。这很难调试,通信协议没有记录。现在我已经把这个解决方案放在一边。
无论如何,我更喜欢 SUNPKCS11 解决方案,它对我来说不是开箱即用的,但它易于调试和分析。并且应该是一个标准。
在这种情况下,我使用欧洲 DSS 库与 PKCS11Provider 进行交互,这让我的配置和实现变得更简单。
在 SunPKCS11 (vanilla) 初始化期间会出现此问题。
根据代码和 Oracle 文档,在某些时候它调用一个方法“P11Keystore.mapLabels()”,该方法匹配来自该插槽的所有私钥处理程序 (CKA_PRIVATE_KEY) 与证书处理程序 (CKO_CERTIFICATE),按顺序查找 cka_id 之间的匹配使用包含 CKA_LABEL 属性的别名映射在内存密钥库中构建软件。(私钥是不可提取的,所以访问是只读的https://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#KeyStoreRestrictions)
在签名初始化中,此私钥条目用于从 HSM(通过一些我没有的密钥属性)获取私钥处理程序。
问题是我的 hsm nCipher 没有为 CKO_CERTIFICATE 公开任何对象,因此匹配返回 0 结果并且我的软件密钥库为空。
当我尝试从密钥库中提取私钥处理程序时,我什么也得不到,也无法初始化 Signature 对象。
我的前任手动将私钥属性包装在本地 jks 中,并重写了一个新的提供程序,以便从文件而不是从 HSM/PKCS11 加载证书。
我不喜欢这个解决方案,我不希望我的应用程序根据 HSM 证书进行配置。处理这些密钥是 HSM 证书工作,而不是我的。
相反,我编写了另一个提供程序来直接从 CKA_PRIVATE_KEY 获取和使用私钥处理程序,使用预配置的 CKA_LABEL,绕过证书匹配。它有效。
但是我也不喜欢这种解决方案,这意味着标准协议的维护成本更高,并且每次都必须对 jar 进行签名,这对我来说很麻烦。
我觉得我从错误的角度来处理问题,也许是因为我在这件事上是个菜鸟。
解释已经结束,所以我的问题是:1-声称 CKO_CERTIFICATE 是 SunPKCS11 的先决条件我错了吗?1- HSM 可以/应该在没有恶意副作用的情况下公开 CKO_CERTIFICATE 对象吗?2- 这个丢失的对象是 nCipher HSM 的限制,还是可能是安装过程中丢失的配置?(即使没有它也可以工作,因此它是一个 Java 先决条件,而不是 HSM 缺失) 3- 如果 CKO_CERTIFICATE 无法安装和公开:是否可以实现我们自己的提供程序来获得解决方法,或者可以存在更好的方法来让它工作?
对不起我的英语,我不是本地人。感谢那些来到这里阅读并回答的人。