python でファイルの暗号化メモ
色んなExampleから抜き出して作成してみました。
angoka.py 暗号化ファイル
cAngo.py 暗号化実装ファイル
実行方法
$ python angoka.py
以下ソースファイル
#===== BEGIN angoka.py =======================================================
# encoding: utf-8
##### pythonのpathは必要ならば書き加えてください。 #####
##### print文の print('ooo') カッコでエラーとなる場合は print 'ooo' に書き換えてください #####
import os, sys # 既存ターゲットファイル削除
import getpass # パスワード入力用
import termios # Yes or No 入力用
import tty # Yes or No 入力用
import subprocess # shell command用
from cAngo import * # 暗号・復号化用 cAngo.py
#===== Yes or No =================================
def yesno(message):
result = ''
sys.stdout.write(message)
sys.stdout.flush()
attribute = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
try:
while True:
char = sys.stdin.read(1)
if char == 'y' or char == 'Y':
result = 'y'
break
elif char == 'n' or char == 'N':
result = 'n'
break
except KeyboardInterrupt:
result = '^C'
termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, attribute)
print(result)
return result
#===== ファイル削除 =====================================================
def delete_file(target):
ret = os.path.exists(target)
try:
if ret:
os.remove(target)
return True
except:
print(' >>> ' + target + ' を削除出来ませんでした。')
return False
_target_user = ''
_num = raw_input('暗号化 or 復号化を選択してください。\n 1: 暗号化\n 2: 復号化\n ※番号を入力してください。: ')
if _num != '1' and _num != '2':
print(' >>> キャンセルしました。')
sys.exit()
_keycode = getpass.getpass(' >>> キーコードを入力して下さい。: ')
if _keycode == '':
sys.exit()
_message = '暗号化'
if _num == '2':
_message = '復号化'
_source_file = raw_input(' >>> ' + _message + ' するファイル名を入力して下さい。: ')
if _source_file == '':
sys.exit()
ret = os.path.exists(_source_file)
if not ret:
print(_source_file + ' は存在しません。')
sys.exit()
_dest_file = raw_input(' >>> 出力するファイル名を入力して下さい。(未入力可): ')
if _dest_file == '':
_dest_file = _source_file + '.enc'
# 既存ファイルの存在と上書きの確認
ret = os.path.exists(_dest_file)
if ret:
result = yesno(' >>> ' + _dest_file + ' はすでに存在します、上書きしますか? (Yes or No) ')
if result != 'y':
print(' >>> 中止しました。')
sys.exit()
result = yesno(' >>> ' + _message + ' を実行しますか? (Yes or No) ')
if result != 'y':
print(' >>> キャンセルしました。')
sys.exit()
# 既存ファイル削除
ret = delete_file(_dest_file)
if not ret:
print(' >>> ' + _dest_file + ' を削除できませんでした。 中止します。')
sys.exit()
try:
if _num == '1':
encrypt_file(_keycode, _source_file, _dest_file) # 暗号化
else:
decrypt_file(_keycode, _source_file, _dest_file) # 復号化
except Exception as e:
print(' >>> Error 中止しました。 (02)' + e.message)
sys.exit()
ret = os.path.exists(_dest_file) # 暗号化・復号化ファイルが作成されたか確認
if not ret:
print(' >>> Error 失敗しました。 (03)')
sys.exit()
path = os.path.dirname(_dest_file) # ファイルのdirectory
print(subprocess.check_output(['ls', '-l', path])) # 確認用 ls -l
print(' >>> ' + _message + ' Complete!! <<<')
# 2016/05/09_1
#===== END angoka.py =========================================================
※参考リンク
http://eli.thegreenplace.net/2010/06/25/aes-encryption-of-files-in-python-with-pycrypto#===== BEGIN cAngo.py =========================================================
# encoding: utf-8
import os, random, struct
from Crypto.Cipher import AES
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_filename:
Name of the input file
out_filename:
If None, '<in_filename>.enc' will be used.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.enc'
if len(key) < 8:
print('keyは8桁以上にして下さい。') # 安全のため8桁以上に
return
if len(key) % 16 != 0:
key = key + '=' * (16 - (len(key) % 16))
#print(key)
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
def decrypt_file(key, in_filename, out_filename=None, chunksize=24*1024):
""" Decrypts a file using AES (CBC mode) with the
given key. Parameters are similar to encrypt_file,
with one difference: out_filename, if not supplied
will be in_filename without its last extension
(i.e. if in_filename is 'aaa.zip.enc' then
out_filename will be 'aaa.zip')
"""
if not out_filename:
out_filename = os.path.splitext(in_filename)[0]
if len(key) < 8:
print('keyは8桁以上にして下さい。') # 安全のため8桁以上に
return
# キーコードの文字数は16の倍数にする必要があるので足らない分は'='を付け足す
if len(key) % 16 != 0:
key = key + '=' * (16 - (len(key) % 16))
#print(key)
with open(in_filename, 'rb') as infile:
origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(origsize)
# 2016/05/09_1
#===== END cAngo.py =========================================================
0 件のコメント:
コメントを投稿