如何通过获取Azure Key Vault证书执行代码签名?是否有其他方法?
Azure Key Vault证书获取与代码签名的替代方法
以下是几种不同于你当前脚本的实现方式,各有适用场景:
方法1:直接通过Get-AzKeyVaultCertificate获取证书对象签名
这种方式跳过Secret的Base64解码步骤,直接操作Key Vault证书对象,流程更简洁:
# 获取Key Vault中的证书对象 $kvCert = Get-AzKeyVaultCertificate -VaultName "kv" -Name "CodeSigning" # 提取带私钥的X509证书实例(设置存储标志确保私钥可用于签名) $x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2( $kvCert.Certificate.RawData, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet ) # 执行代码签名 Set-AuthenticodeSignature -FilePath "C:\Users\Desktop\*.dll" -Certificate $x509Cert -TimestampServer "http://timestamp.digicert.com"
注意:需要确保当前身份对Key Vault证书拥有Get权限,且证书包含代码签名的增强型密钥用法(EKU)。
方法2:通过Azure REST API直接获取证书与私钥
适合无法安装Az模块的环境,通过REST调用直接获取证书数据:
# 证书的Key Vault URI(替换为实际的证书URI,包含版本号) $certUri = "https://kv.vault.azure.net/certificates/CodeSigning/<你的证书版本号>" # 获取证书公钥部分 $certResp = Invoke-AzRestMethod -Uri $certUri -Method Get $certBase64 = ($certResp.Content | ConvertFrom-Json).cer # 获取对应私钥的Secret(Key Vault证书的私钥存储在同名Secret中) $secretUri = $certUri -replace "/certificates/", "/secrets/" $secretResp = Invoke-AzRestMethod -Uri $secretUri -Method Get $pfxBase64 = ($secretResp.Content | ConvertFrom-Json).value # 转换为字节并加载为X509证书 $pfxBytes = [Convert]::FromBase64String($pfxBase64) $x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2( $pfxBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable ) # 执行签名 Set-AuthenticodeSignature -FilePath "C:\Users\Desktop\*.dll" -Certificate $x509Cert -TimestampServer "http://timestamp.digicert.com"
方法3:临时导入证书到本地存储后签名
部分签名工具依赖本地证书存储,可将Key Vault证书临时导入后再清理:
# 获取PFX格式的证书Secret $pfxSecret = Get-AzKeyVaultSecret -VaultName "kv" -Name "CodeSigning" -AsPlainText $pfxBytes = [Convert]::FromBase64String($pfxSecret) # 打开当前用户的个人证书存储 $certStore = New-Object System.Security.Cryptography.X509Certificates.X509Store( [System.Security.Cryptography.X509Certificates.StoreName]::My, [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser ) $certStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) # 导入证书 $x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2( $pfxBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet ) $certStore.Add($x509Cert) $certStore.Close() # 使用证书指纹进行签名 Set-AuthenticodeSignature -FilePath "C:\Users\Desktop\*.dll" -Certificate (Get-ChildItem "Cert:\CurrentUser\My\$($x509Cert.Thumbprint)") -TimestampServer "http://timestamp.digicert.com" # 清理临时导入的证书 $certStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) $certStore.Remove($x509Cert) $certStore.Close()
通用注意事项
- 所有方法都需要确保执行身份拥有Key Vault的
Certificate Get和Secret Get权限(根据方法不同调整)。 - 证书必须包含代码签名的增强型密钥用法(EKU),否则签名无法通过系统验证。
- 时间戳服务器的选择要稳定可靠,确保签名在证书过期后仍可被验证。
内容的提问来源于stack exchange,提问作者as_23
相关产品推荐
相关产品推荐

