如何从文件中解码 utf-8
How do I decode utf-8 from a file
我有一个程序试图使用 aes 加密消息。当我必须加密消息并得到 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:] ))
我是加密新手,所以我真的不知道以前是否有人回答过这个问题,我只是不知道如何表达,但我已经四处寻找几个小时了,还没有'没找到任何东西。
谢谢你。
再次抱歉,如果措辞不当。
您的加密和解密操作不是彼此的镜像。
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)。
但是,由于密码可以处理 任何 字节有效负载,我将删除目前将这些函数限制为字符串的部分。我会将它们更改为 expect 和 return 字节,然后是:
- 分别称它们为
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)
相同。对于加密文件非常有用,因为您可以 read the file incrementally in chunks of N * AES.block_size
,只填充最后一个块。这比先将整个文件读入内存更节省内存。您当前的 encrypt
和 decrypt
设置没有使用它。
我有一个程序试图使用 aes 加密消息。当我必须加密消息并得到 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:] ))
我是加密新手,所以我真的不知道以前是否有人回答过这个问题,我只是不知道如何表达,但我已经四处寻找几个小时了,还没有'没找到任何东西。 谢谢你。 再次抱歉,如果措辞不当。
您的加密和解密操作不是彼此的镜像。
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)。
但是,由于密码可以处理 任何 字节有效负载,我将删除目前将这些函数限制为字符串的部分。我会将它们更改为 expect 和 return 字节,然后是:
- 分别称它们为
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)
相同。对于加密文件非常有用,因为您可以 read the file incrementally in chunks of N * AES.block_size
,只填充最后一个块。这比先将整个文件读入内存更节省内存。您当前的 encrypt
和 decrypt
设置没有使用它。