给定一个 java.security.interfaces.RSAKey,如何获取它的大小?
你可以尝试这样做:
key.getModulus().bitLength();
恕我直言,当模数的最高有效位为0时,key.getModulus().bitLength()
不会返回正确的值吧? 例如,对于2048位密钥,如果模数的最高有效位为0,则key.getModulus().bitLength()
将返回2047(如果更多位是0,则返回更少)。在这种情况下,我认为期望的结果实际上应该是2048。
BigInteger.bitLength()的文档如下:
返回此BigInteger最小二进制补码的位数,不包括符号位。对于正BigIntegers,这相当于普通二进制表示中的位数。(计算(ceil(log2(this < 0?-this:this +1)))。)
恐怕需要对密钥可能的大小作出一些假设。例如,您必须假设只会看到1024、2048或4096位的密钥,然后执行以下操作:
int keySize;
int bitLength = key.getModulus().bitLength();
if (bitLength <= 512) {
throw new IllegalArgumentException(...)
}
else if (bitLength <= 1024) {
keySize = 1024;
}
else if (bitLength <= 2048) {
keySize = 2048;
}
else if (bitLength <= 4096) {
keySize = 4096;
}
else {
throw new IllegalArgumentException(...)
}
return keySize;
有时候,即使是这段代码也可能出现错误(非常罕见),例如,当2048位密钥的前1048位全部为0时。不过我认为这并不是什么需要担心的问题。
key.getModulus().bitLength()
是由“密钥大小”或“密钥长度”术语定义的值。用任意选择的值替换它是完全错误的。 - Oleg EstekhinmyRSAKey.getModulus().bitLength()
来获取它的大小。我分享了在被接受的答案中提到的Wheezil的担忧。带有8个前导0位数的模数将会破坏这种方法。这种情况发生的概率是0.4%,在我看来是不可接受的。因此,我个人使用以下方法:
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, yourKey);
int keyBitSize = rsa.getOutputSize(0) * Byte.SIZE;
由于RSA输出大小始终与密钥模数相同,因此即使输入为0长度,输出的大小也相同。