【问题标题】:Django urlsafe base64 decoding with decryptionDjango urlsafe base64 解码和解密
【发布时间】:2010-02-09 14:39:17
【问题描述】:

我正在为用户注册编写自己的验证码系统。所以我需要创建一个合适的 URL 来接收生成的验证码图片。生成看起来像这样:

_cipher = cipher.new(settings.CAPTCHA_SECRET_KEY, cipher.MODE_ECB)
_encrypt_block = lambda block: _cipher.encrypt(block + ' ' * (_cipher.block_size - len(block) % _cipher.block_size)) 
#...
a = (self.rightnum, self.animal_type[1])
serialized = pickle.dumps(a)
encrypted = _encrypt_block(serialized)
safe_url = urlsafe_b64encode(encrypted)

然后我试图通过视图函数中的 GET 请求接收此密钥,它在 urlsafe_b64decode() 上失败,并出现“字符映射必须返回整数、无或 unicode”错误:

def captcha(request):
  try:
    key = request.REQUEST['key']
    decoded = urlsafe_b64decode(key)
    decrypted = _decrypt_block(decoded)
    deserialized = pickle.loads(decrypted)
    return HttpResponse(deserialized)
  except KeyError: 
    return HttpResponseBadRequest()

我发现在 urlsafe_b64encode 的输出上有一个 str,但是 GET 请求返回一个 unicode 对象(尽管它是一个正确的字符串)。 Str() 没有帮助(它在 django 深处返回解码错误),如果我使用 key.repr 它可以工作,但解密器无法使用错误“输入字符串必须是倍数长度为 16”。 在一个测试文件中,所有这些构造都完美运行,我不明白,有什么问题?

【问题讨论】:

  • 加密有必要吗?验证码的生成不能在会话数据服务器端存储正确的答案吗?还是您想避免这种情况?
  • 只是还没想好。但这个问题很有趣,我想了解它发生的原因。
  • key = str(request.REQUEST['key']) 不起作用?
  • 它返回一个错误:文件“/usr/lib/pymodules/python2.6/django/http/__init__.py”,第 365 行,在 _get_content return smart_str(''.join(self. _container), self._charset) TypeError: sequence item 0: expected string, int found

标签: python django encryption encoding base64


【解决方案1】:

问题是 b64decode 非常明确地只能接受字节(字符串),而不是 unicode。

>>> import base64
>>> test = "Hi, I'm a string"
>>> enc = base64.urlsafe_b64encode(test)
>>> enc
'SGksIEknbSBhIHN0cmluZw=='
>>> uenc = unicode(enc)
>>> base64.urlsafe_b64decode(enc)
"Hi, I'm a string"
>>> base64.urlsafe_b64decode(uenc)
Traceback (most recent call last):
...
TypeError: character mapping must return integer, None or unicode

由于您知道您的数据仅包含 ASCII 数据(这是 base64encode 将返回的内容),因此将 unicode 代码点编码为 ASCII 或 UTF-8 字节应该是安全的,这些字节将等同于您期望的 ASCII。

>>> base64.urlsafe_b64decode(uenc.encode("ascii"))
"Hi, I'm a string"

【讨论】:

  • 这有助于解决我在 python 网络服务器中遇到的相关问题。
  • “你知道你的数据只包含 ASCII 数据”——这就是我写.encode("ascii")的原因。
  • 是的,“ascii”会更好。已更新。
【解决方案2】:

我解决了这个问题!

deserialized = pickle.loads(captcha_decrypt(urlsafe_b64decode(key.encode('ascii'))))
return HttpResponse(str(deserialized))

但我还是不明白,为什么第一次没有成功。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2018-03-13
    • 2019-06-27
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多