usar mensaje libreria encriptar con como cifrar archivos algoritmo python file encryption aes pycrypto

mensaje - encriptar md5 python



Python PyCrypto cifra/descifra archivos de texto con AES (2)

Ya tengo un programa en funcionamiento, pero lo único que no funciona es la función decrypt_file () que tengo. Todavía puedo copiar el texto cifrado del archivo y ponerlo en mi función de descifrado () y hacer que funcione, pero cuando intento utilizar mi función de descifrar () práctica que se supone que será útil, arroja un error. Ahora sé que tengo un 99,999% de certeza de que mis funciones encrypt () y decrypt () están bien, pero hay algo con la conversión de bytes y cadenas cuando leo y codigo el archivo de texto que arroja un error; Simplemente no puedo encontrar el hangup. ¡Por favor ayuda!

Mi programa:

from Crypto import Random from Crypto.Cipher import AES def encrypt(message, key=None, key_size=256): def pad(s): x = AES.block_size - len(s) % AES.block_size return s + ((bytes([x])) * x) padded_message = pad(message) if key is None: key = Random.new().read(key_size // 8) iv = Random.new().read(AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) return iv + cipher.encrypt(padded_message) def decrypt(ciphertext, key): unpad = lambda s: s[:-s[-1]] iv = ciphertext[:AES.block_size] cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = unpad(cipher.decrypt(ciphertext))[AES.block_size:] return plaintext def encrypt_file(file_name, key): f = open(file_name, ''r'') plaintext = f.read() plaintext = plaintext.encode(''utf-8'') enc = encrypt(plaintext, key) f.close() f = open(file_name, ''w'') f.write(str(enc)) f.close() def decrypt_file(file_name, key): def pad(s): x = AES.block_size - len(s) % AES.block_size return s + ((str(bytes([x]))) * x) f = open(file_name, ''r'') plaintext = f.read() x = AES.block_size - len(plaintext) % AES.block_size plaintext += ((bytes([x]))) * x dec = decrypt(plaintext, key) f.close() f = open(file_name, ''w'') f.write(str(dec)) f.close() key = b''/xbf/xc0/x85)/x10nc/x94/x02)j/xdf/xcb/xc4/x94/x9d(/x9e[EX/xc8/xd5/xbfI{/xa2$/x05(/xd5/x18'' encrypt_file(''to_enc.txt'', key)

El archivo de texto que cifré:

b'';c/xb0/xe6Wv5!/xa3/xdd/xf0/xb1/xfd2/x90B/x10/xdf/x00/x82/x83/x9d/xbc2/x91/xa7i M/x13/xdc/xa7''

Mi error al intentar decrypt_file :

Traceback (most recent call last): File "C:/Python33/testing/test/crypto.py", line 56, in <module> decrypt_file(''to_enc.txt'', key) File "C:/Python33/testing/test/crypto.py", line 45, in decrypt_file plaintext += ((bytes([x]))) * x TypeError: Can''t convert ''bytes'' object to str implicitly [Finished in 1.5s]

Cuando reemplazo la línea 45 con: plaintext += ((str(bytes([x])))) * x , este es el error que obtengo:

Traceback (most recent call last): File "C:/Python33/testing/test/crypto.py", line 56, in <module> decrypt_file(''to_enc.txt'', key) File "C:/Python33/testing/test/crypto.py", line 46, in decrypt_file dec = decrypt(plaintext, key) File "C:/Python33/testing/test/crypto.py", line 23, in decrypt plaintext = unpad(cipher.decrypt(ciphertext))[AES.block_size:] File "C:/Python33/lib/site-packages/Crypto/Cipher/blockalgo.py", line 295, in decrypt return self._cipher.decrypt(ciphertext) ValueError: Input strings must be a multiple of 16 in length [Finished in 1.4s with exit code 1]


En Python 3 (que está claramente usando), el modo predeterminado para los archivos que abre es texto, no binario. Cuando lee del archivo, obtiene cadenas en lugar de matrices de bytes. Eso no concuerda con el cifrado.

En tu código, debes reemplazar:

open(file_name, ''r'')

con:

open(file_name, ''rb'')

Lo mismo para cuando abre el archivo para escribir. En ese punto, puede deshacerse de todas las diversas ocurrencias donde se convierte de cadena a binario y viceversa.

Por ejemplo, esto puede desaparecer:

plaintext = plaintext.encode(''utf-8'')


Eché un vistazo más de cerca a tu código y vi que había varios problemas con él. El primero es que la criptografía funciona con bytes, no con texto. Por lo tanto, es mejor mantener los datos como una cadena de bytes. Esto se hace simplemente colocando un carácter ''b'' en el modo. De esta forma puede deshacerse de toda la conversión de codificación y bytes que estaba tratando de hacer.

Reescribí todo el código también utilizando los nuevos modismos de Python. Aquí está.

#!/usr/bin/python3 from Crypto import Random from Crypto.Cipher import AES def pad(s): return s + b"/0" * (AES.block_size - len(s) % AES.block_size) def encrypt(message, key, key_size=256): message = pad(message) iv = Random.new().read(AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) return iv + cipher.encrypt(message) def decrypt(ciphertext, key): iv = ciphertext[:AES.block_size] cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(ciphertext[AES.block_size:]) return plaintext.rstrip(b"/0") def encrypt_file(file_name, key): with open(file_name, ''rb'') as fo: plaintext = fo.read() enc = encrypt(plaintext, key) with open(file_name + ".enc", ''wb'') as fo: fo.write(enc) def decrypt_file(file_name, key): with open(file_name, ''rb'') as fo: ciphertext = fo.read() dec = decrypt(ciphertext, key) with open(file_name[:-4], ''wb'') as fo: fo.write(dec) key = b''/xbf/xc0/x85)/x10nc/x94/x02)j/xdf/xcb/xc4/x94/x9d(/x9e[EX/xc8/xd5/xbfI{/xa2$/x05(/xd5/x18'' encrypt_file(''to_enc.txt'', key) #decrypt_file(''to_enc.txt.enc'', key)