2011-12-15 50 views
1

我正在web.py中构建应用程序,但是在将加密数据存储在MySQL中时遇到了一些麻烦。MySQL没有正确地存储从PyCrypto库生成的密文

PyCrypto创建看起来像暗号文字:“\x06\x7f\x81\xa0\xf4d\x00H\xef\xd0\x18[c\x18Z\xf8”,它在打印时,显示为‘ôdHïÐ[cZø

然而,MySQL是将其存储为:???d H??[cZ? 我存储它以下述方式:

query_string = "INSERT INTO %s (%s) VALUES (\"%s\")" % (table, column, value) 

我试图用“SET character_set_connection=utf8”连接到数据库后,但没有取得结果中的任何改变。

我明显失去了一些非常重要的东西。有什么想法吗?

+0

你不需要在表格中设置字符编码吗? – Poodlehat 2011-12-16 15:29:55

回答

3

MySQL正在尝试储存您的字节串一个字符列。由于连接字符集是UTF-8,但字节字符串不代表有效的UTF-8序列,因此会发生损坏。

要获得原始字节到数据库正常,你需要:

  1. 使列二进制类型(或一般性格类型与二进制排序),并

  2. 使用参数化查询将数据获取到数据库中,而不是将它们插入查询字符串中,在那里它们可能与非二进制(Unicode)内容混合在一起。

无论如何,您应该使用参数化查询,因为您现在使用的字符串插值无法转义,容易受到SQL注入的影响。在web.py可能看起来像:

query_string= 'INSERT INTO %s (%s) VALUES ($value)' % (table, column) 
db.query(query_string, vars= {'value': value}) 

(假设tablecolumn值已知良好。)

这样做也意味着您不必担心美元符号。

另一种方法是使用正常字符串,将非ASCII字节编码。你在当前的解决方法中使用uucode来做到这一点,但是base64将是一个更为常见的替代方案,在Python中更易于使用(ciphertext.encode('base64'))。十六进制编码(.encode('hex'))在散列情况下最为常见。

+0

哇。感谢您的好解释。我曾尝试将列设置为二进制,但我没有为查询设置参数,所以它仍然存在问题。我会尝试你在这里给我的东西! – 2011-12-19 13:50:06

0

我已经想出了一个解决方案。我不确定它有多优雅,但它是我所能想到的最好的。

ENCODING:

1)import binascii

2)ciphertext = cipher.encrypt(plaintext)

3)asciitext = binascii.b2a_uu(ciphertext)

4)webpy_workaround = asciitext.replace('$', 'DOLLARSIGN') //if there are dollar signs in the text, webpy will try to use anything afterward, and will complain at you.

5)店铺webpy_workaround到SQL。

解码:

1)从SQL

检索值

2)asciitext = sql_value.replace('DOLLARSIGN', '$')

3)ciphertext = binascii.a2b_uu(asciitext)

4)plaintext = cipher.decrypt(ciphertext)

相关问题