我有一个程序尝试使用es加密消息。当我必须加密消息并且得到TypeError: Object type <class 'str'> cannot be passed to C code
时,就会出现问题。我发现,如果我将其编码为utf-8,则可以使用,但是当我尝试对其进行解密时,它并不会摆脱b'...',并且base64解密失败,这使我的iv不再是16个字节。每当我尝试使用aes.decrypt(file.readline().decode("utf-8"))
解码文件的第一行时,它都说我不能在str上使用解码。
from Crypto.Cipher import AES
from Crypto import Random
def pad(s):
pad = s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
return str(pad)
def unpad(s):
unpad = s[:-ord(s[len(s)-1:])]
return str(unpad)
class AESCipher:
def __init__( self, key ):
self.key = key
def encrypt( self, s ):
raw = pad(s)
iv = Random.new().read( AES.block_size )
cipher = AES.new( self.key, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw.encode("utf-8") ) )
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] ))
我是加密技术的新手,所以我真的不知道以前是否已经回答过这个问题,而且我只是不知道该怎么写,但是我已经环顾了几个小时,却没有发现任何东西。 谢谢。 再次,抱歉,如果措词不正确。
答案 0 :(得分:4)
您的加密和解密操作不是彼此的镜像。
def encrypt( self, s ):
iv = Random.new().read( AES.block_size ) # new IV
cipher = AES.new( self.key, AES.MODE_CBC, iv ) # create cipher
payload = s.encode("utf-8") # string to bytes
encrypted = cipher.encrypt(pad(payload)) # pad before encrypt
return base64.b64encode( iv + encrypted ) # b64 data
def decrypt( self, enc ):
data = base64.b64decode( enc ) # b64 data
iv = data[:AES.block_size] # split it up
encrypted = data[AES.block_size:] #
cipher = AES.new(self.key, AES.MODE_CBC, iv ) # recreate cipher
payload = unpad(cipher.decrypt( encrypted )) # unpad after decrypt
return payload.decode("utf8") # bytes to string
只能对字节进行加密。字符串不是字节,因此必须先将字符串编码为字节表示形式。 UTF-8是合适的表示形式,但可以是UTF-16甚至是UTF-32(read about the differences)。
但是,由于密码可以处理任何个字节的有效负载,因此我将删除当前将这些功能限制为字符串的部分。我将其更改为期望并返回字节,然后:
x = aes.encrypt(s.encode('utf8'))
和s = aes.decrypt(x).decode('utf8')
,或对于加密文件,您可以直接执行以下操作:
with open('some.txt', 'rb') as fp:
encrypted = aes.encrypt(fp.read())
这根本不会强加任何编码假设,但是会照原样加密文件的字节。
AES是一种分组密码,表示encrypt(a) + encrypt(b)
与encrypt(a + b)
相同。对于加密文件非常有用,因为您可以N * AES.block_size
中的read the file incrementally in chunks,仅填充最后一个块。这比先将整个文件读入内存要高得多的内存效率。您当前的encrypt
和decrypt
设置没有使用它。