2017-08-20 81 views
0

我試圖用兩個Python文件加密和解密5-14 MB文本文件,其中一個包含加密/解密方法,另一個包含加密/解密方法,另一個則是這些方法的運行者。PyCrypto AES在幾行處理輸入後突然停止解密

這裏的類文件:

from Crypto.Cipher import AES 
from Crypto import Random 
import sys 
import codecs 
reload(sys) 
sys.setdefaultencoding('utf8') 
sys.stdout = codecs.getwriter('utf8')(sys.stdout) 

class Crypt: 
    def __init__(self, encrypted, key): 
     self.message = encrypted 
     self.key = key 

    def encrypt(self): 
     iv = Random.new().read(AES.block_size) 
     if len(self.message) % AES.block_size != 0: 
      self.message += " " * (AES.block_size - (len(self.message) % AES.block_size)) 

     lenKey = len(self.key) 
     if lenKey > 32: 
      self.key = self.key[:32] 

     cipher = AES.new(self.key, AES.MODE_CFB, iv) 
     return iv + cipher.encrypt(self.message) 

    def decrypt(self): 
     iv, message = (self.message[:AES.block_size], self.message[AES.block_size:]) 
     if len(message) % AES.block_size != 0: 
      message += " " * (AES.block_size - (len(message) % AES.block_size)) 

     lenKey = len(self.key) 
     if lenKey > 32: 
      self.key = self.key[:32] 

     cipher = AES.new(self.key, AES.MODE_CFB, iv) 
     return cipher.decrypt(message).strip() 

這裏的亞軍:

import crypt_classes 
from Crypto.Hash import SHA256 
import sys 
reload(sys) 
sys.setdefaultencoding('utf8') 

h = SHA256.new() 
while True: 
    choice = raw_input("Encrypt [1] or decrypt [2]? ").strip() 
    if choice != "1" and choice != "2": 
     print "Invalid choice, please try again." 
     continue 
    key = "" 
    first = "" 
    confirm = "" 
    while True: 
     first = raw_input("Enter passphrase (>= 32 chars): ").strip() 
     # confirm = raw_input("Confirm passphrase: ").strip() 
     confirm = first 
     if first == confirm and len(confirm) >= 32: 
      h.update(first) 
      key = h.hexdigest() 
      break 
     else: 
      print "Passphrases did not match or were shorter than 32 characters. Try again." 
      continue 
    if choice == "1": 
     f = open("encrypted.txt", "w") 
     h = open("source.txt", "r") 
     message = h.read() 
     h.close() 
     encrypter = crypt_classes.Crypt(message, key) 
     e = encrypter.encrypt() 
     f.write(e) 
     f.close() 
     break 
    elif choice == "2": 
     f = open("encrypted.txt", "r") 
     encrypted = f.read() 
     f.close() 
     decrypter = crypt_classes.Crypt(encrypted, key) 
     w = open("decrypted.txt", "w") 
     o = decrypter.decrypt() 
     w.write(o) 
     w.close() 
     break 

加密工作正常,但作爲文件被解密,程序表面上完成,只有幾行所示該文件以及其他一些 字符,如下所示:

# This data file generated by 23andMe at: Thu May 22 15:47:06 2008 
# 
# Below is a text version of your data. Fields are TAB-separated 
# Each line corresponds to a single SNP. For each SNP, we provide its identifier 
# (an rsid or an internal id), its lU� 

沒有錯誤引發,我不知道爲什麼整個文件(幾MB)不解密。我很感激任何幫助,請原諒任何草率的代碼或缺乏解釋;我是新來的。如果需要進一步闡述,請發表評論。

謝謝!

+0

UTF8輸出似乎並不像對加密數據是個好主意。 –

+0

爲什麼你需要這個類?只需在AES類的跑步者內部進行即可。採用十六進制的 –

+0

是一個壞主意。 Juse ust .digest如果您必須使用SHA256 .. –

回答

1

只需使用簡單的功能。我認爲這裏不需要上課。

以十六進制消化,然後截斷,使有效keylength 128 ,而你似乎想256

不要寫加密的數據爲UTF8。不要在CFB模式下使用填充。

我的嘗試(在我的系統上工作);如果你喜歡,你可以把加密和解密函數的導入放在一個單獨的文件(模塊)中。

from Crypto.Hash import SHA256 
from Crypto.Cipher import AES 
from Crypto import Random 
import sys 

def encrypt_data(data, key): 
    iv=Random.new().read(AES.block_size) 
    aes=AES.new(key, AES.MODE_CFB, iv) 
    return iv+aes.encrypt(data) 

def decrypt_data(data, key): 
    iv = data[:16] 
    data = data[16:] 
    aes=AES.new(key, AES.MODE_CFB, iv) 
    return aes.decrypt(data) 

h = SHA256.new() 
while True: 
    choice = raw_input("Encrypt [1] or decrypt [2]? ").strip() 
    if choice != "1" and choice != "2": 
     print "Invalid choice, please try again." 
     continue 
    key = "" 
    first = "" 
    confirm = "" 
    while True: 
     first = raw_input("Enter passphrase (>= 32 chars): ").strip() 
     # confirm = raw_input("Confirm passphrase: ").strip() 
     confirm = first 
     if first == confirm and len(confirm) >= 32: 
      h.update(first) 
      key = h.digest() 
      break 
     else: 
      print "Passphrases did not match or were shorter than 32 characters. Try again." 
      continue 
    if choice == "1": 
     f = open("encryptedDNA.txt", "w") 
     h = open("genome_Mikolaj_Habryn_20080522154706.txt", "r") 
     message = h.read() 
     h.close() 
     encmessage = encrypt_data(message, key) 
     f.write(encmessage) 
     f.close() 
     break 
    elif choice == "2": 
     f = open("encryptedDNA.txt", "r") 
     encrypted = f.read() 
     f.close() 
     decrypted = decrypt_data(encrypted,key) 
     w = open("decryptedDNA.txt", "w") 
     w.write(decrypted) 
     w.close() 
     break