Pythonでのファイル暗号化:共通鍵暗号と公開鍵暗号を詳しく解説
Keshav Malik
2023年11月22日
0 分で読めます現代では、デジタルチャネルを通じて、プライベートな情報や機密情報、センシティブな情報を常に共有しています。こうしたやり取りを支える基本的な要素がファイル暗号化です。暗号化アルゴリズムを使って、データを読み取れない形式に変換します。
暗号化には、共通鍵暗号と公開鍵暗号の2つの主な方式があります。共通鍵暗号は、1つの鍵を使う鍵付きボックスのようなものです。2人がその鍵を持っていれば、鍵を持つ人だけが開けられると分かっているので、ボックスを安全に受け渡せます。一方、公開鍵暗号では2つの鍵を使います。片方の鍵で施錠できても、もう片方の鍵でしか開けられないボックスを想像してください。施錠する鍵(公開鍵)は安全に共有できます。開錠する鍵(秘密鍵)がなければ、誰もボックスを開けてデータを復号できないからです。
この記事では、Pythonでの暗号化について詳しく解説します。共通鍵暗号では、Amazon Key Management Service(KMS)とPyNaCl SecretBoxを取り上げます。続いて、公開鍵暗号とPyNaClの公開鍵・秘密鍵ボックスを見ていきます。
前提条件
このチュートリアルを進めるには、次のものが必要です。
Python(v3.7以降)がインストールされていること
pipenvがインストールされていること。このPython用依存関係管理ツールを使うと、パッケージのバージョン間の競合を回避できます。
pip install pipenvでインストールしてください。pipenv install aws-encryption-sdk pynacl cryptographyを実行し、必要なパッケージ(aws-encryption-sdk、PyNaCl、cryptography)をインストールすること。利用可能なAWSアカウントとKMSキー(後ほどPythonプログラムを実行するときに使うため、キーIDとAWSリージョンの情報を手元に用意してください)。
AWSコマンドラインツール(awscli)がインストールされていること。
aws configureを実行し、マシン上でAWSの設定を行います。次のコマンドを使って、分離された環境に新しいプロジェクトをセットアップすること。
完成形はプロジェクトの完全なコードをご覧ください。
Pythonでの共通鍵暗号
共通鍵暗号では、データの暗号化と復号に同じ鍵を使います。シンプルで高速かつ効率的なため、大量のデータの保護に適しています。
このチュートリアルでは、Amazon KMSとPyNaCl SecretBoxを使って、Pythonで共通鍵暗号を実装します。Amazon KMSを使うと、Amazon Web Services(AWS)クラウド上で暗号化キーを作成、制御、管理できます。セキュリティがさらに強化された、クラウド上のキーリングのようなものです。SecretBoxは、暗号化を手軽に利用できるPythonライブラリです。個人用の金庫のようなものと考えてください。
Amazon KMSと暗号化SDKを使った共通鍵暗号
Amazon KMSは、暗号鍵を管理するクラウドベースのサービスです。他のAWSサービスや暗号化ソフトウェア開発キット(SDK)とシームレスに連携し、AWSが提供する堅牢なセキュリティを活用します。AWSサービスや暗号化SDKとの緊密な統合により、AWSベースのアプリケーションに最適です。
共通鍵暗号にKMSを使う大きな理由は、共有する秘密鍵を管理できることです。こうした鍵を安全に取り扱うことは、暗号化で最も難しい課題になり得ます。Amazon KMSは、エンベロープ暗号化方式を採用することで、この課題を巧みに解決します。この方式では、データとともに鍵自体も暗号化されます。そのため、主にハードウェアセキュリティモジュール内のマスターキーに依存できます。このキーには、権限のないユーザーはアクセスできません。このキーラッピングの仕組みによって暗号化のプロセスが簡素化され、鍵の管理やローテーションなどに伴う複雑さを効果的に軽減できます。
ただし、シンプルで小規模なソリューションだけが必要な場合、Amazon KMSは不要かもしれません。また、有料サービスのため、利用量が多いとコストが膨らむ可能性があります。
それでは、Amazon KMSを使ってPythonアプリケーションでファイルを暗号化してみましょう。
必要なモジュールをインポートする
Amazon KMSを使うには、まずaws-encryption-sdkをインストールしてインポートします。これは、暗号化と復号のプロセスを簡素化するPython用AWS Encryption SDKです。
main.pyというファイルを作成し、次のコードを追加します。
注: KMSキーのARNは、AWS KMSダッシュボードからコピーできます。
ファイルを暗号化する
暗号化にはAWS Encryption SDKを使います。このSDKはAWS KMSと緊密に連携し、シームレスな暗号化を実現します。
次のコードをmain.pyに追加します。
ファイルを復号する
ファイルの復号にも、AWS Encryption SDKを使います。復号プロセスでは、暗号化されたファイルを読み込み、KMSキーを使ってデータをシームレスに復号します。
次のコマンドをmain.pyに追加します。
関数を呼び出す
関数を作成したので、次はそれらを呼び出してPythonプログラムを実行します。まずmyfile.txtというファイルを作成し、適当な内容を追加してください。
次に、main.py内で次の関数を呼び出します。
python main.pyを実行してスクリプトを動かすと、myfile.txtを暗号化してから復号するため、内容は変更されません。
注: 説明を簡潔にするため、コード内(キーARNの一部)にキーIDをハードコードしています。機密情報の保存には.envファイルを使用してください。
PyNaCl SecretBoxを使った共通鍵暗号
PyNaClは、ネットワークおよび暗号化ライブラリlibsodiumのPythonバインディングです。共通鍵暗号機能を提供するSecretBoxをはじめ、便利な暗号化ツールが豊富にそろっています。SecretBoxの魅力は、そのシンプルさにあります。データの暗号化と復号に使う鍵は1つだけです。
SecretBoxを使ってPythonアプリケーション内の機密ファイルを暗号化する方法を見ていきましょう。
まずnacl.txtファイルを作成し、仮のテキストを追加します。次に、sym.pyという名前で新しいPythonプログラムファイルを作成し、必要なモジュールをインポートします。
次に、秘密鍵を生成して読み込みます。generate_key関数はランダムな鍵を生成し、load_key関数はファイルパスから生成済みの鍵を読み込んで返します。
続いて、ファイルを暗号化します。encrypt_file関数は、機密ファイルを暗号化するためにfile_pathと鍵を必要とします。file_pathでファイルを特定し、内容を読み込んで秘密鍵を使って暗号化した後、暗号化されたテキストを拡張子.encの新しいファイルに書き込みます。
暗号化関数と同様に、復号関数も必要です。decrypt_file関数は、ファイルを復号するためにfile_pathとkeyを受け取ります。まず、暗号化された.encファイルが存在するか確認します(前の手順で生成済みです)。次に、その内容を読み込み、同じ秘密鍵を使って復号します。最後に、復号した内容を拡張子.decの新しいファイルに書き込みます。
最後に、作成した関数を呼び出します。
ターミナルでsym.pyコマンドを実行すると、Pythonプログラムを実行できます。
注: このコードは、実際のアプリケーションや本番環境で使える状態ではありません。暗号鍵を安全に取り扱うには、鍵を定期的にローテーションするなど、追加の手順が必要です。このコードには、こうした重要なセキュリティ対策が含まれていません。
Pythonでの公開鍵暗号
共通鍵暗号では鍵を1つ使うのに対し、公開鍵暗号では暗号化用の公開鍵と復号用の秘密鍵の2つを使います。鍵付きの郵便受けのようなものです。誰でも投入口から手紙を入れられます(暗号化)が、専用の鍵を持つ人だけが開けて手紙を読めます(復号)。
公開鍵暗号は、インターネット上での安全な通信に特に適しています。友人に秘密のメッセージを送りたい場合、相手の公開鍵で暗号化すれば、相手だけが自分の秘密鍵で復号できます。また、公開鍵暗号はデジタル署名や証明書を保護します。これらは、デジタル世界における認証の基盤です。
PyNaClの公開鍵・秘密鍵ボックスを使った公開鍵暗号
では、Pythonで公開鍵暗号を行うにはどうすればよいでしょうか。PyNaClの別のツール、公開鍵・秘密鍵ボックスを見ていきましょう。
PyNaClの公開鍵・秘密鍵ボックスは、個人用の郵便受けのようなものです。公開鍵と秘密鍵の2つを使ってメッセージを暗号化・復号するためのインターフェースです。メッセージの暗号化に使う公開鍵は、誰にでも共有できます。一方、復号に使う秘密鍵は、秘密にしておく必要があります。
まず、asym_nacl.txtファイルを作成し、テスト用のテキストを追加します。暗号鍵を安全に保存し、取り出せるようにする必要があります。save_key関数はfile_pathに鍵を書き込み、load_key関数はfile_pathから鍵を取得して返します。
新しいファイルasym.pyに、次のコードを追加します。
次に、機密ファイルを暗号化・復号する関数を実装します。encrypt_file関数は公開鍵を使ってファイルを暗号化し、暗号化されたテキストを.encファイルに保存します。decrypt_file関数は秘密鍵を使ってファイルを開き(復号し)、.decファイルに保存します。
次の関数をasym.pyに追加します。
いよいよ、ここまでの作業の成果を確認しましょう。2つの鍵を生成します。ファイルの施錠に使う公開鍵と、保存しておく秘密鍵です。ファイルにアクセスするときは、保存した秘密鍵と、それに対応する公開鍵を読み込み、ファイルを復号します。
最後の関数呼び出しをasym.pyファイルに追加します。
ローカルのターミナルでpython asym.pyを実行して、プログラムを動かします。
注: 上記のコードは、暗号化と復号の仕組みを示すものです。ただし、実際のアプリケーションで安全に使えるものではありません。鍵ファイルが保護されていないため、第三者がアクセスできると、ファイルを開けてしまいます。
PyNaClの公開鍵・秘密鍵ボックスのメリットとデメリット
PyNaClの公開鍵・秘密鍵ボックスは、高いセキュリティを提供します。また、安全でないチャネル上でも安全に通信できるため、インターネット通信に最適です。
一方、公開鍵・秘密鍵ボックスでは、鍵の管理が難しい場合があります。秘密鍵を安全に保管し、暗号化に適切な公開鍵を使う必要があります。また、公開鍵暗号はより複雑な処理を伴うため、共通鍵暗号より遅くなることがあります。
今回の解説のまとめ
この記事では、Pythonで暗号化方式を実装するための強力なツールをいくつか紹介しました。Amazon KMSとPyNaClのSecretBoxは共通鍵暗号に適しており、PyNaClの公開鍵・秘密鍵ボックスは公開鍵暗号に優れています。
これらのツールには、安全なデータ処理に役立つさまざまなメリットがあります。Amazon KMSは優れたスケーラビリティを備え、PyNaClのSecretBoxは高いパフォーマンスと幅広い互換性を持ち、PyNaClの公開鍵・秘密鍵ボックスは非常に安全な通信を可能にします。これらを組み合わせることで、包括的な暗号化ツールキットを構成できます。
暗号化方式を選ぶ際には、データの機密性、データを送信する環境、鍵の管理方法を考慮する必要があります。完璧な暗号化方式はありませんが、ニーズに最適なものを見つけるのは難しくありません。
Pythonアプリのセキュリティ対策を始めましょう
Snykを使って、Pythonの脆弱性を無料で検出・修正できます。
クレジットカードの登録は不要です。
またはAzure AD、Docker ID、Bitbucketで登録
Snykを利用すると、利用規約およびプライバシーポリシーを含む各種ポリシーに同意したものとみなされます。



