使用Safenet HSM和Java解开RSA加密的AES密钥会泄漏解开的密钥

使用Safenet HSM和Java解开RSA加密的AES密钥会泄漏解开的密钥,java,pkcs#11,jce,hsm,Java,Pkcs#11,Jce,Hsm,我正在使用Safenet HSM(硬件安全模块)存储我的加密密钥,并尝试使用Java API和SunPKCS11打开使用RSA加密的密钥(AES/DES)。我希望安全地执行此操作,以便无法从HSM提取未包装的AES/DES密钥(就像RSA私钥值不可见一样)。但是,展开后,在HSM外部的关键点对象中可以看到展开关键点的值 这是我的密码: Key privateKey = keyStore.getKey("MyKeyId", keyStorePassword); Cipher cipher = C

我正在使用Safenet HSM(硬件安全模块)存储我的加密密钥,并尝试使用Java API和SunPKCS11打开使用RSA加密的密钥(AES/DES)。我希望安全地执行此操作,以便无法从HSM提取未包装的AES/DES密钥(就像RSA私钥值不可见一样)。但是,展开后,在HSM外部的关键点对象中可以看到展开关键点的值

这是我的密码:

Key privateKey = keyStore.getKey("MyKeyId", keyStorePassword);

Cipher cipher = Cipher.getInstance("RSA", "SunPKCS11-Safenet");
cipher.init(Cipher.UNWRAP_MODE, privateKey);
Key unwrappedKey = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
// At this point the unwrapped key is visible in the unwrappedKey object!
我怎样才能告诉代码不要泄露打开的钥匙?我是否必须在PKCS11配置文件中添加一些内容?我已尝试将以下选项添加到配置文件中,但似乎没有帮助:

attributes(*,CKO_SECRET_KEY,*) = {
  CKA_SENSITIVE=true
}
我不确定API是否期望在展开过程中显示密钥。如果是这样,我如何将这些密钥安全地导入HSM,以便无法从HSM中提取它们


我试着询问安全网支持团队,但他们无法回答为什么会发生这种情况。所以,在互联网上进行了大量的尝试和搜索之后,我在这里提出了这个问题。

如果你打开钥匙。。。你把钥匙拿回来。也就是说,解开钥匙会露出钥匙。如果您要求HSM打开钥匙,则它会按照您的要求进行操作

如果HSM支持此操作,则可能需要导入密钥。关于密钥导入的假设是,HSM了解为安全/保护/传输而包装密钥的格式

然后,它将为您执行展开,并将展开的密钥保存在其数据库中。然后,它可能会将钥匙作为手柄或不同包装的钥匙(即,使用其内部主钥匙包装)交还给您

在可比较的HSM之间移动密钥是导出/导入或备份/还原,具体取决于设备和设备对这些动词的理解


在不同供应商的HSM或不同密码系统之间移动密钥而不泄露秘密是一个有趣的练习

如果你在某处需要你的私钥,那么@某一点它会在内存中,因此很容易被读出。这里没有奇迹-因为你是用普通代码做的。。。使用java可以让我们调试代码变得更容易,对吗?@Antoniossss:我不熟悉HSM,也不熟悉OP使用的API,但一般来说,使用HSM作为加密提供程序的意义在于,您可以让它为您执行加密操作,而无需任何敏感密钥材料离开HSM的安全存储。基本上,这样做的方式是,Java crypto API实现不会直接存储任何密钥或执行任何加密操作;它应该只存储不透明的密钥标识符,并将Java API操作转换为HSM“使用密钥#1234解密此数据”或其他指令。@IlmariKaronen一个加密提供程序是,您可以让它为您执行加密操作,而无需任何敏感密钥材料离开HSM的安全存储。我不再读了——是的,这就是使用硬件加密设置的意义所在,但问题是,OP是在客户端应用程序端对其进行解密,而不是在设备端,因此它没有按照设计使用它。他实际上是从加密存储中检索私钥的,他很惊讶它在JVM上。@Antoniossss当我检索私钥时,我只得到了对它的引用,而不是密钥的实际值。同样的行为,我期待为解开钥匙也。很抱歉,我没有得到您的声明OP是在客户端应用程序端解密它,而不是在设备端,因此它没有按设计使用它。请解释或提供一些链接。是的,解开密钥会暴露密钥值。现在考虑一下你需要在HSM里面做这件事。“展开”和“导入”步骤应为原子操作,这要求HSM固件支持开箱即用(限制将适用),或者您需要对操作进行编码,然后在HSM上作为自定义固件运行。