ファイルを暗号化するのに、ZIP圧縮の暗号化機能を使っているという方は多いことだろう。とは言え、ZIPファイルの暗号化にZipCrypto形式を使っているなら、安全とは言えないかもしれない。というのも、昨今のコンピューターを使えば8文字(英小文字+数字)のパスワードなど数分以内に解析できてしまう。そこで、今回は暗号化ツールを作って安全にファイルを暗号化する方法を考えてみよう。

  • GUIで使える簡単ファイル暗号化ツールを作ってみよう

    GUIで使える簡単ファイル暗号化ツールを作ってみよう

ZIPファイル圧縮の問題点を確認しよう

まず、今回のプログラムを作る前に、現在、ZIPファイルの暗号化で問題となっている点を確認しよう。一般的に、ZIPファイルの暗号化に使えるのは、ZipCryptoとAES-256の2つの方式となっている。しかし、Windows10のエクスプローラーでも解凍できるのは前者のZipCryptoのみだ。そのため、利便性からZIPファイルの暗号化には、ZipCrypto方式が好まれて使われることが多い。

しかし、ZipCryptoの暗号化はそれほど強力であるとは言えない。もし、ZIPファイルの暗号化に、ZipCryptoを使った上に8文字以下のパスワードを利用するとしたら、それこそ数分でパスワードを解読されてしまうことになるだろう。しかも、この方式で設定できるパスワードの最大文字数は12文字までという欠点がある。

試しにインターネットで「パスワードを忘れたZIPファイルを開く」で検索してみよう。たくさんの暗号解除ツールが見つかるだろう。また、パスワード特定までにかかった時間を示しているものもあり、そうした情報を見ると短いパスワードでのZIPファイル暗号化の意味が全くないことも分かるだろう。

これに対して、ZIP暗号化でもAES-256方式は「高度暗号化標準」と呼ばれる暗号化方式が採用されている。この方式で十分な長さのパスワードを使うことで、簡単に解読されることはない。

ZIPファイルの暗号化のベストプラクティスは、Windows10の標準機能では解凍できなってしまうが圧縮形式にAES-256を使うこと、そして、パスワードに英数記号をまんべんなく使った10桁以上のパスワードを使うことだろう。(ただし、マシンの性能は日々向上しており、いつかは10桁のパスワードでも安全とは言えないという時代が来るだろう。)

独自ツールを作る際の注意点

ところで、ZIPファイルの暗号化ZipCryptoが危険なのであれば、独自の暗号化アルゴリズムを作ることで問題が解決できるかもしれないと思うだろう。しかし、独自の暗号化ツールを作る上で注意が必要な点もある。まず、思いつきで実装した暗号方式が必ずしも安全とは言えないという点だ。

例えば、暗号の最も古典的な手法にシーザー暗号がある(シーザー暗号について詳しい解説はこちら)。簡単に言えば、文字を指定文字数だけアルファベット順にずらすだけという暗号だ。例えば「A」なら「C」に「B」なら「D」に「E」なら「G」にするというもの。しかし暗号化した後のデータを見ただけでは、見ようによっては完全に暗号化されているように見えることもある。

実際のところ、暗号化の強度は暗号化後のデータを見ただけでは分からないため、正しく暗号化されているかどうかの判断は難しい。これは大きな落とし穴であり、素人が作った独自形式の暗号化よりも前述のZipCryptoの方がまだましだったということになりかねない。

そこで、独自ツールを作ろうと思った時にも、よっぽど自身があるのでない限り、実際に解読が難しく安全だと言われている暗号化形式を使うと良いだろう。そして、本稿でも手軽に試せる堅牢な暗号化方式であるAES-256を使う事にする。

必要ライブラリのインストール

PythonでAESなどの暗号化を行うには、pycryptodomeというライブラリを使う。コマンドライン(WindowsならPowerShell、macOSならターミナル.app)で以下のコマンドを実行してライブラリをインストールしよう。また、GUIも利用するので、ついでにPySimpleGUIも一緒にインストールしよう。

python3 -m pip install pycryptodome pysimplegui

暗号化・復号化のプログラム

