在電腦世界里只有二進位。唯有人類才會對數據進行類型與價值判斷。例如,認為某些文件是文本文件、是WORD/EXCEL文件或者是圖片。對於加密演算法來說也是一樣的,加解密演算法處理的只是位元組流,根本不關心所謂的文件類型。 ...
在電腦世界里只有二進位。唯有人類才會對數據進行類型與價值判斷。例如,認為某些文件是文本文件、是WORD/EXCEL文件或者是圖片。對於加密演算法來說也是一樣的,加解密演算法處理的只是位元組流,根本不關心所謂的文件類型。對於文件來說,存在以下基本操作: ◆ open ◆ close ◆ read ◆ write ◆ delete 在Unix世界中,更是將文件這一概念發揮到極致,認為萬物都是文件,都可以用基本類似的方式來打開,也就是所謂的原語。python也不例外,提供了內置的文件操作函數。下麵的代碼就演示瞭如何將word文檔進行加密。假設我們用WORD文檔寫了一段文字,內容如下圖所示。
這當然是一首曹操的名詩,我們使用AES演算法來加解密。AES是一種十分成熟、安全、國際通用的對稱密碼的加密解密演算法,供AES加密解密的重要參數就是密鑰。這個密鑰只是一個隨機字元串,通常是128位或256位字長。AES加密解密所用的密鑰與其它密碼演算法沒有任何區別。廢話不說,直接上代碼。
import os import struct from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad defaultsize = 64*1024 def encrypt_file(key, in_filename, out_filename=None, chunksize=defaultsize): """ 對文件進行加密 Args: key (str): 16位元組密鑰 in_filename (str): 待加密文件 out_filename (str, optional): 加密後輸出的文件 chunksize (int, optional): 塊大小,預設64k """ if not out_filename: out_filename = in_filename + '.enc' iv = os.urandom(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) pos = 0 while pos < filesize: chunk = infile.read(chunksize) pos += len(chunk) if pos == filesize: chunk = pad(chunk, AES.block_size) outfile.write(encryptor.encrypt(chunk)) def decrypt_file(key, in_filename, out_filename=None, chunksize=defaultsize): """ 解密文件 Args: key (str): 16位元組密鑰 in_filename (str): 待解密文件 out_filename (str, optional): 解密後輸出的文件 chunksize (int, optional): 塊大小,預設64K """ if not out_filename: out_filename = in_filename + '.dec' with open(in_filename, 'rb') as infile: filesize = struct.unpack('<Q', infile.read(8))[0] iv = infile.read(16) encryptor = AES.new(key, AES.MODE_CBC, iv) with open(out_filename, 'wb') as outfile: encrypted_filesize = os.path.getsize(in_filename) pos = 8 + 16 # the filesize and IV. while pos < encrypted_filesize: chunk = infile.read(chunksize) pos += len(chunk) chunk = encryptor.decrypt(chunk) if pos == encrypted_filesize: chunk = unpad(chunk, AES.block_size) outfile.write(chunk) # 密鑰,隨便寫,使用時只使用前16位元組 key = 'stayhungrystayfoolish' def test_enc(): sourcefilename=r'../resources/神龜雖壽.docx' encrypt_file(key[:16].encode('utf-8'), sourcefilename) def test_dec(): sourcefilename=r'../resources/神龜雖壽.docx.enc' targetfilename=r'../resources/decrypt.docx' decrypt_file(key[:16].encode('utf-8'), sourcefilename,out_filename=targetfilename) if __name__ == '__main__': test_enc() test_dec()
我們這裡使用128位密鑰進行加解密,加密後的文件微軟的WORD也打不開,內部結構已經完全改變,而解密後文件與原文檔沒有區別。從代碼可以看出,本文提供的對文件的加解密與文件類型沒有關係,完全可以用此演算法對音樂、視頻等進行加解密,如果再配合使用QT等開發工具,可以進一步升級為易於使用的GUI界面的文件加解密器。補充一點,上述的加解密演算法庫需要安裝對應的包,使用以下命令即可。
pip install PyCryptodome