2017-08-20 47 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