M2Crypto について質問です。
発生している問題
RSA.load_key(), X509.load_cert() などでパスフレーズを求められた場合、必ず復号に失敗します。
Linux, Mac どちらも同様の挙動でした。
例:
bash
1# 秘密鍵を作成 2$ openssl genrsa -aes128 -out privkey.pem
python3
1rsa = RSA.load_key('privkey.pem') 2Enter passphrase: 3RuntimeError: Result of callback is not bytes(). 4 5The above exception was the direct cause of the following exception: 6 7Traceback (most recent call last): 8 File "<stdin>", line 1, in <module> 9 File "/usr/lib64/python3.6/site-packages/M2Crypto/RSA.py", line 376, in load_key 10 return load_key_bio(bio, callback) 11 File "/usr/lib64/python3.6/site-packages/M2Crypto/RSA.py", line 393, in load_key_bio 12 rsa = m2.rsa_read_key(bio._ptr(), callback) 13SystemError: <built-in function rsa_read_key> returned a result with an error set
調べたこと
コードを追ってゆくと、RSA.load_key() に callback を指定しない場合
util.passphrase_callback() が呼ばれ入力されたパスフレーズがstr型として m2.rsa_read_key() に渡されます。
python3
1def load_key_bio(bio, callback=util.passphrase_callback): 2 ... 3 rsa = m2.rsa_read_key(bio._ptr(), callback)
しかし m2.rsa_read_key は callback の戻り値をbytes型として扱っていました。
上記で出ているエラー文とも合致しています。
c
1_m2crypto_wrap.c 2int passphrase_callback(char *buf, int num, int v, void *arg) { 3 ... 4 /* PyEval_CallObject sets exception, if needed. */ 5 ret = PyEval_CallObject(cbfunc, argv); 6 ... 7 if (!PyBytes_Check(ret)) { 8 PyErr_SetString(PyExc_RuntimeError, 9 "Result of callback is not bytes().");
入力したパスフレーズを bytes で返せば良いので、例えばこのような回避は可能です。
python3
1RSA.load_key('privkey.pem', lambda *_: util.passphrase_callback(*_).encode())
これは M2Crypto の不具合でしょうか?
あるいは、私の使い方が誤っているのでしょうか?
ご存知の方おりましたら、アドバイスいただけると助かります。
よろしくお願いいたします。
確認環境
・Gentoo Linux
Python 3.6.5, dev-python/m2crypto-0.31.0-r2
・Mac OSX
Python 3.7.3, pip M2Crypto 0.35.2
あなたの回答
tips
プレビュー