在配置文件中移动的 AES 密钥生成“AES 密钥必须是 16、24 或 32 字节长”错误

AES key moved in config file generate " AES key must be either 16, 24, or 32 bytes long" error

我正在使用 python,flask.I正在使用 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...

并在控制台中打印密钥:

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

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

您对 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 只是 returns 与给定配置变量关联的值作为 text,而不是 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]
    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'))
    

    虽然这被认为是 bad/dangerous 实践,但您最好使用 literal_eval() 或 base64 编码。

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

    [Encryption]
    ENCRYPTION_KEY = ¿À<85>)^Pnc<94>^B)jßËÄ<94><9d>(<9e>[EXÈÕ¿I{¢$^E(Õ^X

    但这很难维护。