文字列

[Python] cryptographyの使い方 – ファイルの暗号化/復号化

Pythonのcryptographyライブラリを使用してファイルの暗号化と復号化を行うには、Fernetという対称鍵暗号方式を利用します。

まず、Fernet.generate_key()で暗号化キーを生成し、そのキーを使ってFernetオブジェクトを作成します。

ファイルの内容を読み込み、Fernet.encrypt()で暗号化し、暗号化されたデータをファイルに保存します。

復号化は、同じキーを使ってFernet.decrypt()を呼び出し、元のデータを復元します。

cryptographyライブラリの概要

cryptographyライブラリは、Pythonで暗号化や復号化を行うための強力で使いやすいツールです。

このライブラリは、対称鍵暗号、非対称鍵暗号、ハッシュ関数など、さまざまな暗号化手法をサポートしています。

特に、Fernetという対称鍵暗号方式を使用することで、簡単にデータを安全に暗号化することが可能です。

cryptographyは、セキュリティの専門家によって設計されており、最新の暗号化技術を取り入れています。

これにより、開発者は自分のアプリケーションに強力なセキュリティ機能を組み込むことができます。

また、ライブラリはドキュメントが充実しており、初心者でも扱いやすいのが特徴です。

Pythonの標準ライブラリには含まれていないため、別途インストールが必要ですが、その価値は十分にあります。

cryptographyのインストール方法

pipを使ったインストール手順

cryptographyライブラリは、Pythonのパッケージ管理ツールであるpipを使用して簡単にインストールできます。

以下のコマンドをターミナルまたはコマンドプロンプトで実行してください。

pip install cryptography

このコマンドを実行すると、cryptographyライブラリが自動的にダウンロードされ、インストールされます。

インストールが完了すると、すぐにライブラリを使用することができます。

インストール時の注意点

  • Pythonのバージョン: cryptographyはPython 3.6以上が必要です。

古いバージョンのPythonを使用している場合は、アップグレードを検討してください。

  • 依存関係: cryptographyは他のライブラリに依存している場合があります。

インストール時にエラーが発生した場合は、依存関係のライブラリも手動でインストールする必要があります。

  • 仮想環境の利用: プロジェクトごとに異なるライブラリのバージョンを管理するために、仮想環境venvvirtualenvを使用することをお勧めします。

バージョン確認とアップデート方法

インストールしたcryptographyライブラリのバージョンを確認するには、以下のコマンドを実行します。

pip show cryptography

このコマンドを実行すると、インストールされているcryptographyのバージョン情報が表示されます。

ライブラリを最新バージョンにアップデートするには、次のコマンドを使用します。

pip install --upgrade cryptography

これにより、最新の安定版がインストールされます。

ファイルの暗号化手順

Fernetキーの生成

ファイルを暗号化するためには、まずFernetキーを生成する必要があります。

このキーは、暗号化と復号化の両方に使用されます。

以下のコードを使用して、Fernetキーを生成できます。

from cryptography.fernet import Fernet
# Fernetキーの生成
key = Fernet.generate_key()
# キーをファイルに保存
with open('secret.key', 'wb') as key_file:
    key_file.write(key)
print("Fernetキーが生成され、'secret.key'に保存されました。")

このコードを実行すると、secret.keyというファイルに生成されたキーが保存されます。

ファイルの読み込み方法

次に、暗号化したいファイルを読み込む方法を示します。

以下のコードでは、テキストファイルを読み込みます。

# ファイルの読み込み
file_path = 'example.txt'  # 読み込むファイルのパス
with open(file_path, 'rb') as file:
    file_data = file.read()
print("ファイルが正常に読み込まれました。")

このコードを実行すると、指定したファイルの内容がfile_dataに格納されます。

ファイルの暗号化処理

ファイルを暗号化するためには、先ほど生成したFernetキーを使用します。

以下のコードで暗号化処理を行います。

# Fernetオブジェクトの作成
fernet = Fernet(key)
# ファイルデータの暗号化
encrypted_data = fernet.encrypt(file_data)
print("ファイルが正常に暗号化されました。")

このコードを実行すると、file_dataが暗号化され、encrypted_dataに格納されます。

