2009-10-15 3 views
3

это, наверное, вопрос с новичком. Я генерации пары ключей с Java:Java: Почему 512-разрядный RSA KeyPairGenerator возвращает 65 байтовых ключей?

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); 
keyGen.initialize(512, random); 

KeyPair keyPair = keyGen.genKeyPair(); 

RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); 

Теперь я всегда думал, что privateKey.getModulus() и privateKey.getPrivateExponent() образуют «закрытый ключ», и что они являются столь же большим, как KeySize (512 бит) передается генератору ключей.

Однако privateKey.getPrivateExponent(). ToByteArray() иногда возвращает 64-байтный (как я ожидал), иногда массив из 65 байтов.

Почему иногда 65 байт? Я что-то упустил?

+0

512 = количество бит в ключе. 512/8 = 64 байта. Не уверен, почему вы получаете 65 байтов назад, хотя ... –

ответ

10

getPrivateExponent() возвращает BigInteger и toByteArray() метод возвращает массив байтов, который всегда включает в себя бит знака. Если установлен самый старший бит в показателе 512 бит, BigInteger добавит дополнительный 513-й бит, чтобы указать, что число положительное, а не 511-битное отрицательное число с 512-битным битом, установленным в 1. Для 513 бит 65 байтов необходимых для кодирования.

Если посмотреть на содержимое возвращаемого массива байтов, то первый байт всегда будет 0, если вы получаете массив 65 элементов.

+0

лол, думаю, мы находимся на той же странице здесь, вы просто бить меня к нему с 1 минуту :) – Abel

+0

ТНХ, это было быстро :-) * МРВ * Я думаю, извините ... – wilth

+0

Это происходит не только в Java (из-за подписки BigInteger), но также и в формате ASR.1 DER по аналогичным причинам (из-за подписки на INTEGER ASN.1). – lapo

-1

8 * 64 = 512?

Edit: Мое плохое, не видел сделку между 64 и 65, на самом деле, хороший вопрос.

+0

Да, правильно :-) Моя точка зрения: почему параметры (private exp, mod) _sometimes_ 65 байтов? – wilth

2

Здесь a little story on RSA, что объясняет, что длина ключа не всегда то, что вы думаете, то есть, она рассчитывается из его наиболее значащего бита вперед. Однако он не должен превышать 512 бит, поскольку это максимальная длина ключа. История касается предполагаемой длины ключа, не обязательно длины ключа в реализациях.

getPrivateExponent возвращает BigInteger. getPrivateExponent().toByteArray() возвращает представление двух дополнений BigInteger. Подписан A BigInteger. 512 бит (64 байта) не подписаны. Это означает: если самый старший бит установлен (бит знака), чтобы сделать его неподписанным, то BigInteger необходимо поместить один байт, чтобы сделать его соответствующим. Если вы посмотрите на байты, вы обнаружите, что добавленный байт всегда равен нулю.