Как загрузить закрытый ключ, защищенный паролем, из файла.pem с помощью M2Crypto?

У меня есть защищенный паролем закрытый ключ в файле.pem; Я хочу использовать его для подписи запросов к удаленному серверу. Я могу загрузить ключ и ввести кодовую фразу после того, как его попросят:

python
>>> import M2Crypto
>>> pk = M2Crypto.RSA.load_key('private.pem')
Enter passphrase:
>>>

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

>>> def gimmepw():
...     return 'mysecret'
...
>>> pk = M2Crypto.RSA.load_key('private.pem', gimmepw)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/Plone/Python-2.4/.../M2Crypto/RSA.py", line 351, in load_key
    return load_key_bio(bio, callback)
  File "/usr/local/Plone/Python-2.4/.../M2Crypto/RSA.py", line 372, in load_key_bio
    rsa_error()
  File "/usr/local/Plone/Python-2.4/.../M2Crypto/RSA.py", line 302, in rsa_error
    raise RSAError, m2.err_reason_error_string(m2.err_get_error())
M2Crypto.RSA.RSAError: bad password read
>>>

(заменить "..." на "lib/python2.4/site-packages")

Что я делаю неправильно?

2 ответа

Решение

Это связано с отсутствием поддержки параметров в вашей функции обратного вызова. Как он будет вызываться хотя бы с одним параметром, TypeError возникнет исключение (которое отлавливается M2Crypto).

>>> def gimmepw(*args):
...     print 'args:', repr(args)
...     return 'test'
... 
>>> M2Crypto.RSA.load_key('key.pem', gimmepw)
args: (0,)
<M2Crypto.RSA.RSA instance at 0xb6e8050c>

Тебе стоит попробовать:

def gimmepw(*args):
    return 'mysecret'

Одно предупреждение: Начиная с Python 2.7, возвращаемое значение вашего callback метод должен вернуть str тип.

Например, unicode Тип выдаст ошибку таким же образом.

>>> def gimmepw(*args):
...     return u'test'
... 
>>> M2Crypto.RSA.load_key('key.pem', gimmepw)
Traceback (most recent call last):
  File "test_intuit_data.py", line 76, in <module>
    intuit_rsa_key = RSA.load_key(file='key.pem', callback=gimmepw)
  File "lib/python2.7/site-packages/M2Crypto/RSA.py", line 351, in load_key
    return load_key_bio(bio, callback)
  File "lib/python2.7/site-packages/M2Crypto/RSA.py", line 372, in load_key_bio
    rsa_error()
  File "lib/python2.7/site-packages/M2Crypto/RSA.py", line 302, in rsa_error
    raise RSAError, m2.err_reason_error_string(m2.err_get_error())
M2Crypto.RSA.RSAError: bad password read

Если вы используете какой-либо вход, кроме str типа, обязательно приведите к str соответственно:

>>> def gimmepw(*args):
...     return str(u'test')
... 
>>> M2Crypto.RSA.load_key('key.pem', gimmepw)
<M2Crypto.RSA.RSA instance at 0xb6e8050c>
Другие вопросы по тегам