質問

I am running into the issue of my decrypt_file function unable to decrypt text which was encrypted, No errors are provided just unexpected returns.

The encryption function uses salt and a password to encrypt a text file, then saves it as a .enc file, Then after attempting to run my decrypt_file function, it identifies the salt, iv, password, iterations, ect but does not decrypt() properly. Here is the code. And a dry run. Any guidance or help would be appreciated.

Encryption/Decryption:

from Crypto import Random
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from os import urandom
import hashlib

def key_generation(password, salt, iterations):
    assert iterations > 0
    print "Salt: " + salt, '\n', "Password: " + password
    key = password + salt #Combines [password] and [salt] to create a [key]
    for i in range(iterations): #Hashes the [key]
        key = hashlib.sha256(key).digest() #Using Sha256 it hashes the [key] based on amount of [iterations]
    print '\nKey: ' + key #Debug Print
    return key

def pad(s):
    return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

def encryption(message, password, salt, iterations, key_size=256):
    key = key_generation(password, salt, iterations)
    message = pad(message)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    print "Random IV: " + iv
    enc = salt + iv + cipher.encrypt(message)
    print "Length: " + str(len(enc))
    enc = pad(enc)
    print "Length: " + str(len(enc))
    return enc


def decryption(ciphertext, password, iterations):
    salt = ciphertext[0:16]
    iv = ciphertext[:AES.block_size]
    print len(str(iv))
    print len(str(salt))
    key = key_generation(password, salt, iterations)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext[AES.block_size:])
    print "Plaintext: " + plaintext
    return plaintext.rstrip(b"\0")

def encrypt_file(file_name, password, salt, iterations):
    with open(file_name, 'rb') as fo:
        plaintext = fo.read()
        print "Text: " + plaintext
    enc = encryption(plaintext, password, salt, iterations)
    print "Encrypted Contents: " + enc
    with open(file_name + ".enc", 'wb') as fo:
        fo.write(enc)

def decrypt_file(file_name, password, iterations):
    with open(file_name, 'rb') as fo:
        ciphertext = fo.read()
        print "Cipher'd Text: " + ciphertext
    dec = decryption(ciphertext, password, iterations)
    with open(file_name[:-4], 'wb') as fo:
        fo.write(dec)

encrypt_file('HelloWorld.txt', 'password', 'randomsalt', 64000)
decrypt_file('HelloWorld.txt.enc', 'password', 64000)

Dry Run:

Encrypt:

Text: }¦—Z“Íd¥çgZw?øÈH™«Nœfra¥)ÊãjnÞª»^}K^Ì„¦ý
×¾Šv“_3w€mG9‚ä¤Å¥žUƯ0£Óy®0²
nrfÖÖ «–‰¯ò
Salt: randomsalt 
Password: password

Key: /Îbdヘ5è!ニヒAᆰv=L*øK/ò)Ü
Random IV: eミý1ËÈUÓbIワᄡムl
Length: 138
Length: 144
Encrypted Contents: randomsalteミý1ËÈUÓbIワᄡムl$֭>oリ)<L゙y\I!%wÙßÞlモÊJt$ワ
è   Ì-ᄈMᄀ8ヘ!ᄚܩᄃÆ4ÒO9AÃðO.ä3}ヘål{ヌヒ@ÿËzᄋgDᆰ\éUʼaà8タLᅠMupaÔAミマX0ンᄉi3ヨ˧cᄃ;ᆱÛo

Decrypt:

Cipher'd Text: randomsalteミý1ËÈUÓbIワᄡムl$֭>oリ)<L゙y\I!%wÙßÞlモÊJt$ワ
è   Ì-ᄈMᄀ8ヘ!ᄚܩᄃÆ4ÒO9AÃðO.ä3}ヘål{ヌヒ@ÿËzᄋgDᆰ\éUʼaà8タLᅠMupaÔAミマX0ンᄉi3ヨ˧cᄃ;ᆱÛo
16
16
Salt: randomsalteミý1Ë 
Password: password

Key: 1ÜA !TzxGÑ`wß~|º‹|¡(—ª-%òÇŒÖ
Plaintext: Rネ*SᄊÕñÛ.
t-Îテýト͛'úᄎSタ&2ᆴæマéヌᄏýýᄑtçØÉe?×ûìrモᄈÞcᄎᄇ×_Kメ
ᄎÀ~ä'ᄅ,ᄉ-Èᄀt&gSð:WÕ|
メ^リøᄃ]ノヤÏYvísgl/ᆵレホ*`\ᄚåᄌŴÇlヒÓ!Â`゚
役に立ちましたか?

解決

So please print things out in hexadecimals. You can then clearly see that indeed during decrypt that the salt and IV were overlapping. In your code you were also assuming a different length salt than that was given.

from Crypto import Random
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from os import urandom
import hashlib
import binascii


def key_generation(password, salt, iterations):
    assert iterations > 0
    print "Salt: " + tohex(salt), '\n', "Password: " + password
    key = password + salt #Combines [password] and [salt] to create a [key]
    for i in range(iterations): #Hashes the [key]
        key = hashlib.sha256(key).digest() #Using Sha256 it hashes the [key] based on amount of [iterations]
    return key

def pad(s):
    return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

def encryption(message, password, salt, iterations, key_size=256):

    print " === ENCRYPTION === "

    key = key_generation(password, salt, iterations)
    print "Key: " + tohex(key)
    message = pad(message)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    print "Random IV: " + tohex(iv)
    enc = salt + iv + cipher.encrypt(message)
    return enc


def decryption(ciphertext, password, iterations):

    print " === DECRYPTION === "

    salt = ciphertext[0:10]
    iv = ciphertext[10:10+AES.block_size]
    print "Random IV: " + tohex(iv)
    key = key_generation(password, salt, iterations)
    print "Key: " + tohex(key)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext[10+AES.block_size:])
    print "Plaintext: " + plaintext
    return plaintext.rstrip(b"\0")

def encrypt_file(file_name, password, salt, iterations):
    with open(file_name, 'rb') as fo:
        plaintext = fo.read()
        print "Text: " + plaintext
    enc = encryption(plaintext, password, salt, iterations)
    print "Encrypted Contents: " + enc
    with open(file_name + ".enc", 'wb') as fo:
        fo.write(enc)

def decrypt_file(file_name, password, iterations):
    with open(file_name, 'rb') as fo:
        ciphertext = fo.read()
        print "Cipher'd Text: " + ciphertext
    dec = decryption(ciphertext, password, iterations)
    with open(file_name + ".dec", 'wb') as fo:
        fo.write(dec)

def tohex(data):
    return binascii.hexlify(data)

encrypt_file('HelloWorld.txt', 'password', 'randomsalt', 64000)
decrypt_file('HelloWorld.txt.enc', 'password', 64000)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top