Python PyCrypto使用AES加密/解密文本文件 [英] Python PyCrypto encrypt/decrypt text files with AES

查看:2546
本文介绍了Python PyCrypto使用AES加密/解密文本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经有一个工作程序,但唯一不起作用的就是我拥有的decrypt_file()函数。我仍然可以从文件中复制加密的文本,并将其放在我的decrypt()函数中,并使其工作,但是当我尝试使用我应该使用的方便的decrypt_file()函数时,会引发错误。现在我知道99.999%确认我的encrypt()和decrypt()函数是正常的,但当我读取和编码引起错误的文本文件时,会有字节和字符串转换的东西;我找不到挂机。请帮助!



我的程序:

 从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 = 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):
unad = 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:]

返回明文

def encrypt_file(file_name,key):
f = open file_name,'r')
plaintext = f.read()
plain text = 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(明文,键)
f.close()
f = open(file_name,'w')
f.write(str(dec))
f。关闭()



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)






文本FIL e加密:

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






尝试 decrypt_file

 追溯(最近的最后一次呼叫):
文件C:\Python33\testing \test\crypto.py,第56行,在< module>
decrypt_file('to_enc.txt',key)
文件C:\Python33\testing\test\crypto.py,第45行,在decrypt_file
plaintext + = ((bytes([x])))* x
TypeError:不能将'bytes'对象转换为str隐式
[在1.5s完成]






当我用以下代码替换第45行: plaintext + =((str ([x]))))* x ,这是我得到的错误:

  (最近呼叫最后):
文件C:\Python33\testing\test\crypto.py,第56行,< module>
decrypt_file('to_enc.txt',key)
文件C:\Python33\testing\test\crypto.py,第46行在decrypt_file
dec = decrypt (明文,键)
文件C:\Python33\testing\test\crypto.py,第23行解密
plaintext = unpad(cipher.decrypt(ciphertext))[ AES.block_size:]
文件C:\Python33\lib\site-packages\Crypto\Cipher\blockalgo.py,第295行解密
return self._cipher .decrypt(ciphertext)
ValueError:输入字符串必须是长度为
的16的倍数[以退出代码1完成1.4s]


解决方案

我仔细看了你的代码,看到有几个问题。第一个是加密功能与字节,而不是文本。所以最好把数据保持为字节串。这可以通过在模式中放置一个b字符来完成。这样,您可以摆脱您尝试做的所有编码和字节转换。



我重写了整个代码也使用较新的Python成语。这里是。

 #!/ 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 =密文[:AES.block_size]
cipher = AES.new(key,AES.MODE_CBC,iv)
plaintext = cipher.decrypt(ciphertext [AES.block_size:])
返回明文

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')作为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)


I already have a working program, but the only thing that doesn't work is the decrypt_file() function I have. I can still copy the encrypted text from the file and put it in my decrypt() function and have it work, but when I try to use my supposed-to-be handy decrypt_file() function it throws an error. Now I know 99.999% sure that my encrypt() and decrypt() functions are fine, but there is something with the bytes and strings conversion when I read and encode the text file that throws an error; I just can't find the hangup. Please help!

My Program:

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)


The text file I encrypted:

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


My error when attempting 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]


When I replace line 45 with: plaintext += ((str(bytes([x])))) * x, this is the error I get:

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]

解决方案

I took a closer look at your code, and saw that there were several problems with it. First one is that the crypto functions with with bytes, not text. So it's better to just keep the data as a byte string. This is done simply by putting a 'b' character in the mode. This way you can get rid of all the encoding and bytes conversion you were trying to do.

I rewrote the whole code also using newer Python idioms. Here it is.

#!/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)

这篇关于Python PyCrypto使用AES加密/解密文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