PublicKey/PrivateKey 和 RSAPublicKey/RSAPrivateKey 有什么区别?

What are the differences between PublicKey/PrivateKey and RSAPublicKey/RSAPrivateKey?

RSAPublicKeyPublicKey 在 Java 中的主要区别是什么?我也在问 RSAPrivateKeyPrivateKey 的相同问题。

PublicKey/PrivateKey 是一些使用密钥对的算法的密钥,没有指定算法是什么。

他们与 RSA 相关的同行是他们对 RSA 算法的专长。例如,RSAPublicKeyPublicKey 中缺少 getPublicExponent() 方法。

在实践中,你可以使用这个规则:如果你确定你只会使用RSA,那么使用RSAPublicKey/RSAPrivateKey;否则,使用 PublicKey/PrivateKey.

class 的实例,例如 CipherSignature 通常会在编译期间接受任何 PublicKeyPrivateKey 实例作为它们的初始化方法。然而,密钥的类型应该与实现的算法相匹配。这是在运行时检查的,如果密钥和算法不匹配,则会导致 InvalidKeyException

这使得可以更轻松地在算法之间切换,如果需要,即使在运行时也是如此。因此,无论使用何种算法,大部分代码都可以实现,至少在需要特定键类型的操作之前是这样。


请注意 RSAPublicKey 扩展了 PublicKey 并且两者都是 Java 接口。通常,如果您需要接口提供的其他方法,您应该只使用 RSAPublicKey。这种情况不应该经常出现;对于加密操作,PublicKey 通常就足够了。

然而,有时您需要更多信息,例如密钥大小(RSA 情况下的模数大小)或以不同于默认编码提供的方式对密钥进行编码。在那种情况下,您需要直接使用更高级别的接口。


KeyFactoryKeyPairGenerator工厂classes只是输出PublicKeyPrivateKey,后者通过输出通用KeyPair间接实例。如果您需要其他方法,则需要将 cast public 密钥转换为 RSA public 密钥:

RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

如果您不确定获得的密钥类型,您首先需要使用 instanceof:

验证类型是否正确
if (publicKey instanceof RSAPublicKey) {
    RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
}

或者您应该愿意赶上接下来的 ClassCastException


加密提供程序,根据Java密码体系结构实现,提供这些接口的实际实现。

这解释了这些接口的另一种用途:只要底层密码 material 例如模数和指数可以被检索到,它 可能 创建一个使用一个提供者的密钥或密钥对,并在另一个提供者中使用它。如果检索模数和指数的接口没有标准化,这将是不可能的。

当您尝试检索私有指数或其他私有密钥时,基于硬件的提供程序(智能卡、HSM)通常会抛出异常 material。这是因为密钥一般不会离开硬件设备;您只能使用指定的提供商在设备本身上执行 RSA 操作。

无法在其他 Cipher 实现中使用这些键。 Java 因此包含 "delayed provider selection" 以确保在实例化期间未明确指定正确的提供者时选择正确的提供者 - 例如 - Cipher.getInstance(String algorithm)。而是在初始化期间选择提供者。


RSAPrivateCrtKey 是一个再次扩展 RSAPrivateKey 的接口。此 class 包含对执行使用中国剩余定理 (CRT) 的更快计算所需的参数的访问。通常您也不需要访问这些参数。