【问题标题】:Python UnicodeEncodeError using PyCrypto on App Engine在 App Engine 上使用 PyCrypto 的 Python UnicodeEncodeError
【发布时间】:2011-11-12 23:14:04
【问题描述】:

我正在尝试将加密的查询字符串传递给另一个 URL。

下面的代码给了我这个错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u04b7' in 位置 7:序数不在范围内(128)

加密模块为PyCrypto

在 App Engine 上运行 Python 2.5.2

第 A 页

    import Crypto
    from Crypto.Cipher import ARC4

    obj=ARC4.new('stackoverflow')
    msg = 'This is my secret msg'
    encrypted = obj.encrypt(msg);

    self.redirect('/pageb?' + urllib.urlencode({'q': encrypted}))

第 B 页

    import Crypto
    from Crypto.Cipher import ARC4

    encrypted = self.request.get('q')
    obj=ARC4.new('stackoverflow')
    decrypted = obj.decrypt(encrypted)

    get_data = cgi.parse_qs(decrypted)

    self.response.out.write(decrypted)
    self.response.out.write(pprint.pprint(get_data))

追溯

Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\_webapp25.py", line 701, in __call__
    handler.get(*groups)
  File "C:\Program Files\Google\google_appengine\demos\guestbook\guestbook.py", line 47, in get
    decrypted = obj.decrypt(encrypted)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u04b7' in position 7: ordinal not in range(128)

【问题讨论】:

  • 这似乎是事实陈述,附带最少的抵押品。尝试提出一个问题,由有用的信息(如回溯)支持。
  • @JohnMachin 谢谢,我已经更新了帖子。
  • 信息已经有了,但问题仍然是最好的暗示。
  • 为什么要在自己的应用程序中重定向到另一个 URL,试图在请求之间加密内容,而不是在请求中调用所需的内部 API 位或使用会话控制在服务器端存储敏感信息?这似乎是不必要的复杂。

标签: python google-app-engine


【解决方案1】:

一般准则:在您的加密内容中添加 base64 编码/解码步骤。

import base64

base64_encrypted_message = base64.b64encode(encrypted_message)
// send your message via POST as GET can be seen on system logs

encrypted_message = base64.b64decode(base64_encrypted_message)
// decrypt your message

对于另一个错误,请尝试阅读非 ascii 字符的unicode & utf-8 编码。在将其传递给您的 de/encrypt 函数之前,您需要此步骤。

【讨论】:

  • John Machin 提到了 base64,但你的回答更直接。
【解决方案2】:

所有可以从可用信息中推断出的东西是期待一个字节串,但你已经给它提供了一个包含 Unicode 字符 U+04B7 西里尔小写字母 CHE WITH DESCENDER 的 unicode 对象......这当然不是可以用 ASCII 编码(默认编码),因此会出现错误消息。

迄今为止最好的答案:不要那样做。

更新 1:您还没有提出任何问题。尽管如此:

所以“某物”是一些加密小工具的decrypt 方法。那肯定需要一个str 对象。 print repr(encrypted) 告诉你什么?如果它看起来像随机垃圾(加密的东西应该如此),那么它已经以某种方式从str 对象转换为unicode 对象。您需要回溯以了解这是如何发生的。如果encrypted 看起来像有意义的文本,那么您的加密过程被破坏了。

第 1 步:从一些已知的明文开始,对其进行加密,然后在 GAE 设备外部的一个简单脚本中再次解密。在每个阶段使用 print repr() 以便您对下一步有合理的期望。

第 2 步:使用 GAE 重复第 1 步,检查每条数据的类型和内容。

更新 2 似乎您在 A 页面中有 urlencode,但在 B 页面中没有对应的 urldecode;这是(部分)问题吗?

【讨论】:

  • 我将消息更改为其他内容,“你好”,错误消失了,但我仍然得到解密,它是空的。如何在 URL 之间发送加密消息?我对 python 很陌生(几天前开始)我通常使用 PHP,所以我非常有限。我想这就是 PHP 主导网络的原因,因为它不需要花费数天的研究/头痛来编码/解码一个简单的字符串。
  • 好的,让我试试,然后回复你。谢谢。 PS:我已经尝试过直接输出加密,我确实得到了乱码,包括很多带有问号的黑色菱形字符。
  • 这里是repr的输出(加密):'\xf0"\xfe\xe8I)\x0bxCq\xd1\x1e\xa1v\xc38\xb1\xd2\xb7^\x85'
  • 您在 2 个 URL 之间发送加密消息的方式与在任何地方发送任何字节串的方式相同:适当地防止受到诸如 base64 之类的装甲板的破坏,然后在到达时移除装甲板。您不需要任何语言的“数天的研究/头痛来编码/解码一个简单的字符串”。您确实需要一种用任何语言有条不紊地解决问题的方法。
  • 您的“repr(加密)输出”来自页面 A 或页面 B????什么纯文本输入???它看起来肯定不会在任何地方包含\x04\xb7
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多