はじめに
pythonで暗号化をしたくて調べたらpycryptoを利用する記事がいくつかヒットしました。
pycryptoは、パディングとか考慮しないといけないみたいですが、便利なラッパークラスが公開されているようですね。
ですが、ユーザー配布するときに、インストールするパッケージが増えるのが嫌だったので単純なXORによる暗号化を実装してみました。
用途
個人的には以下の条件の場合は、簡単な暗号でもよいと思っています。(異論は認めます)
- ローカル利用のみの場合
自分の環境のみ利用して、他の人に見られることがないのであれば、情報漏洩のリスクが低いと判断していいと思います。念のために暗号化しておくパターン。
-
スクリプト自体を配布する場合
スクリプトを見たり、print文を入れればすぐにハックされてしまう場合は、あまり暗号化方式は重要でないと思います。他の問題を優先するべきパターン。
データを送受信する場合や、他人とデータを共有する場合、サーバーで動作するスクリプトの場合はちゃんとAESなどで暗号化したほうがいいと思います。
XOR
簡単な暗号化といえばXORを利用したものが一般的と思います。
XORの暗号化で調べてみたらここのような記事がありましたが、
ちょっと使いにくいので、もう少し汎用化してみました。
パスワードのようなテキストを設定ファイルに格納することを想定しているので、テキストと暗号化文字列を相互変換できる機能のみ実装します。
バイナリデータは対応していませんが、ちょっと修正すれば対応できると思います。
ソース
# 暗号化:引数の2つの文字列をXORした結果をhex文字列で返す
# src_text=暗号化したい文字列
# key=暗号化するためのキー文字列
def crypto_text_to_hex(src_text, key):
if src_text and key:
xor_code = key
# keyが短い場合は、繰り返して必要バイト数を準備する
while len(src_text) > len(xor_code):
xor_code += key
return "".join([chr(ord(data) ^ ord(code))
for (data, code) in zip(src_text, xor_code)]).encode().hex()
# 複号:引数のHex文字列とkeyをXORして戻した文字列で返す
# hex_text=暗号化されているhex文字列
# key=複号するためのキー文字列
def decrypto_hex_to_text(hex_text, key):
if hex_text and key:
try:
crypt_data = bytes.fromhex(hex_text).decode()
except ValueError:
crypt_data = None
if crypt_data:
xor_code = key
# keyが短い場合は、繰り返して必要バイト数を準備する
while len(crypt_data) > len(xor_code):
xor_code += key
return "".join([chr(ord(data) ^ ord(code))
for (data, code) in zip(crypt_data, xor_code)])
実行
key = "1234567890"
src_text = "crypto test string"
print("src:" + src_text)
hex_text = crypto_text_to_hex(src_text, key)
print("enc:" + hex_text)
decode_text = decrypto_hex_to_text(hex_text, key)
print("dec:" + decode_text)
if src_text == decode_text:
print("decode OK.")
実行結果
src:crypto test string
enc:52404a444159174c5c4345124040475f595f
dec:crypto test string
decode OK.
まとめ
なんでもAESにすればいいというものでもないと思う。適材適所です。