Search code examples
windowspython-2.7cryptographypycrypto

PyCrypto: text to decrypt must be a multiple of 16-bytes long


I've tried to do a encryptor program with PyCrypto... It works but some times when I decrypt I give me the error that the text to decrypt must be a multiple of 16-bytes long.

Don't watch the "print" because the language is Italian.

from Crypto.Cipher import AES
from Crypto.Hash import SHA256
import time
print "++++++++++++++++++++++++++++++++++++++++++++++++++"
print "+          PROGRAMMA DI CRITTOGRAFIA             +"
print "+                versione 1.0                    +"
print "++++++++++++++++++++++++++++++++++++++++++++++++++"
def crypt(percorso):
    while 1:
        try:
            print "----------------------------------------------------------"
            print "inserisci la password di encriptazione"
            pasw=raw_input("oppure inserisci undo per tornare al menu principale  ")
            passw=SHA256.new(pasw).hexdigest()
            if len(passw) >= 32 :
                passw=passw[:32]
                f = open(percorso,"r")
                text=f.read()
                f.close
                while len(text)%16 != 0 :
                    text=text+("{")
                iv=passw[:16]
                enk=AES.new(passw,AES.MODE_CBC,iv).encrypt(text)
                f=open(percorso, "w")
                f.write(enk)
                f.close()
                print "Criptazione del file", percorso, "è avvenuta con Successo!"
                time.sleep(3)
                break
            else:
                print "la password inserita non è valida!!!"
                print "prova con una password più lunga..."
                time.sleep(2)
                break
        except :
            print "è avvenuto un errore durante la fase di criptazione."
            print "controllare il File", percorso,"e riprovare"
            time.sleep(2)
            break
def decrypt(percorso):
    while 1:
        try:
            print "----------------------------------------------------------"
            print "inserisci la password di decriptazione"
            pasw=raw_input("oppure inserisci undo per tornare al menu principale  ")
            passw=SHA256.new(pasw).hexdigest()
            if len(passw) >= 32 :
                passw=passw[:32]
                f = open(percorso,"r")
                text=f.read()
                f.close
                print text
                iv=passw[:16]
                dek=AES.new(passw,AES.MODE_CBC,iv).decrypt(text)
                Dek=dek.replace("{","")
                f=open(percorso, "w")
                f.write(Dek)
                f.close()
                print "Deriptazione del file", percorso, "è avvenuta con Successo!"
                time.sleep(3)
                break
            else:
                print "la password inserita non è valida!!!"
                print "prova con una password più lunga..."
                time.sleep(2)
                break
        except :
            print "è avvenuto un errore durante la fase di decriptazione."
            print "controllare il File", percorso,"e riprovare"
            time.sleep(2)
            break
ex= True
while ex == True :
    time.sleep(2)
    print "----------------------------------------------------------"
    prc=raw_input("immettere il percorso del file da criptare  ")
    print "----------------------------------------------------------"
    try:
        f=open(prc,"r")
        f.close()
        while 1:
            command=raw_input("immetti il comando ")
            if command == "help" :
                print "############################"
                print "I comandi sono:"
                print "############################"
                print "    help --> apre la lista dei comandi"
                print "    exit --> chiude il programma"
                print "    undo --> anulla il percorso del file selezionato"
                print "    crypt --> cripta il file selezionato"
                print "    decrypt --> decripta il file selezionato"
            elif command == "undo":
                break
            elif command == "exit":
                ex = False
                break
            elif command == "crypt":
                    crypt(prc)
            elif command == "decrypt":
                    decrypt(prc)
            else:
                print "----------------------------------------------------------"
                print "il comando inserito non è valido, scrivi help per consultare la lista dei comandi"
                time.sleep(2)
    except :
        print "----------------------------------------------------------"
        print "il percorso inserito non è valido"

The problem I think that is only in the decrypt function :

def decrypt(percorso):
    while 1:
        try:
            print "----------------------------------------------------------"
            print "inserisci la password di decriptazione"
            pasw=raw_input("oppure inserisci undo per tornare al menu principale  ")
            passw=SHA256.new(pasw).hexdigest()
            if len(passw) >= 32 :
                passw=passw[:32]
                f = open(percorso,"r")
                text=f.read()
                f.close
                print text
                iv=passw[:16]
                dek=AES.new(passw,AES.MODE_CBC,iv).decrypt(text)
                Dek=dek.replace("{","")
                f=open(percorso, "w")
                f.write(Dek)
                f.close()
                print "Deriptazione del file", percorso, "è avvenuta con Successo!"
                time.sleep(3)
                break
            else:
                print "la password inserita non è valida!!!"
                print "prova con una password più lunga..."
                time.sleep(2)
                break
        except :
            print "è avvenuto un errore durante la fase di decriptazione."
            print "controllare il File", percorso,"e riprovare"
            time.sleep(2)
            break

Solution

  • You need to open the files for reading and writing in binary mode:

    On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files. On Unix, it doesn’t hurt to append a 'b' to the mode, so you can use it platform-independently for all binary files.

    Ciphertext may contain bytes with any value, including non-printable characters and line endings. These bytes may be left out of converted to other sequences if you read them as if they were text.