そして、今回、以下のようなプログラムを作成した。テキストエディタに以下のプログラムを貼り付けて「angou.py」という名前で保存しよう。

import PySimpleGUI as sg
import Crypto
from Crypto.Cipher import AES
# AES-256のオブジェクトを作成 --- (*1)
def aes_new(password, iv):
    sha = Crypto.Hash.SHA256.new()
    sha.update(password.encode())
    return AES.new(sha.digest(), AES.MODE_CFB, iv)
# 暗号化 --- (*2)
def encrypt(data, password):
    iv = Crypto.Random.new().read(AES.block_size)
    return iv + aes_new(password, iv).encrypt(data)
# 復号化 --- (*3)
def decrypt(data, password):
    iv, cipher = data[:AES.block_size], data[AES.block_size:]
    return aes_new(password, iv).decrypt(cipher)
# ダイアログで質問 --- (*4)
password = sg.popup_get_text('パスワードは?', password_char='*')
password2 = sg.popup_get_text('パスワード(確認)', password_char='*')
if password != password2: sg.popup_ok('パスワードが一致しません'); quit()
# 入力ファイルを選択 --- (*5)
infile = sg.popup_get_file('入力ファイルを指定')
if infile is None: quit()
data = open(infile, 'rb').read()
# 暗号化/復号化 --- (*6)
t = sg.popup_yes_no('暗号化なら[Yes]、復号化なら[No]')
if t == 'Yes':
  savedata = encrypt(data, password)
else:
  savedata = decrypt(data, password)
# 出力ファイルを選択 --- (*7)
outfile = sg.popup_get_file('出力ファイルを指定', save_as=True)
if outfile is None: quit()
open(outfile, 'wb').write(savedata)
sg.popup_ok('保存しました')

プログラムを実行するには、コマンドラインで以下を実行しよう。

python3 angou.py

すると、次々とダイアログが出るので質問に答えていくと暗号化・復号化ができる。

  • 次々とダイアログが出るので質問に答えていくと暗号化・復号化ができる

    次々とダイアログが出るので質問に答えていくと暗号化・復号化ができる

それでは、プログラムを確認してみよう。(*1)から(*3)の部分では、AES-256暗号化・復号化のための手順を関数にまとめたものだ。AES暗号化では、パスワードに加えてIV(初期化ベクトル)を指定することになっている。初期ベクトルを指定することにより、同じパスワードで暗号化したときも異なるデータになる。今回、この初期ベクトルは暗号化済みのファイルに埋め込んでおくことにした。(*2)では暗号化を行い、(*3)では復号化を行う。

そして、(*4)ではダイアログを表示してユーザーにパスワードを質問する。(*5)では入力ファイルダイアログを出して、ユーザーがファイルを選ぶとファイルを読み込む。(*6)では暗号化・復号化のどちらを行うのか尋ねて、暗号化・復号化の処理を行う。そして、(*7)では出力ファイルダイアログを出してユーザーが保存先を指定したら、ファイルを保存する。

まとめ

以上、今回はAES-256を利用した独自の暗号化ツールを作ってみた。コメントを入れても35行のプログラムなので、一気に読める量のプログラムだろう。ただし、最低限の機能しか実装していない。

そこで、10桁以下のパスワードが指定されたら、受け付けないようにするなど改良してみると安心だろう。また、暗号化済みのデータの拡張子を決め打ちにして、そのデータが選ばれたら暗号化・復号化を選ばなくても良いようにすると利便性が高まる。その際、Windowsの関連づけに対応すると、さらに使い勝手が向上するだろう。

そして、せっかくのGUI対応プログラムなので、pyinstallerなどを利用して、実行ファイル(EXEファイル)にして配布すれば、自分以外の人にもつかってもらえるだろう。

なお、メールでパスワードとファイルを送信する方法は、いかに暗号化の方法を強化したとしても安全とは言えない。そもそも、メールからファイルを読み出せたのであれば、同一経路で受け渡されるパスワードも簡単に読み出せてしまうというのが理由だ。そのため、ファイルの受け渡しには、DropboxやOneDrive、Googleドライブなどクラウドストレージを使ってファイルを受け渡す方法が推奨されている。参考にしよう。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。