为什么 Key Vault 中的 .PEM 密钥无法在我的 Function App 中正确使用?

问题描述 投票:0回答:1

我正在尝试通过 Azure Function App 使用 Python 完成一个流程。此过程需要一个私钥(.PEM,已作为密钥上传到 Azure Key Vault)以及两个秘密(基本上是我们的 API 密钥),声明多个声明、签名,并返回一个签名的 JWT 作为输出。

我已经在我的函数应用程序中运行了该函数的不同变体超过 170 次,每次都能很好地检索到机密(即 API 密钥),但该过程在密钥部分失败。我在 Git BASH 中使用 OpenSSL 创建了密钥,当我在本地运行此脚本的一个版本(因此直接调用 .PEM 文件)时,它工作正常。

我也需要“使用”公钥吗?如果是的话,怎么办?

这是我在 Function App 中使用的当前 Python 脚本(某些部分已编辑):

import azure.functions as func
import logging
import jwt
import uuid
from time import time
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from azure.keyvault.keys import KeyClient
from azure.keyvault.keys.crypto import CryptographyClient, SignatureAlgorithm

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

    # Azure Key Vault settings
    key_vault_url = "<my key vault>.vault.azure.net/"
    credential = DefaultAzureCredential()

    # Initialize the KeyClient to fetch the key for signing
    key_client = KeyClient(vault_url=key_vault_url, credential=credential)
    key_name = "int-test1"  # The name of the key in Azure Key Vault
    key = key_client.get_key(key_name)

    # Initialize the CryptographyClient for signing
    crypto_client = CryptographyClient(key, credential)

    # Initialize the SecretClient to fetch the 'sub' and 'iss' claims
    secret_client = SecretClient(vault_url=key_vault_url, credential=credential)
    sub_claim = secret_client.get_secret("int-sub").value
    iss_claim = secret_client.get_secret("int-iss").value

    # Your JWT claims
    claims = {
        "sub": sub_claim,
        "iss": iss_claim,
        "jti": str(uuid.uuid4()),
        "aud": "<api token endpoint>",
        "exp": int(time()) + 300 
    }

    additional_headers = {"kid": key_name, "alg": "RS512"}

    # Prepare the JWT to be signed
    encoded_jwt = jwt.encode(
        claims,
        "",  # Empty string for key, as we will sign the JWT using the CryptographyClient
        algorithm="RS512",
        headers=additional_headers
    )

    try:
        # Sign the JWT using the CryptographyClient
        result = crypto_client.sign(SignatureAlgorithm.rs512, encoded_jwt.encode('utf-8'))
        signature = result.signature

        # Append the signature to the JWT to complete the token
        signed_jwt = f"{encoded_jwt}.{signature.decode('utf-8')}"

    except Exception as e:
        logging.error(f"Error signing JWT: {e}")
        raise

    # Return the JWT in the HTTP response
    return func.HttpResponse(signed_jwt, status_code=200)

我尝试复制并粘贴 .PEM 文本(Unix 格式,具有正确的标题(例如 -----BEGIN PRIVATE KEY----- 和最后 -----END PRIVATE KEY--- --)) 作为 Secret,并在脚本中将其称为 Secret,但这也不起作用。

函数应用程序具有托管身份,并分配了 Key Vault 加密官员和 Key Vault 秘密官员角色,并使用它与 Key Vault 进行交互。

运行提供的当前 Python 代码,我总是在 Application Insights 中收到此错误:

Result: 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).', [<OpenSSLError(code=75497580, lib=9, reason=108, reason_text=no start line)>]) Stack: File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py", line 491, in _handle__invocation_request call_result = await self._run_async_func( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py", line 774, in _run_async_func return await ExtensionManager.get_async_invocation_wrapper( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/extension.py", line 147, in get_async_invocation_wrapper result = await function(**args) ^^^^^^^^^^^^^^^^^^^^^^ File "/home/site/wwwroot/Http_createSignedJWT/__init__.py", line 43, in main encoded_jwt = jwt.encode( ^^^^^^^^^^^ File "/home/site/wwwroot/.python_packages/lib/site-packages/jwt/api_jwt.py", line 73, in encode return api_jws.encode( ^^^^^^^^^^^^^^^ File "/home/site/wwwroot/.python_packages/lib/site-packages/jwt/api_jws.py", line 160, in encode key = alg_obj.prepare_key(key) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/site/wwwroot/.python_packages/lib/site-packages/jwt/algorithms.py", line 353, in prepare_key return cast(RSAPublicKey, load_pem_public_key(key_bytes)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/site/wwwroot/.python_packages/lib/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 35, in load_pem_public_key return ossl.load_pem_public_key(data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/site/wwwroot/.python_packages/lib/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 794, in load_pem_public_key self._handle_key_loading_error() File "/home/site/wwwroot/.python_packages/lib/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 984, in _handle_key_loading_error raise ValueError(
python jwt azure-functions azure-keyvault private-key
1个回答
0
投票

要检索 .PEM 文件/密钥/证书,我使用以下代码:

import logging
from azure.identity import DefaultAzureCredential
from azure.keyvault.certificates import CertificateClient
import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    rithwik_keyVaultURi = "https://keyvaultname.vault.azure.net"
    rith_certificate_name = "name of your certificate"
    creds = DefaultAzureCredential()
    rithwik_CC = CertificateClient(vault_url=rithwik_keyVaultURi, credential=creds)
    rith_certificate = rithwik_CC.get_certificate(rith_certificate_name)
    rith_cer_data = rith_certificate.cer
    print(rith_cer_data)
    return func.HttpResponse(f"Hello Rithwik Certificate Retrieved: {rith_certificate.name}", status_code=200)

Output:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.