「Python 暗号化」で調べると、pycryptoが出てきます。
でも、pycryptoはもう古すぎて使えません。
セキュリティ的にもおススメできません。
その代わりに、pycryptodomeを使いましょう。
本記事の内容
- pycryptodomeとは?
- pycryptodomeのシステム要件
- pycryptodomeのインストール
- pycryptodomeの動作確認
それでは、上記に沿って解説していきます。
pycryptodomeとは?
pycryptodomeは、データの暗号化・復号化を可能にするPythonライブラリです。
ただ、Pythonで暗号化と言えば、pycryptoの方が知名度があります。
知名度と言う点では、pycryptodomeはまだまだでしょう。
しかし、pycryptodomeはpycryptoの後継のようなモノです。
pycryptoは、すでに開発がストップしています。
2013年10月18日にpycrypto 2.6.1をリリースしたのが、最後となります。
そして、そのソースコードをフォークしたのがpycryptodomeです。
その意味で、pycryptodomeはpycryptoの後継ライブラリと言えます。
pycryptoはもう古すぎて、使うのは危険です。
もしかしたら、インストールすらできないかもしれません。
よって、pycryptoではなくpycryptodomeをインストールしましょう。
以上、pycryptodomeについての説明でした。
次は、pycryptodomeのシステム要件を確認します。
pycryptodomeのシステム要件
現時点(2021年7月)での pycryptodomeの最新バージョンは、3.10.1となります。
この最新バージョンは、2021年2月9日にリリースされています。
サポートOSに関しては、以下を含むクロスプラットフォーム対応となります。
- Windows
- macOS
- Linux
基本的には、OSは問わないということです。
そして、サポート対象となるPythonのバージョンは以下。
- Python 2.7
- Python 3.5
- Python 3.6
- Python 3.7
- Python 3.8
- Python 3.9
個人的には、これだけ幅広い対応には反対です。
基本的には、下記のPythonの公式開発サイクルに合わせるだけで十分だと思います。
バージョン | リリース日 | サポート期限 |
3.6 | 2016年12月23日 | 2021年12月 |
3.7 | 2018年6月27日 | 2023年6月 |
3.8 | 2019年10月14日 | 2024年10月 |
3.9 | 2020年10月5日 | 2025年10月 |
Python 2系と3系の両方をサポートする場合、互換性を保つ分だけコードは膨れ上がるでしょう。
セキュリティ的にも、それはよろしくないと思います。
もちろん、パフォーマンス的にも。
互換性という言葉の響きは、カッコイイです。
それにメリットもあるでしょう。
でも、同時にデメリットもあるということです。
以上、pycryptodomeのシステム要件についての説明でした。
次は、pycryptodomeをインストールしていきます。
pycryptodomeのインストール
最初に、Pythonのバージョンを確認しておきます。
>python -V Python 3.9.6
次に、現状のインストール済みパッケージを確認しておきます。
>pip list Package Version ---------- ------- pip 21.1.3 setuptools 57.0.0
次にするべきことは、pipとsetuptoolsの更新です。
pipコマンドを使う場合、常に以下のコマンドを実行しておきましょう。
python -m pip install --upgrade pip setuptools
では、pycryptodomeのインストールです。
pycryptodomeのインストールは、以下のコマンドとなります。
pip install pycryptodome
インストールは、すぐに終わります。
では、どんなパッケージがインストールされたのかを確認しましょう。
>pip list Package Version ------------ ------- pip 21.1.3 pycryptodome 3.10.1 setuptools 57.0.0
依存パッケージは、ゼロです。
その点では、pycryptodomeを容易に導入できます。
加えて、OSはクロスプラットフォーム、Pythonバージョンの制約もほぼナシです。
この対応力を良しとするかどうかという疑問は残りますが。。。
それがどうであれ、開発陣の努力には本当に感謝ですね。
以上、pycryptodomeのインストールについての説明でした。
最後は、pycryptodomeの動作確認を行います。
pycryptodomeの動作確認
pycryptodomeの動作確認は、次の3つの処理に分けられます。
- 秘密鍵・公開鍵の作成
- 公開鍵を使ったデータの暗号化
- 秘密鍵を使ったデータの復号化
それぞれを下記で説明します。
秘密鍵・公開鍵の作成
from Crypto.PublicKey import RSA # 秘密鍵の作成 key = RSA.generate(2048) private_key = key.export_key() file_out = open("private.pem", "wb") file_out.write(private_key) file_out.close() # 公開鍵の作成 public_key = key.publickey().export_key() file_out = open("public.pem", "wb") file_out.write(public_key) file_out.close()
秘密鍵と公開鍵をセットで作成します。
セットじゃないと意味がないですからね。
利用の場合は、必ずセットで作成された鍵を利用する必要があります。
上記コードを実行すると、次のファイルが作成されます。
- private.pem(秘密鍵)
- public.pem(公開鍵)
これらの鍵を使って、暗号化と復号化を検証していきます。
公開鍵を使ったデータの暗号化
一般的には、データの送信者が公開鍵を利用します。
渡された公開鍵を用いて、送りたいデータを暗号化することになります。
このことを実現するのが、次のコードです。
from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP data = "日本語で書かれた秘密のメッセージ".encode("utf-8") file_out = open("encrypted_data.txt", "wb") recipient_key = RSA.import_key(open("public.pem").read()) session_key = get_random_bytes(16) # セッションキーをRSA公開鍵で暗号化する cipher_rsa = PKCS1_OAEP.new(recipient_key) enc_session_key = cipher_rsa.encrypt(session_key) # データをAESセッションキーで暗号化 cipher_aes = AES.new(session_key, AES.MODE_EAX) ciphertext, tag = cipher_aes.encrypt_and_digest(data) [file_out.write(x) for x in (enc_session_key, cipher_aes.nonce, tag, ciphertext)] file_out.close()
公開鍵を使って、データを暗号化しています。
その暗号化されたデータは、encrypted_data.txtというファイルに保存されています。
もちろん、encrypted_data.txtの中身は以下のように暗号化されています。
秘密鍵を使ったデータの復号化
一般的には、データの受信者が秘密鍵を利用します。
秘密鍵を用いて、受け取ったデータを復号化することになります。
このことを実現するのが、次のコードです。
from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP file_in = open("encrypted_data.txt", "rb") private_key = RSA.import_key(open("private.pem").read()) enc_session_key, nonce, tag, ciphertext = \ [file_in.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)] # セッションキーをRSA秘密鍵で復号する cipher_rsa = PKCS1_OAEP.new(private_key) session_key = cipher_rsa.decrypt(enc_session_key) # データをAESセッションキーで復号する cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag) print(data.decode("utf-8"))
秘密鍵を使って、データを復号化しています。
上記のコードを実行すると、復号化されたデータが表示されます。
日本語で書かれた秘密のメッセージ
まとめ
秘密鍵・公開鍵のセットというのが、重要です。
これさえ注意すれば、簡単に暗号化・復号化が実現できます。
以上、pycryptodomeの動作確認について説明しました。