yoraba build

備忘録を兼ねた技術ブログ

pythonにおけるAES暗号

 データのセキュリティを高めるためには暗号化処理が不可欠となります。
 AES、DES、MD5など方式は色々とありますが、まずはAES暗号化に挑戦してみたいと思います。

暗号化パッケージ

 暗号化パッケージとして有名なのはPyCryptoというものらしいです。必要なパラメータや手順が結構あるのでラッパークラスを作成した方が後々楽だと思いました。詳細を確認しながら書いていきます。

AES暗号について

  • 鍵の長さ

鍵の長さによって規格が異なります。
AES-128: 128bit=16byte
AES-192: 192bit=24byte
AES-256: 256bit=32byte

  • 暗号化モード

初期ベクトルの利用方法がモードによって異なります。
https://qiita.com/shoichi0599/items/6082b765c1257b71985b

  • 初期ベクトル

IVと呼ばれます。同じ鍵でも毎回違う暗号文を作成するために用います。
暗号化する度に乱数を使って作成します。復号する際に必要になるので、暗号文とセットにします。
ECBモードとCTRモードでは不要です。

  • ブロックサイズ

AES暗号の場合、ブロック長は128bit=16byteです。

  • パディング

平文をブロック長の倍数長に調整する必要があります。端数が生じた場合は空白で埋めます。

  • カウンター

CTRモードではパフォーマンスを向上させる為にカウンターというパラメータを要します。

  • セグメントサイズ

CFBモードではセグメントサイズというパラメータを要します。

暗号抽象クラス

複数のラッパーの作成が想定されるので、それらのクラスの基底となる抽象クラスを作成しました。
ファイル出力機能を追加してもいいかもしれません。
https://github.com/yoraba/python_tools/blob/master/lib/cryptos/abc_crypto.py

利用例

test_encrypt_decrypt(self):
    def encrypt_decrypt(key, text,
                        mode=Cipher.AES.blockalgo.MODE_CBC,
                        segment_size=8):
        cipher = AES(key, mode, segment_size)
        iv, encrypted = cipher.encrypt(text=text)
        print(f'IV:{iv} crypto:{encrypted} base64:{base64.b64encode(encrypted)}')
        decrypted = cipher.decrypt(text=encrypted, iv=iv)
        print(decrypted)
        self.assertTrue(text == decrypted)

    encrypt_decrypt('1234abcd6789efgh0', '1234567890123456')
    encrypt_decrypt('1234abcd', 'keyが16byte以下')
    encrypt_decrypt('1234abcd6789efgh', 'keyが16byte')
    encrypt_decrypt('1234abcd6789efgh0', 'keyが16byteを超える')
    encrypt_decrypt('1234abcd6789efgh1234abcd', 'keyが24byte')
    encrypt_decrypt('1234abcd6789efgh1234abcd0', 'keyが24byteを超える')
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh', 'keyが32byte')
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh0', 'keyが32byteを超える')
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh0', 'モードCFB', mode=Cipher.AES.blockalgo.MODE_CFB)
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh0', 'モードCTR', mode=Cipher.AES.blockalgo.MODE_CTR)
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh0', 'モードECB', mode=Cipher.AES.blockalgo.MODE_ECB)
    encrypt_decrypt('1234abcd6789efgh1234abcd6789efgh0', 'モードOFB', mode=Cipher.AES.blockalgo.MODE_OFB)