在Java加密库中,密钥有两种不同的表示形式 - Key
和KeySpec
。文档暗示两者之间存在差异 - KeySpec
是透明的' (无论那意味着什么),但没有方法,而Key
有一个getEncoded
方法。您打算使用KeyFactory
在两者之间进行转换(确实有getKeySpec
方法可以转换)。
但是,SecretKeySpec
同时实现Key
和KeySpec
!但是也有一个SecretKeyFactory
类,它不会继承KeyFactory
。
这一切让我彻底困惑。 Key
和KeySpec
之间有什么不同,SecretKeySpec
和SecretKeyFactory
如何进入呢?
答案 0 :(得分:5)
这里的透明意味着实现/扩展KeySpec
接口的所有类/接口都应该以独立于提供者的方式显示关于密钥的元数据。该元数据实际上从未在密钥的常见使用中实际使用(加密等),但仅在需要查看密钥的数学属性时使用。知道关于密钥的这种提供者独立数据可能很有用,例如,如果要从/向字节流生成密钥,如果密钥驻留在HSM上,则挂钩密钥,或者甚至找出密钥是否弱,如: / p>
DESKeySpec.isWeak(byte[] key, int offset)
无论您希望公开关于密钥的元数据都取决于您。 KeySpec
只是作为标记界面(标记界面设计模式)。
与使用KeySpec
的这种可能的内省相反,使用SecretKeyFactory
生成的密钥是“不透明的”,因为你无法获得完整数学(模数,指数,编码等)和其他(如上面提供的DESKeySpec
)关于密钥的元数据。
SecretKeySpec
是JCE用于从字节流生成密钥的开箱即用解决方案,因此它实现了Key
和KeySpec
- 以使用{{生成密钥提供1}},并使用KeySpec
使密钥可用。
答案 1 :(得分:4)
关键对象和关键规范(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接口定义的三种方法: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