【问题标题】:AES key moved in config file generate " AES key must be either 16, 24, or 32 bytes long" error在配置文件中移动的 AES 密钥生成“AES 密钥必须是 16、24 或 32 字节长”错误
【发布时间】:2015-11-02 07:54:55
【问题描述】:

我正在使用 python,flask。我正在使用 AES 进行加密。它工作得很好,我很容易加密和解密数据。 为了保护加密密钥,我从配置文件中的应用程序表单中移动了我的加密密钥。首先我在配置文件中保存了一个变量,我在config.cfg 中声明了ENCRYPTION_KEY

[Encryption]
ENCRYPTION_KEY = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'

然后在我声明的初始化文件上:

 app.config['ENCRYPTION_KEY'] = config.get('Encryption', 'ENCRYPTION_KEY')

我尝试从key = flask.config['ENCRYPTION_KEY'] 访问它。我在控制台中打印密钥只是为了确保该命令有效:

def encrypt_data(self, form_data):
        key = current_app.config['ENCRYPTION_KEY']
        print "KEY : " , key
        cipher = AES.new(key)
        //code...

并在控制台中打印键:

现在,当我尝试从配置文件中使用此密钥时,我收到一条错误消息:

出现此消息只是因为我在配置文件中移动了该键,因为正如我之前所说,我对相同的方法使用相同的键并且它工作得很好? 谁能帮帮我,为什么会出现这个错误?

【问题讨论】:

  • 您使用的是 Python 2 还是 Python 3? print 语句看起来像 Python 2,但是它的输出看起来像 Python 3。
  • @mhawke 我正在使用 Python 2.7.6
  • @EgzontinaK:这是不可能的。 Python 2 不会将密钥打印为带有前导 b 的字节字符串。你是如何加载你的配置文件的?您是否有任何机会实际设置了 ENCRYPTION_KEY = "b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'" ,即字符串实际上包含 b 前缀?
  • @mhawke 我更新了我的问题,正如我写的那样,我只是将它添加到初始化文件中,我可以在字符串之前使用 b 前缀访问它,我只在配置中使用了单引号 ('')文件!
  • @EgzontinaK:ConfigParser 返回原始字符串,即反斜杠用额外的反斜杠转义,这会产生一个 92 个字符的字符串,包括 b 前缀和周围的引号。请参阅我的答案以获取解决方案。

标签: python encryption configuration flask aes


【解决方案1】:

您对ConfigParser 模块的使用是问题的原因。鉴于显示的配置文件:

>>> config.get('Encryption', 'ENCRYPTION_KEY')
"b'\\xbf\\xc0\\x85)\\x10nc\\x94\\x02)j\\xdf\\xcb\\xc4\\x94\\x9d(\\x9e[EX\\xc8\\xd5\\xbfI{\\xa2$\\x05(\\xd5\\x18'"
>>> len(config.get('Encryption', 'ENCRYPTION_KEY'))
92

您可以在这里看到ConfigParser 只是将与给定配置变量关联的值返回为文本,而不是Python 字符串。因为配置值包含反斜杠转义序列,所以这些反斜杠使用额外的反斜杠进行转义。这会破坏 \x 字符序列,然后将其扩展为 4 个字符。

解决这个问题的最简单方法是使用 Flask 的配置文件:

config.cfg

ENCRYPTION_KEY = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\ x18'
>>> import flask
>>> app = flask.Flask('test')
>>> app = flask.Flask('')
>>> app.config.from_pyfile('config.cfg')
True
>>> app.config['ENCRYPTION_KEY']
'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
>>> len(app.config['ENCRYPTION_KEY'])
32

如果您不想使用 Flask 的配置文件,您的选择是(按优先顺序):

  • 使用ast.literal_eval() 将原始字符串安全地转换为 Python 字符串:

    from ast import literal_eval
    app.config['ENCRYPTION_KEY'] = literal_eval(config.get('Encryption', 'ENCRYPTION_KEY'))
    
  • Base64 编码配置文件中的值,例如

    [加密]
    ENCRYPTION_KEY = v8CFKRBuY5QCKWrfy8SUnSieW0VYyNW/SXuiJAUo1Rg=

    然后在访问密钥时对其进行解码:

    app.config['ENCRYPTION_KEY'] = config.get('Encryption', 'ENCRYPTION_KEY').decode('base64')
    
  • 使用eval()将原始字符串转换为Python字符串:

    app.config['ENCRYPTION_KEY'] = eval(config.get('Encryption', 'ENCRYPTION_KEY'))
    

    虽然这被认为是不好/危险的做法,但最好使用 literal_eval() 或 base64 编码。

  • 将密钥作为二进制值存储在文件中:

    [加密]
    ENCRYPTION_KEY = ¿À)^Pnc^B)jßËÄ([EXÈÕ¿I{¢$^E(Õ^X

    但这很难维护。

【讨论】:

  • 太棒了!非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 2020-04-28
  • 2018-05-31
  • 2015-02-05
  • 1970-01-01
  • 2017-04-26
相关资源
最近更新 更多