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

4
我正在使用Safenet HSM(硬件安全模块)来存储我的加密密钥,并尝试使用Java API和SunPKCS11解密使用RSA加密的秘密密钥(AES / DES)。我希望能够安全地进行此操作,以使被解密的AES / DES密钥无法从HSM中提取(就像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中,以便它们无法从中提取?我已经尝试向Safenet支持团队询问,但他们无法回答为什么会发生这种情况。因此,在尝试和搜索互联网很多之后,我在这里提出了这个问题。

1
@Antoniossss:我对OP使用的HSM和API都不熟悉,但通常使用HSM作为加密提供者的目的是让它为您执行加密操作,而不会有任何敏感密钥材料离开HSM的安全存储。基本上,这个应该的工作方式是Java加密API实现不直接存储任何密钥或执行任何加密操作;它应该只存储不透明的密钥标识符,并将Java API操作转换为指示HSM“使用#1234密钥解密此数据”等的指令。 - Ilmari Karonen
@IlmariKaronen 加密提供程序的作用是,您可以让它为您执行加密操作,而无需将任何敏感密钥材料离开HSM的安全存储。 我在那里停止阅读 - 是的,这就是使用硬件加密设置的目的,但问题在于,OP正在客户端应用程序上解密它,而不是在设备端上使用它,因此它没有按照设计使用。他从加密存储中检索私钥,然后惊讶地发现它在JVM上。 - Antoniossss
是的,我也尝试过那个,但没有起作用。 - snesh
当您包装密钥时,唯一的原因是将其移动到某个地方,以便随后解包以供使用。我在这里支持@Antoniossss - 我们没有足够的信息,并且从我们所拥有的信息来看,是的,您已经获得了您要求的内容 - 在解包后的密钥。1)包装的密钥来自哪里?它突然出现在您的提取中。2)在创建时,是否对“wrappedKey”应用了CKA_属性?当您将其包装时? - rip...
2
是的,解封密钥会暴露密钥值。现在考虑您需要在HSM内部执行此操作。"解封"和"导入"步骤应该是一个原子操作,这要求HSM固件支持此功能(将适用限制),或者您需要编写操作代码,然后将其作为自定义固件在HSM上运行。 - rip...
显示剩余7条评论
1个回答

0

如果您解包密钥...您会得到密钥。也就是说,解包密钥会暴露密钥。如果您要求HSM解包密钥,则它正在执行您告诉它要做的事情。

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

然后,它将为您解包,并将未包装的密钥保存在其数据库中。然后,它可以将密钥作为句柄或以不同方式包装的密钥(即使用其内部主密钥进行包装)交还给您。

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

在不暴露机密的情况下,在不同供应商的HSM或不同的加密系统之间移动密钥是一项有趣的练习。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接