◾️はじめに
Pythonでのファイル暗号化・復号化のためのライブラリ python-gnupg について扱う
目次
【1】前提知識:GnuPG 【2】python-gnupg 1)インストール 【3】サンプル 例1:キー生成・暗号化・復号化 例2:署名・検証(sign / verify) 例3:公開鍵・秘密鍵のエクスポート/インポート 例4:公開鍵による暗号化・復号化
【1】前提知識:GnuPG
* GnuPG(グヌー・ピー・ジー) = GNU Privacy Guard * オープンソースの暗号化ツール
【2】python-gnupg
* Pythonから GnuPGを利用するためのラッパーライブラリ
1)インストール
Step1: GnuPG のインストール
# Macの場合 brew install gnupg gpg --version
Step2: ライブラリのインストール
pip install python-gnupg
【3】サンプル
例1:キー生成・暗号化・復号化
import os import gnupg # --- 設定 --- os.makedirs('./gpg_home', exist_ok=True) gpg = gnupg.GPG(gnupghome='./gpg_home') # --- 鍵ペアを作成 --- input_data = gpg.gen_key_input( name_email='test@example.com', passphrase='testpass' ) key = gpg.gen_key(input_data) print("✅ 鍵ペアを作成しました:", key.fingerprint) # --- テスト用ファイル作成 --- with open('secret.txt', 'w') as f: f.write('これは秘密のメッセージです!') # --- ファイルを暗号化 --- with open('secret.txt', 'rb') as f: encrypted_data = gpg.encrypt_file( f, recipients=['test@example.com'], output='secret.txt.gpg' ) if encrypted_data.ok: print("🔒 暗号化成功: secret.txt.gpg") else: print("❌ 暗号化失敗:", encrypted_data.stderr) # --- ファイルを復号化 --- with open('secret.txt.gpg', 'rb') as f: decrypted_data = gpg.decrypt_file( f, passphrase='testpass', output='decrypted.txt' ) if decrypted_data.ok: print("🔓 復号化成功: decrypted.txt") else: print("❌ 復号化失敗:", decrypted_data.stderr)
例2:署名・検証(sign / verify)
import os import gnupg # --- 設定 --- os.makedirs('./gpg_home', exist_ok=True) gpg = gnupg.GPG(gnupghome='./gpg_home') # --- 鍵ペアを作成 --- input_data = gpg.gen_key_input( name_email='signer@example.com', passphrase='mypassword' ) key = gpg.gen_key(input_data) print("✅ 鍵ペアを作成しました:", key.fingerprint) # --- 署名対象のファイルを作成 --- message_path = 'message.txt' with open(message_path, 'w') as f: f.write('このメッセージは署名されています。') # --- ファイルに署名(sign) --- with open(message_path, 'rb') as f: signed_data = gpg.sign_file( f, keyid=key.fingerprint, passphrase='mypassword', output='message.txt.asc' # ASCIIアーマー形式で署名付きファイルを作成 ) if signed_data: print("✍️ 署名完了: message.txt.asc") else: print("❌ 署名失敗") # --- 署名の検証(verify) --- with open('message.txt.asc', 'rb') as f: verify_result = gpg.verify_file(f) if verify_result: print("✅ 検証成功!") print(f"署名者: {verify_result.username}") print(f"フィンガープリント: {verify_result.fingerprint}") else: print("❌ 検証失敗!")
例3:公開鍵・秘密鍵のエクスポート/インポート
import os import gnupg # --- 設定 --- os.makedirs('./gpg_home', exist_ok=True) gpg = gnupg.GPG(gnupghome='./gpg_home') # --- 鍵ペア作成(送信者側)--- input_data = gpg.gen_key_input( name_email='sender@example.com', passphrase='mypassword' ) sender_key = gpg.gen_key(input_data) print("✅ 送信者の鍵ペアを作成:", sender_key.fingerprint) # --- 公開鍵をエクスポート --- public_key_ascii = gpg.export_keys(sender_key.fingerprint) with open('sender_public.asc', 'w') as f: f.write(public_key_ascii) print("📤 公開鍵を sender_public.asc にエクスポート") # --- 秘密鍵をエクスポート(※通常は安全な場所にのみ保存)--- private_key_ascii = gpg.export_keys( sender_key.fingerprint, secret=True, passphrase='mypassword') with open('sender_private.asc', 'w') as f: f.write(private_key_ascii) print("🔐 秘密鍵を sender_private.asc にエクスポート") # --- 別のユーザー環境(受信者側)をシミュレーション --- gpg_home_receiver = './gpg_home_receiver' os.makedirs(gpg_home_receiver, exist_ok=True) gpg_receiver = gnupg.GPG(gnupghome=gpg_home_receiver) # --- 公開鍵をインポート --- with open('sender_public.asc', 'r') as f: import_result = gpg_receiver.import_keys(f.read()) print("📥 公開鍵をインポート:", import_result.results) # --- インポートした鍵を確認 --- print("🔎 受信者側のキー一覧:") for key in gpg_receiver.list_keys(): print(f" - {key['uids']} ({key['fingerprint']})")
例4:公開鍵による暗号化・復号化
import os import gnupg def make_home(path): os.makedirs(path, exist_ok=True) os.chmod(path, 0o700) # 権限を安全にする(warning 対策) return gnupg.GPG(gnupghome=path) gpg_sender = make_home('./gpg_home_sender') gpg_receiver = make_home('./gpg_home_receiver') # --- Step1: 鍵作成 --- sender_input = gpg_sender.gen_key_input( name_email='sender@example.com', passphrase='senderpass' ) sender_key = gpg_sender.gen_key(sender_input) receiver_input = gpg_receiver.gen_key_input( name_email='receiver@example.com', passphrase='receiverpass' ) receiver_key = gpg_receiver.gen_key(receiver_input) # --- Step2: 公開鍵交換 --- receiver_pub = gpg_receiver.export_keys(receiver_key.fingerprint) import_result = gpg_sender.import_keys(receiver_pub) print("📥 送信者が受信者の公開鍵をインポート:", import_result.count, "件") # 🔑 信頼レベル設定(重要) for key in gpg_sender.list_keys(): if 'receiver@example.com' in key['uids']: gpg_sender.trust_keys(key['fingerprint'], 'TRUST_ULTIMATE') print(f"✅ 受信者の鍵 {key['fingerprint']} を信頼済みに設定") # 再読み込み gpg_sender.list_keys() # --- Step3: 暗号化 --- message = "これは受信者への秘密メッセージです。" encrypted = gpg_sender.encrypt( message.encode('utf-8'), recipients=['receiver@example.com'], output='message.asc', always_trust=True # ← これが重要! ) if encrypted.ok: print("🔒 暗号化完了: message.asc") else: print("❌ 暗号化失敗:", encrypted.stderr) # --- Step4: 復号化 --- if os.path.exists('message.asc'): with open('message.asc', 'rb') as f: decrypted = gpg_receiver.decrypt_file(f, passphrase='receiverpass', output='decrypted.txt') if decrypted.ok: print("🔓 復号化完了: decrypted.txt") print("📨 内容:", open('decrypted.txt').read()) else: print("❌ 復号化失敗:", decrypted.stderr) else: print("⚠️ 暗号化が失敗したため、message.asc が存在しません。")
関連記事
Python ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2014/08/07/231242