暗号化

2020年12月25日

はじめに

Python によるデータの暗号化について。

大文字小文字入れ替え

msg に暗号化したいデータが入っているとする。文字列の大文字と小文字を入れ替えるには、以下のようにする。

msg.swapcase()

さすがにこれでは暗号にならないが、パスワードをちょっとひねって保存するにはよいかも。

逆順

文字列を逆順にする。

msg = "abcdefghijklmnop"

def reverse_str(s):
    l = list(s)
    l.reverse()
    return "".join(l)

data = reverse_str(msg)
print(data)

org_msg = reverse_str(data)
print(org_msg)

これもちょっとしたひねり。

シーザー暗号

import codecs
msg = "abcdefghijklmnop"

data = codecs.decode(msg, "rot13")
print(data)

org_msg = codecs.decode(data, "rot13")
print(org_msg)

一応暗号。文字を 13 個動かす。簡単すぎて実用的ではない。

base64

import base64
msg = "abcdefghijklmnop"

data = base64.b64encode(msg.encode())
print(data)

org_msg = base64.b64decode(data).decode()
print(org_msg)

ちょっとしたカモフラージュ。Base64 は雰囲気でわかる。

zlib

import zlib
msg = "abcdefghijklmnop"

data = zlib.compress(msg.encode())
print(data)

org_msg = zlib.decompress(data).decode()
print(org_msg)

これもカモフラージュ。データの圧縮にもなってお得? もちろん単体では使えない。

pycryptodome

AES というちゃんとした暗号。

from Crypto.Cipher import AES

key = "1234567890123456"
msg = "abcdefghijklmnop"

iv = b"0"*AES.block_size
crypto = AES.new(key.encode(), AES.MODE_CBC, iv)

data = crypto.encrypt(msg.encode())
print(data)

crypto = AES.new(key.encode(), AES.MODE_CBC, iv)

org_msg = crypto.decrypt(data).decode()
print(org_msg)

シークレットキーは 16, 24, 32 の長さである必要がある。暗号化する文字列の長さは 16 の倍数である必要がある。以下のようにすればサイズ調整できる。

from Crypto.Util import Padding

key = Padding.pad(key.encode(), AES.block_size)
msg = Padding.pad(msg.encode(), AES.block_size)

iv は、暗号化のたびにランダムに変えて、暗号化データと一緒に保存するのがよいらしい。

参考: Good AES Initialization Vector practice (stackoverflow)