Azure KeyVault如何隔离私钥?使含指定权限的应用无法获取
如何在Azure KeyVault中隔离私钥,同时保留证书链获取权限
问题背景
我有一个用于文件数字签名的PKCS12文件,通过以下OpenSSL命令生成:
openssl pkcs12 -in cert_chain.pem -inkey private.key -passin "pass:xx" -export -passout "pass:yy" -out signature.pfx
目标是将该材料导入Azure KeyVault,仅通过KeyVault的签名API完成操作,避免应用直接接触私钥。但当前即使将密钥标记为exportable: false,拥有Certificate Get、Sign、Secret Get权限的应用仍能通过Secret API获取完整PKCS12并提取私钥。
核心需求:在保留应用获取证书链能力的前提下,确保私钥无法被导出或获取
问题根源
直接导入完整PKCS12时,Azure KeyVault会自动将原始PKCS12文件(包含私钥)以Secret形式存储,这个Secret不受密钥exportable属性的控制——无论密钥是否标记为不可导出,只要能获取该Secret,就能提取私钥。
解决方案:拆分材料分别导入
将原始PKCS12拆分为证书链(不含私钥)和私钥两部分,分别导入KeyVault,确保Secret仅存储证书链,私钥以不可导出的密钥形式独立存储。
步骤1:拆分原始PKCS12
从原PKCS12中导出仅包含证书链的文件:
openssl pkcs12 -in signature.pfx -passin "pass:yy" -nokeys -out cert_chain_only.pem
导出仅包含私钥的文件(注意妥善保管该文件):
openssl pkcs12 -in signature.pfx -passin "pass:yy" -nocerts -out private_only.key
步骤2:导入不可导出的私钥到KeyVault
使用Azure CLI将私钥导入为不可导出的密钥:
az keyvault key import \ --vault-name "someKv" \ --name "signature-key" \ --file private_only.key \ --exportable false
此时该密钥的exportable属性为false,仅允许调用签名API,无法导出私钥。
步骤3:导入证书链并关联到私钥
创建证书策略文件cert_policy.json,指定关联的密钥名称,确保证书仅关联已导入的不可导出密钥:
{ "keyProperties": { "exportable": false, "keyName": "signature-key" }, "secretProperties": { "contentType": "application/x-pkcs12" }, "x509CertificateProperties": { "subject": "<替换为你的证书主题,可从原证书获取>" } }
导入证书链到KeyVault:
az keyvault certificate import \ --vault-name "someKv" \ --name "signature-cert" \ -f cert_chain_only.pem \ --policy "@cert_policy.json"
步骤4:验证效果
- 应用通过
Certificate Get权限可获取完整证书链(包含中间CA),无需依赖Secret API - 应用通过
Sign权限可调用KeyVault签名API,无法获取私钥明文 - 即使拥有
Secret Get权限,获取到的Secret仅包含证书链,无任何私钥信息
内容的提问来源于stack exchange,提问作者GPI
相关产品推荐
相关产品推荐

