密钥和密钥规范之间有什么区别?

2022-09-04 22:19:37

在 Java 加密库中,密钥有两种不同的表示形式 - KeyKeySpec。文档暗示两者之间存在差异 - a是“透明的”(无论这意味着什么),但没有方法,而有一个方法。你打算使用KeyFactory在两者之间进行转换(它确实有一种转换方法)。KeySpecKeygetEncodedgetKeySpec

但是,同时实现 和 !但是还有一个类,它不会继承掉 。SecretKeySpecKeyKeySpecSecretKeyFactoryKeyFactory

所有这一切让我彻底困惑。a 和 a 之间有什么区别,以及如何进入它?KeyKeySpecSecretKeySpecSecretKeyFactory


答案 1

这里的透明意味着所有实现/扩展接口的类/接口都应该以独立于提供程序的方式显示有关密钥的元数据。此元数据实际上从未用于密钥的常见用途(加密等),而仅在需要查看密钥的数学属性时使用。了解关于密钥的此类独立于提供程序的数据可能很有用,例如,如果您想从/到字节流生成密钥,如果密钥驻留在HSM上,则挂接密钥,甚至找出密钥是否较弱,例如:KeySpec

DESKeySpec.isWeak(byte[] key, int offset)

无论您要公开有关密钥的任何元数据都取决于您。 只是充当标记接口(标记接口设计模式)。KeySpec

与 这种可能的内省相反,使用 生成的密钥是“不透明的”,从某种意义上说,您无法获得有关密钥的完整数学(模数,指数,编码等)和其他(如果像上面那样提供)元数据。KeySpecSecretKeyFactoryDESKeySpec

SecretKeySpec另一方面,JCE的开箱即用解决方案,用于从字节流生成密钥,因此它实现了和 - 使用提供的生成密钥,并使用使密钥可用。KeyKeySpecKeySpecKey.getEncoded()


答案 2

关键对象和关键规范 (KeySpecs) 是密钥数据的两种不同表示形式。

密码使用 Key 对象来初始化其加密算法,但密钥可能需要转换为更易于移植的格式以进行传输或存储。

键的透明表示意味着您可以通过相应规范类中定义的 get 方法之一单独访问每个键材料值。

For example, DSAPrivateKeySpec defines getX, getP, getQ, and getG methods, to access the private key x, and the DSA algorithm parameters used to calculate the key(the prime p, the sub-prime q, and the base g). 

如果密钥存储在硬件设备上,则其规范可能包含有助于识别设备上的密钥的信息。此表示形式与由 Key 接口定义的不透明表示形式形成对比,在该表示形式中,您无法直接访问密钥材料字段。换句话说,“不透明”表示形式使您可以有限地访问Key - 只有Key接口定义的三种方法:getAlgorithm,getFormat和getEncoded。

可以以特定于算法的方式指定密钥,也可以以独立于算法的编码格式(如 ASN.1)指定密钥。

For example, a DSA private key may be specified by its components x, p, q, and g (eg: DSAPrivateKeySpec), or it may be specified using its DER encoding (eg: PKCS8EncodedKeySpec).

KeyFactory 和 SecretKeyFactory 类可用于在不透明和透明密钥表示形式之间进行转换,即在 Keys 和 KeySpecs 之间进行转换。

参考和更多详细信息,请访问: https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#KeySpecs


推荐