2014-06-13 74 views
0

我有一個加密/解密類,我正在使用跨平臺。我在服務器和客戶端上使用相同的類。我在Linux服務器上加密文件,然後在Linux或Windows客戶端上解密。我沒有問題,在Linux上解密的時候,但是當我將文件傳輸到Windows,並嘗試解密,我得到以下異常:Pycrypto - 在Linux上加密/在Windows上解密

ValueError異常:輸入的字符串必須是16的倍數長

我的第一個認爲它是由不同的文件系統和用於創建填充的任何字符引起的。這裏是我的類代碼:

class FileSec: 
    def __init__(self): 

     # File chunk size 
     self.chunk_size = 64*1024 

    # Encrypt file with OpenSSL 
    def encrypt(self, infile, outfile, key): 
     if not infile or not os.path.isfile(infile): 
      return False 
     if not outfile or os.path.isfile(outfile): 
      return False 
     if not key: 
      return False 

     # Encrypt the file 
     iv  = ''.join(chr(random.randint(0, 0xFF)) for i in range(16)) 
     encryptor = AES.new(key, AES.MODE_CBC, iv) 
     filesize = os.path.getsize(infile) 
     with open(infile, 'rb') as ifh: 
      with open(outfile, 'wb') as ofh: 
       ofh.write(struct.pack('<Q', filesize)) 
       ofh.write(iv) 
       while True: 
        chunk = ifh.read(self.chunk_size) 
        if len(chunk) == 0: 
         break 
        elif len(chunk) % 16 != 0: 
         chunk += ' ' * (16 - len(chunk) % 16) 
        ofh.write(encryptor.encrypt(chunk)) 
     return True 

    # Decrypt file with OpenSSL 
    def decrypt(self, infile, outfile, key): 
     if not infile or not os.path.isfile(infile): 
      return False 
     if not outfile or os.path.isfile(outfile): 
      return False 
     if not key: 
      return False 

     # Decrypt the file 
     with open(infile, 'rb') as ifh: 
      origsize = struct.unpack('<Q', ifh.read(struct.calcsize('Q')))[0] 
      iv  = ifh.read(16) 
      decryptor = AES.new(key, AES.MODE_CBC, iv) 
      with open(outfile, 'wb') as ofh: 
       while True: 
        chunk = ifh.read(self.chunk_size) 
        if len(chunk) == 0: 
         break 
        ofh.write(decryptor.decrypt(chunk)) 
       ofh.truncate(origsize) 
     return True 

http://pastebin.com/Dvf6nUxH

我使用的是改編自這裏代碼:http://eli.thegreenplace.net/2010/06/25/aes-encryption-of-files-in-python-with-pycrypto/

任何人有我如何可以修改這個類來跨平臺工作有什麼建議?

+0

OT:什麼是'返回False'而不是拋出異常,順便說一句? – Veedrac

回答

0

myfile.read(x)讀取任何數量高達x字節;不保證全部退回x

請注意,它將始終返回至少一個,直到文件爲空,因此可以將其包裝在循環中,然後加入返回的字符串。

+0

如果我理解正確,'ifh.read(16)'不保證讀取16個字節,但最多16個字節,這是有道理的,可能會導致異常。但是從我所知道的情況來看,在加密方法中,它將最後一塊數據寫入並填充到16個字節,以確保加密文件大小以16個字節爲增量。至於返回False vs異常,我在內部調用這個類,並測試True/False值。這是API的一部分,所以我記錄了任何錯誤並返回了帶有錯誤的HTTP響應。 – djtaylor

0

關閉這一個。事實證明,這個問題與加密/解密功能無關,但是當我將其傳輸到Windows機器時,會在加密文件中附加一個額外的字節,導致異常。

相關問題