You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无Azure Key Vault访问权限时验证签名的方法咨询

问题

使用Azure Key Vault对文件签名并存储签名后,希望在无Vault访问权限的机器上,通过原文件、从文件读取的RSA模数和RSA公钥指数验证签名。尝试用PyCryptoDome的RSA和pkcs1_15模块时,遇到无法直接传入字节类型签名的问题(需要PyCryptoDome哈希对象),感觉当前实现方法繁琐,求正确的实现方式。

原精简代码:

import hashlib

from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15

from azure.identity import DefaultAzureCredential
from azure.keyvault.keys import KeyClient
from azure.keyvault.keys.crypto import SignatureAlgorithm
from azure.keyvault.certificates import CertificateClient
from azure.keyvault.secrets import SecretClient
from azure.keyvault.keys.crypto import CryptographyClient, EncryptionAlgorithm

VAULT_URL = os.environ["AZURE_VAULT_URL"]
CERTIFICATE_NAME = os.environ["AZURE_CERTIFICATE_NAME"]

credential = DefaultAzureCredential()
certificate_client = CertificateClient(vault_url=VAULT_URL, credential=credential)
key_client = KeyClient(vault_url=VAULT_URL, credential=credential)
secret_client = SecretClient(vault_url=VAULT_URL, credential=credential)

key = key_client.get_key(CERTIFICATE_NAME)
cryptography_client = CryptographyClient(key, credential=credential)

input_digest = hashlib.sha256(input_bytes).digest() # input_bytes is the file bytes

result = cryptography_client.sign(SignatureAlgorithm.rs256, input_digest)

public_key = RSA.construct((int.from_bytes(key.key.n), int.from_bytes(key.key.e)))
signature_object = pkcs1_15.new(public_key)
signature_object.verify(input_digest, result.signature)
解决方案

核心问题是PyCryptoDome的pkcs1_15.verify要求第一个参数为哈希对象而非哈希值字节,同时可以通过拆分签名/验证流程、简化公钥存储方式来优化实现。

实现思路

  1. 签名端(有Vault权限):使用Azure SDK完成签名,同时导出公钥的模数和指数并持久化存储(用于验证端)
  2. 验证端(无Vault权限):读取原文件、签名、公钥参数,构造公钥后用哈希对象完成签名验证

签名端代码(有Vault权限)

import os
import hashlib
from azure.identity import DefaultAzureCredential
from azure.keyvault.keys import KeyClient
from azure.keyvault.keys.crypto import CryptographyClient, SignatureAlgorithm

VAULT_URL = os.environ["AZURE_VAULT_URL"]
CERTIFICATE_NAME = os.environ["AZURE_CERTIFICATE_NAME"]

# 初始化Azure客户端
credential = DefaultAzureCredential()
key_client = KeyClient(vault_url=VAULT_URL, credential=credential)
key = key_client.get_key(CERTIFICATE_NAME)
cryptography_client = CryptographyClient(key, credential=credential)

# 读取目标文件并生成哈希
with open("target_file.bin", "rb") as f:
    input_bytes = f.read()
input_hash = hashlib.sha256(input_bytes)

# 执行签名
sign_result = cryptography_client.sign(SignatureAlgorithm.rs256, input_hash.digest())

# 保存签名到文件
with open("signature.bin", "wb") as f:
    f.write(sign_result.signature)

# 保存公钥参数(十六进制格式,便于存储和读取)
with open("pubkey_params.txt", "w") as f:
    f.write(f"{key.key.n:x}\n{key.key.e:x}")

验证端代码(无Vault权限)

import hashlib
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15

# 读取原文件
with open("target_file.bin", "rb") as f:
    input_bytes = f.read()

# 读取已存储的签名
with open("signature.bin", "rb") as f:
    signature = f.read()

# 读取公钥参数并构造RSA公钥
with open("pubkey_params.txt", "r") as f:
    n_hex, e_hex = f.read().splitlines()
public_key = RSA.construct((int(n_hex, 16), int(e_hex, 16)))

# 生成原文件的哈希对象(关键:传入哈希对象而非digest字节)
input_hash = hashlib.sha256(input_bytes)

# 验证签名
try:
    pkcs1_15.new(public_key).verify(input_hash, signature)
    print("签名验证通过")
except (ValueError, TypeError):
    print("签名验证失败")

优化说明

  • 拆分签名与验证流程,完全适配无Vault权限机器的验证场景
  • 验证时传入hashlib哈希对象,解决PyCryptoDome的参数要求问题
  • 用十六进制字符串存储公钥参数,比字节序列化更易读写和传输
  • 移除冗余的Azure客户端(如CertificateClient、SecretClient),精简签名端代码

内容的提问来源于stack exchange,提问作者P3tray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:33:10