暗号化データの保存方法

最後に、暗号化されたデータを新しいファイルに保存します。

以下のコードを使用します。

# 暗号化データの保存
with open('encrypted_file.enc', 'wb') as encrypted_file:
    encrypted_file.write(encrypted_data)
print("暗号化データが'encrypted_file.enc'に保存されました。")

このコードを実行すると、暗号化されたデータがencrypted_file.encというファイルに保存されます。

これで、ファイルの暗号化が完了しました。

ファイルの復号化手順

復号化に必要な情報

ファイルを復号化するためには、以下の情報が必要です。

  • Fernetキー: 暗号化時に使用したキー。
  • 暗号化されたファイル: 復号化したいファイルのパス。

これらの情報を用意しておくことが重要です。

暗号化ファイルの読み込み

まず、復号化したい暗号化ファイルを読み込みます。

以下のコードでは、encrypted_file.encというファイルを読み込みます。

# 暗号化ファイルの読み込み
with open('encrypted_file.enc', 'rb') as encrypted_file:
    encrypted_data = encrypted_file.read()
print("暗号化ファイルが正常に読み込まれました。")

このコードを実行すると、暗号化されたデータがencrypted_dataに格納されます。

ファイルの復号化処理

次に、Fernetキーを使用してファイルを復号化します。

以下のコードでは、先に保存したsecret.keyからキーを読み込み、復号化を行います。

from cryptography.fernet import Fernet
# キーの読み込み
with open('secret.key', 'rb') as key_file:
    key = key_file.read()
# Fernetオブジェクトの作成
fernet = Fernet(key)
# ファイルデータの復号化
decrypted_data = fernet.decrypt(encrypted_data)
print("ファイルが正常に復号化されました。")

このコードを実行すると、暗号化されたデータが復号化され、decrypted_dataに格納されます。

復号化データの保存方法

最後に、復号化されたデータを新しいファイルに保存します。

以下のコードを使用します。

# 復号化データの保存
with open('decrypted_file.txt', 'wb') as decrypted_file:
    decrypted_file.write(decrypted_data)
print("復号化データが'decrypted_file.txt'に保存されました。")

このコードを実行すると、復号化されたデータがdecrypted_file.txtというファイルに保存されます。

これで、ファイルの復号化が完了しました。

暗号化/復号化のエラーハンドリング

無効なキーのエラー処理

暗号化や復号化の際に、無効なキーを使用するとエラーが発生します。

この場合、InvalidToken例外がスローされます。

以下のコードでは、無効なキーを使用した場合のエラーハンドリングを示します。

from cryptography.fernet import Fernet, InvalidToken
# 無効なキーの例
invalid_key = b'invalid_key'
# Fernetオブジェクトの作成
fernet = Fernet(invalid_key)
try:
    # 復号化処理
    decrypted_data = fernet.decrypt(encrypted_data)
except InvalidToken:
    print("エラー: 無効なキーです。復号化に失敗しました。")

このコードを実行すると、無効なキーによるエラーが適切に処理されます。

ファイルが存在しない場合の対処

指定したファイルが存在しない場合、FileNotFoundErrorが発生します。

このエラーを処理するためには、try-exceptブロックを使用します。

以下のコードでは、ファイルが存在しない場合の対処を示します。

file_path = 'non_existent_file.txt'
try:
    with open(file_path, 'rb') as file:
        file_data = file.read()
except FileNotFoundError:
    print(f"エラー: '{file_path}' が見つかりません。")

このコードを実行すると、指定したファイルが存在しない場合にエラーメッセージが表示されます。

復号化に失敗した場合のエラー処理

復号化処理が失敗した場合も、InvalidToken例外がスローされます。

以下のコードでは、復号化に失敗した場合のエラーハンドリングを示します。

try:
    # 復号化処理
    decrypted_data = fernet.decrypt(encrypted_data)
except InvalidToken:
    print("エラー: 復号化に失敗しました。暗号化されたデータが無効です。")

このコードを実行すると、復号化に失敗した場合に適切なエラーメッセージが表示されます。

これにより、ユーザーは問題の原因を特定しやすくなります。

応用例

複数ファイルの一括暗号化

