生成 JWT 令牌错误的 Azure 函数对存储在 Key Vault 机密中的私钥进行消毒

Azure Function to generate JWT token error desterilising private key stored in key vault secret

我正在构建一个 Azure 函数来为我生成(并重新生成)一个 JWT 令牌,然后我将使用它来调用 DocuSign API。

我在本地运行此程序,并且在调用 DocuSign API 时正在生成的令牌正在运行。当我将其部署到 Azure 函数时,我 运行 遇到了问题。

在本地,我使用本地设置来存储密钥,然后将其作为环境变量引用。在 Azure 上,我使用 Azure Key Vault 将相同的密钥存储为机密。但是我对密钥及其存储方式有疑问。

当 运行 Azure 函数上的相同代码时出现此错误:

Failure Exception: ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).

我认为这是 Azure Key Vault 存储数据的字符集的问题,但即使将它从 UTF-8 编码为 ANSI 或从 ANSI 编码为 UTF-8,我也无法解决这个问题。

import logging
import os
import azure.functions as func
import jwt

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    private_key = os.environ["servicePrivateKey"]

    payload = {"sub": "1234567890","name": "John Doe","iat": 1516239022}

    encoded = jwt.encode(payload, private_key, algorithm="RS256")

    return func.HttpResponse(
        encoded, status_code=200
    )

按照这里的用法示例 pyjwt example

我本地的密钥是这样存储的:

"servicePrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAK................m1T6yWn5MparGHIY=\n-----END RSA PRIVATE KEY-----"

在 Azure Key vault 上,我尝试以几种不同的方式将其保存在秘密中,但这是一个示例(这是从 Azure 上的秘密值中复制出来的):

-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAK................m1T6yWn5MparGHIY= -----END RSA PRIVATE KEY-----

我现在遇到了困难,因为如果不将私钥以明文形式存储在 azure 函数中或以某种方式将其与应用程序文件一起上传,我无法弄清楚我能做什么。

我终于找到了这个问题的答案。我解决错误的方法是将密钥作为 ascii 编码的秘密上传到 txt 文件中。

Azure 文档:https://docs.microsoft.com/en-us/cli/azure/keyvault/secret?view=azure-cli-latest#az-keyvault-secret-set

az keyvault secret set --name
                       --vault-name
                       [--description]
                       [--disabled {false, true}]
                       [--encoding {ascii, base64, hex, utf-16be, utf-16le, utf-8}]
                       [--expires]
                       [--file]
                       [--not-before]
                       [--tags]
                       [--value]

然后,当我读取机密时,它在机密中添加了 \n(新行)字符。但这实际上是作为一个字符串而不是一个新行来读取的。我只是用换行符替换了字符串版本并且这有效。

private_key = private_key.replace('\n' , '\n')

所以最终的解决方案是这样的:

from dataclasses import replace
import logging
import os
import azure.functions as func
import jwt

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    private_key = os.environ["servicePrivateKey"]

    private_key = private_key.replace('\n' , '\n')

    payload = {"sub": "1234567890","name": "John Doe","iat": 1516239022}

    encoded = jwt.encode(payload, private_key, algorithm="RS256")

    return func.HttpResponse(
        encoded, status_code=200
    )