You are currently viewing Python(cryptography)でファイルを共通鍵 暗号化!

みなさん…秘密にしておきたいデータって無いですか?私にはあります。それは大事なデータだったり黒歴史の恥ずかしいデータだったりします。秘密にしたいデータは暗号化してしまうことで普通には見えないようにすることができます。そして、ネットを探せばいくらでも暗号化のソフトは出てきます。

しかし、せっかくなら作ってみたくなるのがエンジニア(Lv.1)ということで、今回はPythonで暗号化と復号化と行うコードを書いてみました。とはいえ全てを実装するというわけではないのがLv.1の所以ということで、今回はcryptographyというライブラリを使用してお手軽にやっていこうと思います。

cryptography?

cryptographyは簡単に共通鍵暗号化を行うAPIと、より詳細に暗号処理を組むための処理群という2面をサポートしているライブラリです。今回は簡単に暗号化を試してみようと思うので、APIを活用していこうと思います。インストールはpipコマンドでできます。

$ pip install cryptography

cryptographyとは別に、pycryptoという似たようなライブラリもありますが、こちらは現在はアップデートが停止しているらしいので、上記のcryptographyを使うのが良さそうです。

できたコード

というわけで簡単にできたのがこちらです。今回は全く凝っていないので出力されるファイル名などはとてもテキトーです。

#coding:utf-8
import os
from cryptography.fernet import Fernet

def generate_key():
    """まだ存在しない場合は鍵を作成
    """    
    key = Fernet.generate_key()

    if not os.path.isfile('p.key'):
        with open('p.key', 'wb') as f:
            f.write(key)

def file2crypt(filepath):
    """パス指定したファイルを暗号化する
    Args:
        filepath (str): 暗号化するファイルのパス
    """    
    if not os.path.isfile('p.key'):
        generate_key()

    with open('p.key', 'rb') as f:
        key = f.read()

    with open(filepath, 'rb') as f:
        data = f.read()

    fernet    = Fernet(key)
    encrypted = fernet.encrypt(data)

    with open(f'{filepath}.crypted', 'wb') as f:
        f.write(encrypted)

def crypt2file(filepath):
    """パス指定した暗号化済みファイルを復号する
    Args:
        filepath (str): 暗号化済みファイルへのパス
    """    
    with open('p.key', 'rb') as f:
        key = f.read()

    with open(filepath, 'rb') as f:
        data = f.read()

    fernet    = Fernet(key)
    plaintext = fernet.decrypt(data)

    with open(f'{filepath}.plaintext', 'wb') as f:
        f.write(plaintext)

if __name__ == '__main__':
    file2crypt('test.txt')
    crypt2file('test.txt.crypted')

メイン部分はそれぞれ暗号化,複号を行うfile2crypt()crypt2file()です。基本的にはcryptographyの関数を呼び出して結果を保存しているだけです。

実行結果

次に動作確認をしてみます。今回はtest.txtというテキストファイルを用意してそれを暗号化&複号してみます。もちろんテキストファイルでなくても画像ファイルだったりでも同じようにできます。というわけでテスト用に寿限無のお名前テキストを用意して実行してみました。

じゅげむ じゅげむ ごこうのすりきれ
かいじゃりすいぎょの すいぎょうまつ
うんらいまつ ふうらいまつ
くうねるところに すむところ
やぶらこうじの ぶらこうじ
パイポパイポ
パイポのシューリンガン
シューリンガンのグーリンダイ
グーリンダイのポンポコピーのポンポコナーの
ちょうきゅうめいのちょうすけ
gAAAAABfeLvFieLQ1CQ5uClOTzNwG7xoAlh1Cx95slRl_wUu0N0XZLvJpLAQBWoRHRC9IWeya-velnwWo1RYApJm9vtlG4CqWfuUTeyNwL6d0H2UYVrjUw8KA9DgSukmhSOydTliyIuzw4KVB-O2gt_pZW_IME2JQyFSxS03UyMmAEojITuxZ9mLpa5uKLSiR-6TWE9WaBlWBp-GEU5t5-FxQiqLkTlT3NLsiYFsmofepOBfhpaA4MccSjmkErn-Yv8VT_9ScA6XkbtRa98pISHyEsQoVykz96z_Qz7gC7RUXlTVNDBtuGFN3M7M0fhS4AkZlZ5muR2Y6r1ZuCOyVdFGksDCeA5hI_1yECZa5Ur0WAtREyRQwthEKgUvVeuzqYOmX8M6DJirfW4vuCXV3Hjrab4r65n7sFNQkOplAO42T2PwOm4Mnbt4XEgHAtmIjrJ2xidgMmeEOwELvD2bzz21oCdlDKm7zfGb2-I8GJXU9zHriYQZRkQO8VbqIotYHqGGI9V8Pt6NrkCNSGm7OEEMyqVP7Ly7J78n6AYsRNl8bTg0JmT2BjUtzSRU4aIj-LQXMBQJ5Ix8mDRdnTFVOFYl3GhhPQSyQw9dopz6G6ArKOZjyNTG9er_VZOm4paxOP7B7YjqzVkKUqa7UBnbg1QXUJ5t0Hcw3g==
じゅげむ じゅげむ ごこうのすりきれ
かいじゃりすいぎょの すいぎょうまつ
うんらいまつ ふうらいまつ
くうねるところに すむところ
やぶらこうじの ぶらこうじ
パイポパイポ
パイポのシューリンガン
シューリンガンのグーリンダイ
グーリンダイのポンポコピーのポンポコナーの
ちょうきゅうめいのちょうすけ

こちらはそれぞれ、元ファイル,暗号化後ファイル,複号したファイルとなっています。1つ目と3つ目は同じ内容になり、2つ目は元の内容が読めない様になっているのが確認できると思います。またこれとは別に鍵ファイルも自動で作成されています。これがないと圧縮したファイルは戻せないので、誤って無くなさいように注意が必要です。

終わりに

今回はライブラリを使って簡単に暗号化を試してみました。暗号化のアルゴリズムについては別途勉強が必要ですが、とりあえず暗号化ができていそうなので、これで秘密にしておきたいファイルが出てきても安心ですね。

今後はちょっとやりたいことがあるので、今回書いた処理を活用しつつ、出力されるファイルの調整など、もう少し手を加えて生きたとおもいます。今後の変化は下記リポジトリで反映していきますので、しばらくたって気になったら覗いてみてください。