Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python AES编码/解码字符串并存储在MySQL中_Python_Mysql_Encryption_Pyramid_Pycrypto - Fatal编程技术网

Python AES编码/解码字符串并存储在MySQL中

Python AES编码/解码字符串并存储在MySQL中,python,mysql,encryption,pyramid,pycrypto,Python,Mysql,Encryption,Pyramid,Pycrypto,我正在做一个使用Pyramid1.3(Python2.7)并在MySQL中存储数据的项目。我有一个表的电子邮件地址,我想加密他们的存储。我试图在应用程序中加密它们,然后将它们解密以供查看。我不打算完全安全,但主要目的是在数据库本身受损的情况下,对数据进行足够的模糊处理 我将PyCrypto与AES结合使用,并一直在尝试关注这里的一些帖子和我找到的一些web教程。到目前为止,我发现的最接近的方法是,而且似乎有效,至少是对它进行加密。我遵循这一点,并在数据库中存储类似于“7hBAQrWhJRnL9Y

我正在做一个使用Pyramid1.3(Python2.7)并在MySQL中存储数据的项目。我有一个表的电子邮件地址,我想加密他们的存储。我试图在应用程序中加密它们,然后将它们解密以供查看。我不打算完全安全,但主要目的是在数据库本身受损的情况下,对数据进行足够的模糊处理

我将PyCrypto与AES结合使用,并一直在尝试关注这里的一些帖子和我找到的一些web教程。到目前为止,我发现的最接近的方法是,而且似乎有效,至少是对它进行加密。我遵循这一点,并在数据库中存储类似于
“7hBAQrWhJRnL9YdBGJfRErGFwGi3aC6noGzYTrGwAoQ=“
”的内容。但decrypt函数始终出现以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa1 in position 1: ordinal not in range(128)
我遇到了一些关于Python的unicode演示,这在某种程度上帮助我理解了它,但我仍然不断遇到同样的错误

有关于如何编码、存储在数据库中、从数据库中取出以及解码源数据字符串的简单教程吗

我需要数据库列的特定排序规则吗?字段是否需要为特定类型?到目前为止,我一直在使用默认排序规则并将其设置为VARCHAR,假设我正在存储一个字符串。听起来好像我在某些地方遇到了一些编码问题,比如不兼容的类型之类的问题,但我的脑袋一直在转,我需要在哪里修改一些东西

我能提供更好的指示或其他什么吗?我可以显示我的代码,但它基本上是上面链接的副本。。。我只是想在对其进行太多修改之前,让概念验证生效

编辑: 一些样本源。。。 在MySQL中,表是 id(int) 客户id(int) emailaddress varchar(100)utf8mb4_general_ci(我一直在玩排序规则,我不知道它应该是什么!)

Python:

from base64 import b64encode, b64decode, urlsafe_b64decode, urlsafe_b64encode

BLOCK_SIZE = 32
INTERRUPT = u'\u0001'
PAD = u'\u0000'
def AddPadding(data, interrupt, pad, block_size):
    new_data = ''.join([data, interrupt])
    new_data_len = len(new_data)
    remaining_len = block_size - new_data_len
    to_pad_len = remaining_len % block_size
    pad_string = pad * to_pad_len
    return ''.join([new_data, pad_string])
def StripPadding(data, interrupt, pad):
    return data.rstrip(pad).rstrip(interrupt)#data.rsplit(interrupt,1)[0]#rstrip(pad).rstrip(interrupt)

SECRET_KEY = u'a1b2c3d4e5f6g7h8a1b2c3d4e5f6g7h8'
IV = u'12345678abcdefgh'

cipher_for_encryption = AES.new(SECRET_KEY, AES.MODE_CBC, IV)
cipher_for_decryption = AES.new(SECRET_KEY, AES.MODE_CBC, IV)

def EncryptWithAES(encrypt_cipher, plaintext_data):
    plaintext_padded = AddPadding(plaintext_data, INTERRUPT, PAD, BLOCK_SIZE)
    encrypted = encrypt_cipher.encrypt(plaintext_padded)
    return urlsafe_b64encode(encrypted)
def DecryptWithAES(decrypt_cipher, encrypted_data):
    decoded_encrypted_data = urlsafe_b64decode(encrypted_data)
    decrypted_data = decrypt_cipher.decrypt(decoded_encrypted_data)
    return StripPadding(decrypted_data, INTERRUPT, PAD)

#encrypts it
posted_singleaddress = EncryptWithAES(cipher_for_encryption, posted_singleaddress)

#"me@mail.com" inserts "Ktpr49Uzn99HZXbmqEzGKlWo9wk-XBMXGZl_iyna-8c=" into the database
clientemails是上表中的电子邮件列表。我在取消注释时出错:

#if clientemails:
#    decrypted = DecryptWithAES(cipher_for_decryption, clientemails[0].emailaddress)

我只是试着解码第一个项目,只是为了让它工作,但这似乎是让它适合现在的部分…

PyCrypto的一般规则是,加密密钥、IVs、明文、填充和密文应该始终定义为二进制字符串,而不是文本。对它们使用Unicode本身就是问题的根源

另一个问题是您要以十六进制编码形式传递给AES.newkey和IV,因此前者是256位,而后者是128位。这似乎仍然有效,但我猜您的意图是使用AES128,它有一个128位的密钥。因此,您需要将其转换为二进制,例如通过
unexlify
:两个字符串b'34'将映射到单个字节'\x34'。静脉注射需要两倍长

因此,在您的代码中最好有:

from binascii import unhexlify

INTERRUPT = b'\x01'
PAD = b'\x00'
SECRET_KEY = unhexlify('a1b2c3d4e5f6g7h8a1b2c3d4e5f6g7h8')
IV = unhexlify('12345678abcdefgh'*2)
如果您需要对文本进行加密,您可以先对其进行编码(如UTF-8),然后将其传递给函数
EncryptWithAES()
。另请参见以下示例:


加密步骤的结果(即密文)也是一个二进制字符串。为了将其直接存储在MySQL数据库中,您必须使用
BINARY
VARBINARY
类型列。

您可以发布代码中有问题的部分吗?通过添加编辑…您是否验证了
AddPadding
stripppadding
是否按预期工作?第二个定义是“fits”,它会引发异常,还是只会给你错误的数据?如果它抛出异常,异常是什么,我们可以看到回溯吗?我一直得到的错误是“UnicodeDecodeError:'ascii'编解码器无法解码位置1中的字节0xa1:序号不在范围(128)”内。这听起来似乎是比较常见的,是由于ascii和unicode之间的转换或其他原因。回溯看起来像:文件“/home/peter/dev/env/myproj/myproj/views.py”,第320行,在view\u clientemails decrypted=DecryptWithAES(用于解密的密码,email.emailaddress)文件“/home/peter/dev/env/myproj/myproj/views.py”,第114行,DecryptWithAES返回StripPadding(解密的_数据,中断,PAD)文件“/home/peter/dev/env/myproj/myproj/views.py”,第79行,在StripPadding返回数据.rstrip(PAD).rstrip(中断)中
from Crypto.Cipher import AES
from Crypto import Random

key = b'Sixteen byte key'
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')