実装する共通鍵暗号について
暗号化方式には共通鍵暗号と公開鍵暗号の2つがあります。
共通鍵暗号では、暗号化と復号に同じ鍵を使用します。暗号化と復号の両方を1つの鍵で可能にするのが特徴です。
現在主流な暗号化方式は「AES」で、無線LANのWPA2でも採用されている暗号化方式です。今回はAESをpythonで実装します!
0, 動作環境
- windows 11
- vscode 1.75.1
- python 3.11.0
- cryptography 38.0.4
1, pyca/cryptographyとは
暗号化機能にはLow-levelとHigh-levelという概念があります。Low-levelのインターフェースを誤って使用すると、セキュリティ的なリスクが大きいです。暗号化についてよくわからないのであれば、High-levelの方を使うと良いと思います。
pyca/cryptographyではFernetという規格を採用しています。Fernetにおいて、暗号化はCBCモードのAES128で実施されます。
↓詳細
・https://cryptography.io/en/latest/fernet/
・https://timesaving.hatenablog.com/entry/2020/12/31/110000
2, pipコマンドでpyca/cryptographyをインストール
pip install cryptography
ちなみにインストールやバージョンの確認は
pip list
からできると思います。
3, 実装
新しいクラスAESにまとめ、自分なりに
・鍵生成
・暗号化
・復号
の機能を関数にしました。
注)下記の 4,実行結果にありますが、それぞれの関数内のprint内の「.decode()」を消すとbyte長になった結果がなります。byte長というのは('\xe3\x81...')こういうやつです。
コード
#use "cryptography"
#共通鍵暗号
from cryptography.fernet import Fernet
class AES:
def __init__(self):
#鍵生成
self.key = Fernet.generate_key()
print(f"共通鍵:{self.key.decode()}")
self.f = Fernet(self.key)
def get_key(self):
return self.key
#暗号化
def encode(self,i):
self.token = self.f.encrypt(i.encode("utf8"))
print(f"暗号文:{self.token.decode()}")
#復号化
def decode(self,kagi:str):
result = Fernet(kagi).decrypt(self.token)
print(f"復号(byte):{result}")
# utf8 でデコード
re_str = bytes(result).decode("utf8")
print(f"復号(str):{re_str}")
aes = AES()
message = "こんにちは、平文です。"
decode_str = aes.encode(message)
aes.decode(aes.key)
4, 実行結果
順を追って
・共通鍵:鍵サイズは選べますが、デフォルトは128bitです。たしか。
・暗号文:平文の「こんにちは、平文です。」を共通鍵を用いて暗号化します。
・復号(byte):コンソールには「b'\xe3\x81...'」とありますが、これは復号結果がbyte長になっています。
・復号(str):utf-8で読めるように直したものです。
5, 感想
案外簡単に実装できちゃいました。共通鍵の安全性や理論については触れていませんが、ライブラリを使うことで簡単に実装できることが今回分かりました!