web-dev-qa-db-ja.com

PyCryptoでRSA公開鍵を使用して復号化します

私が理解している限り、RSAを使用して、必要に応じて信頼性またはプライバシーを確​​保できるはずです。私の場合、信頼性を確保したいので、データを秘密鍵で暗号化し、誰でも公開鍵で復号化できるようにします。データは実際には秘密ではありませんが、公開(および秘密)鍵の所有者によって作成されたことを保証する必要があります。

PyCryptoを使用して復号化しようとすると、PyCryptoから秘密鍵なしエラーが発生します。コードは次のとおりです。

def _decrypt_rsa(decrypt_key_file, cipher_text):
    from Crypto.PublicKey import RSA
    from base64 import b64decode

    key = open(decrypt_key_file, "r").read()
    rsakey = RSA.importKey(key)
    raw_cipher_data = b64decode(cipher_text)
    decrypted = rsakey.decrypt(raw_cipher_data)
    return decrypted

公開鍵ファイル(OpenSSH形式)へのパスを使用して呼び出しています。暗号化されたデータは私が生成したものではなく、PythonではなくPHPで生成されました。 PHPには、このデータを簡単に復号化するopenssl_public_decrypt関数があります。

PyCryptoで公開鍵を使用して復号化することはまったく可能ですか?

7
sergiopereira

パディングなしで生のRSAを使用しているため、これは完全に安全ではありません。

アプリケーションには署名が必要なので、暗号化や復号化を扱うべきではありません。たとえば、署名は信頼性を証明したいものに追加する必要のあるデータですが、PKCS#1v1.5は優れたプロトコルです。

PythonでPKCS#1 v1.5署名を検証するには、次のようにします。

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA

rsa_key = RSA.importKey(open(verification_key_file, "rb").read())
verifier = PKCS1_v1_5.new(rsa_key)
h = SHA.new(data_to_verify)
if verifier.verify(h, signature_received_with_the_data):
    print "OK"
else:
    print "Invalid"

PHPコードを変更して、そのような署名を作成することを強くお勧めします。

あなたの機能は正しいです。公開鍵の代わりに復号化するには、秘密鍵へのパスを指定する必要があります。公開鍵は暗号化用、秘密鍵は復号化用です。

def _decrypt_rsa(decrypt_key_file, cipher_text):
    '''
    Decrypt RSA encrypted package with private key
    :param decrypt_key_file: Private key
    :param cipher_text: Base64 encoded string to decrypt
    :return: String decrypted
    '''
    from Crypto.PublicKey import RSA
    from base64 import b64decode

    key = open(decrypt_key_file, "r").read()
    rsakey = RSA.importKey(key)
    #optionally could use OAEP
    #from Crypto.Cipher import PKCS1_OAEP
    #rsakey = PKCS1_OAEP.new(rsakey)
    raw_cipher_data = b64decode(cipher_text)
    decrypted = rsakey.decrypt(raw_cipher_data)
    return decrypted
0
jchysk