У меня есть модуль и частный показатель. Как построить закрытый ключ RSA и подписать сообщение?


Я новичок в криптографии и pycrypto.

У меня есть модуль n и частные экспоненты d. Из того, что я понял после прочтения некоторых документов закрытый ключ состоит из n и d.

Мне нужно подписать сообщение, и я не могу понять, как это сделать с помощью pycrypto. RSA.construct() метод принимает кортеж. Но я должен дополнительно предоставить публичный показатель e этому методу (которого у меня нет).

Так вот мой вопрос. Должен ли я вычислять e как-то для того, чтобы подписать послание?

Кажется, я должен быть в состоянии подписать сообщение, просто используя n и d (которые составляют закрытый ключ). Я не ошибаюсь? Могу ли я сделать это с pycrypto?

Заранее благодарю.

3 7

3 ответа:

На самом деле для расшифровки сообщения, зашифрованного открытым ключом, достаточно иметь частный экспонент.

Это также означает, что вы можете подписать сообщение, потому что подпись в основном просто *де*шифрует открытый текст с помощью закрытого ключа, который, когда *en*зашифрован с помощью открытого ключа, снова даст открытый текст. Обычно вы используете хэш-дайджест в открытом тексте до этого и подписываете его...

Причина, по которой вы не можете расшифровать сообщение, содержащее только n и d с pyrcypto, заключается в том, что оно Шагослепления во время расшифровки сообщения, которыйвключает в себя публичный показатель , но на самом деле не нужен для расшифровки.

Но с помощью некоторых вызовов приватного API этот шаг можно обойти.

Поэтому это должно работать:

from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long, long_to_bytes

full = RSA.generate(2048)

# construct key using only n and d
try:
    # pycrypto >=2.5, only tested with _slowmath
    impl = RSA.RSAImplementation(use_fast_math=False)
    partial = impl.construct((full.n, 0L))
    partial.key.d = full.d
except TypeError:
    # pycrypto <=2.4.1
    partial = RSA.construct((full.n, 0L, full.d))   



pub = full.publickey()

# create message with padding
# http://en.wikipedia.org/wiki/RSA_%28algorithm%29#Padding_schemes
cleartext = ...

signature = partial.sign(cleartext, None)

print "validating message: ", pub.verify(cleartext, signature)


message = pub.encrypt(cleartext, None)

# bypassing the blinding step on decrypt
enc_msg=map(bytes_to_long, message)
dec_msg = map(partial.key._decrypt, enc_msg)

print "decrypting: "
for m in dec_msg:
    print long_to_bytes(m)

Нет, вы не можете вычислить e из d.

RSA симметричен в d и e: вы можете одинаково хорошо обмениваться ролями открытого и закрытого ключей. Конечно, мы специально выбираем одно, чтобы быть частными, и раскрываем другое-но теоретически они делают то же самое. Естественно, поскольку вы не можете вывести закрытый ключ из открытого, вы также не можете вывести открытый ключ из частного.

Конечно, если у вас есть закрытый ключ, это означает, что Вы сгенерировали пару ключей, что означает, что у вас где-то есть открытый ключ.

Если у вас нет публичного экспонента, вы можете догадаться об этом. В большинстве случаев это не случайное простое число, а статическое значение. Попробуйте значения 65537 (шестнадцатеричное 0x010001, четвертое число Ферма), 3, 5, 7, 13 и 17 (в таком порядке).

Просто войдите с помощью закрытого ключа и проверьте с помощью открытого ключа, чтобы увидеть, является ли открытый ключ правильным.

Примечание: если это случайное простое число, его так же трудно найти, как и частный показатель; это означает, что вы попытаетесь сломать RSA-не вероятно, для любых размеров ключа > 512 бит.