本来なら Python だけで PuTTYgen で作成したRSA鍵ファイル (*.ppk) を読み込んで
Python crypto が使用できるRSA公開鍵、RSA秘密鍵を取り出したかったのですが、
秘密鍵を抽出するもの puttykeys · PyPI しか見つからず、
公開鍵を抽出するものが欲しかったのですが、見つからない。
もちろん *.ppk を単純に読んで "Public-Lines: " から行数取得して公開鍵の行を読んだだけで
そのまま使用できるわけない。
そこで、前回投稿のとおり、Java で ppk ファイルを読込み、Python が公開鍵と秘密鍵を使用できるように
ファイルに、Base64エンコードして書き出しておいて使用する。
Base64エンコードさえ、気をつければ、OpenSSL RSA の暗合複合と同様に、
pycryptodome をインストールした環境で Python でも Putty の RSA 暗合複合が実現できる。
Putty 用と、OpenSSL 用を書き並べてみる。Base64エンコード結果のキーを使う点が差になる。
ppk Java → 公開鍵抽出 → Python 公開鍵で暗合化
def rsa_encrypt(plane): from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from base64 import b64encode from base64 import b64decode with codecs.open('puttypub.txt', 'r', 'utf-8') as f: pbkey = f.read() key = RSA.importKey(b64decode(pbkey)) cipher = PKCS1_v1_5.new(key) return b64encode(cipher.encrypt(bytes(plane, 'utf-8'))).decode('utf-8')
def rsa_encrypt(plane): with open("public_key.der", "rb") as f: from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from base64 import b64encode key = RSA.importKey(f.read()) cipher = PKCS1_v1_5.new(key) return b64encode(cipher.encrypt(bytes(plane, 'utf-8'))).decode('utf-8')
OpenSSL の公開鍵は、元からバイナリで読めない。
ppk Java → 秘密鍵抽出 → Python 秘密鍵で複合
def rsa_decrypt(enctxt): from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from base64 import b64encode from base64 import b64decode with codecs.open('privatekey.txt', 'r', 'utf-8') as f: key = RSA.importKey(b64decode(f.read())) cipher = PKCS1_v1_5.new(key) text = cipher.decrypt(b64decode(enctxt), "Error while decrypt") return text.decode('utf-8')
def rsa_decrypt(enctxt): with open('private_key.pem','r') as f: from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from base64 import b64decode pemkey = b64decode(f.read().replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("-----END RSA PRIVATE KEY-----", "").replace("\n", "")) rsakey = RSA.importKey(pemkey) cipher = PKCS1_v1_5.new(rsakey) text = cipher.decrypt(b64decode(enctxt), "Error while decrypt") return text.decode('utf-8')
Java ー Pthon 間の RSA 暗合複合は、Base64 エンコードが使えるのは、
OpenSSL RSA でも、Putty ssh-2 - RSA でも上記に従えば、可能だ。