Python 解密烧瓶应用程序密钥

Python 解密烧瓶应用程序密钥,python,flask,Python,Flask,如果未设置app.secret\u key,Flask将不允许您设置或访问会话字典 这就是关于这个问题的全部内容 我对web开发非常陌生,我不知道任何安全性东西是如何工作的。我想知道烧瓶在引擎盖下做什么 为什么Flask强制我们设置此密钥属性 Flask如何使用密钥属性 任何需要加密(为了安全防止攻击者篡改)的内容都需要设置密钥。就Flask本身而言,“anything”就是会话对象,但其他扩展可以使用相同的秘密 secret\u key只是为secret\u key配置密钥设置的值,也可以直

如果未设置
app.secret\u key
,Flask将不允许您设置或访问会话字典

这就是关于这个问题的全部内容

我对web开发非常陌生,我不知道任何安全性东西是如何工作的。我想知道烧瓶在引擎盖下做什么

  • 为什么Flask强制我们设置此
    密钥
    属性
  • Flask如何使用
    密钥
    属性

任何需要加密(为了安全防止攻击者篡改)的内容都需要设置密钥。就Flask本身而言,“anything”就是
会话
对象,但其他扩展可以使用相同的秘密

secret\u key
只是为
secret\u key
配置密钥设置的值,也可以直接设置

对于应该设置什么样的服务器端机密,有很好的、明智的建议

加密依赖于秘密;如果您没有为加密设置服务器端机密,每个人都可以破坏您的加密;这就像是你电脑的密码。秘密加上要签名的数据用于创建签名字符串,这是使用;只有当您拥有完全相同的机密和原始数据时,您才能重新创建此值,让Flask检测是否有任何内容未经允许被更改。由于发送给客户机的数据中从不包含秘密,因此客户机不能篡改会话数据并希望生成新的有效签名


烧瓶用瓶子做所有的苦工;会话将与自定义JSON序列化程序一起使用。

下面的答案主要涉及签名cookie,这是会话概念的一种实现(在web应用程序中使用)。Flask同时提供普通(未签名)cookie(通过
request.cookies
response.set\u cookie()
)和签名cookie(通过
Flask.session
)。答案分为两部分,第一部分描述如何生成签名Cookie,第二部分以QA的形式呈现,以解决方案的不同方面。示例使用的语法是Python3,但这些概念也适用于以前的版本

什么是
SECRET\u KEY
(或者如何创建签名Cookie)? 签署cookie是防止cookie篡改的一种预防措施。在对cookie签名的过程中,
SECRET\u KEY
的使用方式类似于在散列密码之前使用“salt”来混淆密码。下面是对这个概念的(非常)简化的描述。示例中的代码旨在说明问题。许多步骤都被省略了,而且并非所有函数都存在。这里的目标是提供对总体思路的理解,实际实现将更加复杂。另外,请记住,Flask在后台为您完成了大部分工作。因此,除了为cookie设置值(通过会话API)并提供一个
密钥
,自己重新实现这一点不仅是不明智的,而且没有必要这样做:

穷人的饼干签名 在向浏览器发送响应之前: (1)首先建立
密钥。它应该只为应用程序所知,并且应该在应用程序的生命周期中保持相对恒定,包括通过应用程序重新启动

# choose a salt, a secret string of bytes
>>> SECRET_KEY = 'my super secret key'.encode('utf8')
(2)创建一个cookie

>>> cookie = make_cookie(
...     name='_profile', 
...     content='uid=382|membership=regular',
...     ...
...     expires='July 1 2030...'
... )

>>> print(cookie)
name: _profile
content: uid=382|membership=regular...
    ...
    ...
expires: July 1 2030, 1:20:40 AM UTC
(3)要创建签名,请将
密钥
附加(或前置)到cookie字节字符串,然后根据该组合生成哈希

# encode and salt the cookie, then hash the result
>>> cookie_bytes = str(cookie).encode('utf8')
>>> signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()
>>> print(signature)
7ae0e9e033b5fa53aa....
(4)现在将签名粘贴在原始cookie的
内容
字段的一端

# include signature as part of the cookie
>>> cookie.content = cookie.content + '|' + signature
>>> print(cookie)
name: _profile
content: uid=382|membership=regular|7ae0e9...  <--- signature
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC
# Upon receiving the cookie from browser
>>> cookie = request.get_cookie()
# pop the signature out of the cookie
>>> (cookie.content, popped_signature) = cookie.content.rsplit('|', 1)
从浏览器接收cookie时: (5)当浏览器将此cookie返回到服务器时,从cookie的
内容
字段中删除签名以返回原始cookie

# include signature as part of the cookie
>>> cookie.content = cookie.content + '|' + signature
>>> print(cookie)
name: _profile
content: uid=382|membership=regular|7ae0e9...  <--- signature
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC
# Upon receiving the cookie from browser
>>> cookie = request.get_cookie()
# pop the signature out of the cookie
>>> (cookie.content, popped_signature) = cookie.content.rsplit('|', 1)
(6)使用原始cookie和应用程序的
密钥
,使用与步骤3相同的方法重新计算签名

# recalculate signature using SECRET_KEY and original cookie
>>> cookie_bytes = str(cookie).encode('utf8')
>>> calculated_signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()
(7)将计算结果与之前从刚收到的cookie中弹出的签名进行比较。如果它们匹配,我们知道饼干没有被弄乱。但是,即使只是在cookie中添加了一个空格,签名也不会匹配

# if both signatures match, your cookie has not been modified
>>> good_cookie = popped_signature==calculated_signature
(8)如果它们不匹配,那么您可以响应任意数量的操作、记录事件、丢弃cookie、发布新cookie、重定向到登录页面等

>>> if not good_cookie:
...     security_log(cookie)
基于散列的消息身份验证码(HMAC) 上面生成的需要密钥以确保某些内容完整性的签名类型在密码学中称为消息身份验证码或MAC

我在前面指出,上面的例子过于简化了这个概念,实现自己的签名不是一个好主意。这是因为用于在Flask中对Cookie进行签名的算法被调用,并且比上面简单的一步一步的过程要复杂一些。总体思路是相同的,但由于超出本讨论范围的原因,这一系列计算稍微复杂一些。 如果您仍然对制作DIY感兴趣,通常情况下,Python有一些模块可以帮助您入门:)这里是一个起点:

import hmac
import hashlib

def create_signature(secret_key, msg, digestmod=None):
    if digestmod is None:
        digestmod = hashlib.sha1
    mac = hmac.new(secret_key, msg=msg, digestmod=digestmod)
    return mac.digest()
和的文档


密钥的“解密”:
在这种情况下,“签名”是什么?
这是一种确保某些内容未被授权修改的个人或实体以外的任何人修改的方法

最简单的签名形式之一是“”,它只是验证两个数据是否相同。例如,从源代码安装软件时,首先确认您的源代码副本与作者的相同是很重要的。实现这一点的常用方法是通过加密哈希函数运行源代码,并将输出与上发布的校验和进行比较
name: _profile
content: uid=382|status=genie
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC
>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
# this is not good
SECRET_KEY = random_key_generator()