Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the size of a RSA key in Java

Tags:

java

rsa

Given an java.security.interfaces.RSAKey, how do I get it's size?

like image 595
The Student Avatar asked May 27 '10 15:05

The Student


4 Answers

I share Wheezil's concerns mentioned in the accepted answer. A modulus with 8 leading 0-bits will break the approach. This has a 0.4% chance of occurring, which is unacceptable in my opinion. So I personally use this instead:

Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, yourKey);
int keyBitSize = rsa.getOutputSize(0) * Byte.SIZE;

...since RSA output size is always the same size as the key's modulus, even with 0-length input.

like image 151
Glenn Lane Avatar answered Nov 12 '22 04:11

Glenn Lane


You could try this:

key.getModulus().bitLength();
like image 26
David M Avatar answered Nov 12 '22 04:11

David M


(EDIT: I wrote this response before I understood the restrictions placed on the prime integers that are generated for an RSA key. http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf I now believe that any good key generator should ensure that the modulus is between 2^(n-1) and 2^n-1. Thus the minimal two's-complement representation of the modulus will always have exactly the number of bits that were specified for the key length at the time of key creation. So, for example, if you create a 2048-bit key, then key.getModulus().bitLength() will always return 2048.)

Pardon, but doesn't key.getModulus().bitLength() return an incorrect value when the most significant bit of the modulus is a 0? For example, for a 2048-bit key, if the most significant bit of the modulus is 0, then key.getModulus().bitLength() will return 2047 (or less if more bits are 0). I would think the desired result in such a case would actually be 2048.

The documentation for BigInteger.bitLength() reads as follows:

Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. (Computes (ceil(log2(this < 0 ? -this : this+1))).)

I am afraid that one needs to make some assumptions about what sizes the key could be. You'll have to assume, for example, that you will only ever see 1024, 2048, or 4096-bit keys and then do something like:

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;

This code can still be wrong on the (VERY rare) occasion, for example, when the first 1048 bits of a 2048 bit key are all 0. I think that is not something to worry about, though.

like image 5
John L Avatar answered Nov 12 '22 04:11

John L


The size of an RSA key is the number of bits in its modulus, so you want myRSAKey.getModulus().bitLength().

like image 4
Jacob Mattison Avatar answered Nov 12 '22 03:11

Jacob Mattison