暗号化 PyCrypto
2016/07/26
PyCrypto2.6, Python2.7
Blowfishアルゴリズムを使った暗号化して、元に戻す(復号化)スクリプト。
ブロック暗号とか呼ばれるものは、暗号化した文字列を16倍との倍数だとか決まったブロック数にしなきゃいけない。
# -*- coding: utf-8 -*-
from Crypto.Cipher import Blowfish
from Crypto import Random
from struct import pack
plaintext = 'hello world!!'
key = 'password'
print('source: '+plaintext)
bs = Blowfish.block_size
iv = Random.new().read(bs)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
plen = bs - divmod(len(plaintext),bs)[1]
padding = [plen]*plen
padding = pack('b'*plen, *padding)
ciphertext = cipher.encrypt(plaintext + padding)
print('encrypt: '+ciphertext)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
msg = cipher.decrypt(ciphertext)
last_byte = msg[-1]
msg = msg[:- (last_byte if type(last_byte) is int else ord(last_byte))]
print('decrypt: '+msg)
iv
の部分が同じでないといけないので、これだと同一プログラムの中でしか、復号化できないので、iv
を一緒に保存しとかなきゃいけない。
初期化ベクトルっていうらしい。
ということで、暗号化した分にくっつけてしまう。
# -*- coding: utf-8 -*-
from Crypto.Cipher import Blowfish
from Crypto import Random
from struct import pack
plaintext = 'hello world!!'
key = 'password'
def encrypt(plaintext,key):
bs = Blowfish.block_size
iv = Random.new().read(bs)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
plen = bs - divmod(len(plaintext),bs)[1]
padding = [plen]*plen
padding = pack('b'*plen, *padding)
ciphertext = cipher.encrypt(plaintext + padding)
msg = iv + ciphertext
return msg
def decrypt(msg,key):
bs = Blowfish.block_size
iv = msg[:bs]
ciphertext = msg[bs:]
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
msg = cipher.decrypt(ciphertext)
last_byte = msg[-1]
msg = msg[:- (last_byte if type(last_byte) is int else ord(last_byte))]
return msg
def main():
print('source: '+plaintext)
msg = encrypt(plaintext,key)
print('encrypt: '+msg)
msg = decrypt(msg,key)
print('decrypt: '+msg)
main()
How to decrypt using Blowfish in Pycrypto?
http://stackoverflow.com/questions/35042164/how-to-decrypt-using-blowfish-in-pycrypto
ブロックサイズにするためにpaddingをなにやら難しいことをしているけど、base64エンコードしてもいい感じにブロックサイズに合わせることが出来るらしい。あと、文字化けも防げるので、保存しやすい。ただ、画像とかでやるとデータ量が膨らむのでよくないらしい。
# -*- coding: utf-8 -*-
from Crypto.Cipher import Blowfish
from Crypto import Random
from struct import pack
import base64
plaintext = 'hello'
key = 'password'
print('source: '+plaintext)
cipher = Blowfish.new(key, Blowfish.MODE_ECB)
plaintext = base64.b64encode(plaintext)
ciphertext = cipher.encrypt(plaintext)
ciphertext = base64.b64encode(ciphertext)
print('encrypt: '+ciphertext)
cipher = Blowfish.new(key, Blowfish.MODE_ECB)
ciphertext = base64.b64decode(ciphertext)
msg = cipher.decrypt(ciphertext)
msg = base64.b64decode(msg)
print('decrypt: '+msg)
ECBモードだと初期ベクトルは関係ないそうな(セキュリティ的には弱い)。