1

web.pyでアプリケーションを構築していますが、暗号化されたデータをMySQLに保存する際に問題が発生しています。

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ましたが、結果に変化はありませんでした。

私は明らかに非常に重要な何かを見逃しています。何かご意見は?

4

2 に答える 2

3

MySQL is trying to store your byte string in a character column. Because the connection character set is UTF-8 but the byte string doesn't represent a valid UTF-8 sequence, it gets mangled.

To get raw bytes into the database properly you need to:

  1. make the column a BINARY type (or generally character type with a binary collation), and

  2. use parameterised queries to get the data into the database instead of interpolating them into the query string where they might mix with non-binary (Unicode) content.

You should use parameterised queries anyway because the string interpolation you're using now, with no escaping, is vulnerable to SQL injection. In web.py that might look like:

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

(assuming that the table and column values are known-good.)

Doing it like this also means you don't have to worry about the dollar sign.

The other approach is to use a normal character string, encoding away the non-ASCII bytes. You're doing this with uucode in your current workaround, but base64 would be a more common alternative that's easier to get to in Python (ciphertext.encode('base64')). Hex encoding (.encode('hex')) is most common for the case of a hash.

于 2011-12-17T16:39:02.833 に答える
0

私は解決策を見つけました。それがどれほどエレガントかはわかりませんが、私が理解できる最高のものでした。

エンコーディング:

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)

于 2011-12-16T14:55:39.357 に答える