Pycrypto: как просмотреть необработанные данные подписи RSA?

Я работаю со службой, которая использует необработанный RSA с закрытым ключом для подписи полезной нагрузки. Данные эффективно создаются с использованием:

openssl rsautl -inkey private_key.pem -raw -sign

(Также результат шифрования закрытым ключом)

К сожалению, в Pycrypto соответствующий метод .verify() принимает аргумент только для проверки данных, чтобы вернуть true или false.

В openssl это может быть достигнуто одним из следующих способов:

# Private key based
openssl rsautl -inkey private_key.pem -raw -verify
# Public key based
openssl rsautl -inkey public_key.pem -pubin -raw -verify

Как я могу добиться той же функциональности в Pycrypto?

(Я понимаю риски необработанного RSA. Для снижения некоторых из этих рисков был реализован специальный механизм заполнения. К сожалению, изменить текущую реализацию невозможно)


person Alastair McCormack    schedule 16.01.2018    source источник
comment
FWIW, можно получить доступ к библиотеке OpenSSL непосредственно в Python с помощью модуля ctypes. Тем не менее, вам нужно договориться о кроличьем лабиринте документации и заголовочных файлов OpenSSL. ;) Вот пример, показывающий, как таким образом выполнять некоторые простые задачи AES.   -  person PM 2Ring    schedule 16.01.2018
comment
спасибо @PM2Ring. Мне повезло, что я смог решить эту проблему с помощью нативного кода, но ваш пример — действительно хороший пример ctypes, который я обязательно буду использовать в будущем.   -  person Alastair McCormack    schedule 16.01.2018
comment
В заголовке есть слово "просмотр". Вы имели в виду "проверить"?   -  person President James K. Polk    schedule 17.01.2018
comment
Привет @JamesKPolk. Проблема в том, что я по сути хочу увидеть результат расшифровки подписи с помощью открытого ключа. Функция проверки Pycrypto не позволяет мне видеть результат, а только проверяет его на известное значение. В некоторых случаях я не знаю значения для проверки или просто хочу увидеть результат шифрования с закрытым ключом.   -  person Alastair McCormack    schedule 17.01.2018


Ответы (1)


Углубившись в метод .verify(), можно узнать, как Pycrypto создает проверочную подпись, прежде чем сравнивать ее с заданной требуемой подписью.

По сути, он использует метод Python pow() с открытым ключом (e) и модулем ключа (n). Сначала вам нужно будет упаковать секретное сообщение в (длинное) целое число, а затем преобразовать результат обратно в байты. К счастью, Pycrypto предоставляет все необходимое.

from Crypto.PublicKey import RSA
from Crypto.Util import number

key = RSA.importKey(private_key_str, key_password_str)

# The message must be packed as a long first.
secret_message_long = number.bytes_to_long(secret_message_bytes)
# The magic!        
verify_long = pow(encrypted_session_key_long, key.e, key.n)
# and back to bytes
verify_bytes = number.long_to_bytes(result_long)

# Convert message back to a str (Unicode str in Py2).
# Replace 'utf-8' with the correct encoding for *your* message!!!!!
verify_str = verify_bytes.decode('utf-8')
person Alastair McCormack    schedule 16.01.2018