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

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

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

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

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

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

Заранее спасибо.

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 (hex 0x010001четвертое число Ферма), 3, 5, 7, 13 и 17 (в таком порядке).

[РЕДАКТИРОВАТЬ] Просто подпишите с закрытым ключом и проверьте с открытым ключом, чтобы увидеть, является ли открытый ключ правильным.

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

Другие вопросы по тегам