複数のファイルを一括で暗号化するには、ファイルのリストを作成し、ループを使用して各ファイルを暗号化します。

以下のコードは、指定したディレクトリ内のすべてのテキストファイルを暗号化する例です。

import os
from cryptography.fernet import Fernet
# Fernetキーの読み込み
with open('secret.key', 'rb') as key_file:
    key = key_file.read()
fernet = Fernet(key)
# 暗号化するファイルのディレクトリ
directory = 'files_to_encrypt'
# ディレクトリ内のファイルを一括暗号化
for filename in os.listdir(directory):
    if filename.endswith('.txt'):
        with open(os.path.join(directory, filename), 'rb') as file:
            file_data = file.read()
        encrypted_data = fernet.encrypt(file_data)
        with open(os.path.join(directory, f'encrypted_{filename}'), 'wb') as encrypted_file:
            encrypted_file.write(encrypted_data)
print("すべてのファイルが正常に暗号化されました。")

暗号化キーの安全な保存方法

暗号化キーを安全に保存することは非常に重要です。

以下の方法でキーを安全に保存できます。

  • 環境変数: 環境変数にキーを保存し、プログラム内で読み込む。
  • セキュアストレージ: AWS Secrets ManagerやAzure Key Vaultなどのセキュアストレージサービスを使用する。
  • 暗号化されたファイル: キー自体を暗号化して保存し、必要なときに復号化する。

以下は、環境変数を使用してキーを保存する例です。

import os
from cryptography.fernet import Fernet
# 環境変数からキーを取得
key = os.environ.get('FERNET_KEY').encode()
fernet = Fernet(key)

ファイルの自動暗号化スクリプトの作成

特定のディレクトリに新しいファイルが追加されたときに自動的に暗号化するスクリプトを作成できます。

以下は、watchdogライブラリを使用してディレクトリを監視する例です。

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from cryptography.fernet import Fernet
import os
class FileHandler(FileSystemEventHandler):
    def on_created(self, event):
        if event.is_directory:
            return
        with open('secret.key', 'rb') as key_file:
            key = key_file.read()
        fernet = Fernet(key)
        with open(event.src_path, 'rb') as file:
            file_data = file.read()
        encrypted_data = fernet.encrypt(file_data)
        with open(event.src_path + '.enc', 'wb') as encrypted_file:
            encrypted_file.write(encrypted_data)
        print(f"{event.src_path} が暗号化されました。")
# 監視するディレクトリ
path = 'directory_to_watch'
event_handler = FileHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=False)
observer.start()
try:
    while True:
        pass
except KeyboardInterrupt:
    observer.stop()
observer.join()

公開鍵暗号方式を使ったファイルの暗号化

公開鍵暗号方式を使用することで、より安全な暗号化が可能です。

cryptographyライブラリでは、RSAを使用して公開鍵と秘密鍵を生成し、ファイルを暗号化できます。

以下は、公開鍵を使用してファイルを暗号化する例です。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
# RSA鍵ペアの生成
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
public_key = private_key.public_key()
# 公開鍵の保存
with open('public_key.pem', 'wb') as pub_file:
    pub_file.write(public_key.public_bytes(encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo))
# ファイルの暗号化
file_path = 'example.txt'
with open(file_path, 'rb') as file:
    file_data = file.read()
encrypted_data = public_key.encrypt(
    file_data,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
# 暗号化データの保存
with open('encrypted_file_rsa.enc', 'wb') as enc_file:
    enc_file.write(encrypted_data)
print("ファイルがRSAで暗号化されました。")

このコードを実行すると、指定したファイルが公開鍵を使用して暗号化され、encrypted_file_rsa.encに保存されます。

公開鍵暗号方式を使用することで、より高いセキュリティを確保できます。

まとめ

この記事では、Pythonのcryptographyライブラリを使用したファイルの暗号化と復号化の手順について詳しく解説しました。

また、エラーハンドリングや応用例についても触れ、実際の利用シーンを想定した内容を提供しました。

これを機に、セキュリティを強化するために自分のプロジェクトに暗号化機能を取り入れてみてはいかがでしょうか。

関連記事

Back to top button