如何从密钥库中检索证书并将其导入另一个密钥库而不保存?

How to retrieve certificate from a keyvault and import it into another without saving it?

在 Azure 管道中有以下任务

  1. AzureResourceManagerTemplateDeployment@3 从 ARM 模板部署 Key Vault
  2. 然后 AzurePowerShell@5 检查 Key Vault 是否包含 "my-self-signed-cert",如果不包含 - 将其导入 Key Vault
  3. 最后另一个 AzureResourceManagerTemplateDeployment@3 部署了一个 Service Fabric 集群并配置 SF 集群及其 VMSS 以使用证书

以下是任务:

- task: AzureResourceManagerTemplateDeployment@3
  displayName: 'Deploy Keyvault'
  inputs:
    deploymentScope: 'Resource Group'
    subscriptionId: '${{ parameters.SubscriptionId }}'
    azureResourceManagerConnection: '${{ parameters.ArmConnection }}'
    action: 'Create Or Update Resource Group'
    resourceGroupName: '${{ parameters.resourceGroupName }}'
    location: 'West Europe'
    templateLocation: 'Linked artifact'
    csmFile: '$(Build.SourcesDirectory)/pipelines/templates/keyvault.json'
    csmParametersFile: '$(Build.SourcesDirectory)/pipelines/templates/keyvault-params.json'
    deploymentMode: 'Incremental'

- task: ARM Outputs@5
  displayName: 'Collect Keyvault output'
  inputs:
    ConnectedServiceNameSelector: 'ConnectedServiceNameARM'
    ConnectedServiceNameARM: '${{ parameters.ArmConnection }}'
    resourceGroupName: '${{ parameters.resourceGroupName }}'
    whenLastDeploymentIsFailed: 'fail'

- task: AzurePowerShell@5
  displayName: 'Import certificate'
  inputs:
    azureSubscription: '${{ parameters.ArmConnection }}'
    ScriptType: 'InlineScript'
    azurePowerShellVersion: '3.1.0'
    Inline: |
      $Cert = Get-AzKeyVaultCertificate -VaultName my-kv -Name my-self-signed-cert
      if (!$Cert) {
          $Base64 = 'MIIWMgIBA___3000_chars_here____o7WqDoWm5I7fg=='
          $Cert = Import-AzKeyVaultCertificate -VaultName my-kv -Name my-self-signed-cert -CertificateString $Base64
      }
      # set the pipeline variables Thumbprint and SecretId - needed for SF deployment
      echo "##vso[task.setvariable variable=Thumbprint]$($Cert.Thumbprint)"
      echo "##vso[task.setvariable variable=SecretId]$($Cert.SecretId)"

# deploy SF cluster by ARM template and use the SF Cluster certificate thumbsprint as admin cert
- task: AzureResourceManagerTemplateDeployment@3
  displayName: 'Deploy SF cluster'
  inputs:
    deploymentScope: 'Resource Group'
    subscriptionId: '${{ parameters.SubscriptionId }}'
    azureResourceManagerConnection: '${{ parameters.ArmConnection }}'
    action: 'Create Or Update Resource Group'
    resourceGroupName: '${{ parameters.resourceGroupName }}'
    location: 'West Europe'
    templateLocation: 'Linked artifact'
    csmFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster.json'
    csmParametersFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster-params.json'
    overrideParameters: '-certificateThumbprint $(Thumbprint) -sourceVaultResourceId $(KeyvaultId) -certificateUrlValue $(SecretId)'
    deploymentMode: 'Incremental'

效果很好,但现在我正尝试用托管在另一个 Key Vault 中的真实证书替换自签名证书。

我的计划是从另一个 Key Vault 下载新的证书内容(包括密钥),然后对其进行 Base64 编码(以避免创建任何临时文件)- 最后 Import-AzKeyVaultCertificate ... -CertificateString $Base64 到我的 Key Vault (请参阅我的任务列表中的 "Step 2")。

我的问题是我无法获取证书内容。

我可以使用以下 PowerShell 命令检索 "real" 证书:

$Cert = Get-AzKeyVaultCertificate -VaultName the-company-kv -Name the-real-cert
$Secret = Get-AzKeyVaultSecret -VaultName the-company-kv -Name the-real-cert

他们在上面命令 return 一些元数据,但是没有什么类似于我能够的内容(如果还没有 base64 编码的话):

$Base64 = [System.Convert]::ToBase64String($Bytes)
Import-AzKeyVaultCertificate -VaultName my-kv -Name my-self-signed-cert -CertificateString $Base64

这里有一个解决方案,用于将证书从一个 Key Vault 复制到另一个(此处:the-company-kv -> my-kv)而不将其保存到临时文件中:

$Cert = Get-AzKeyVaultCertificate -VaultName my-kv -Name the-real-cert
if (!$Cert) {
    $OrigCert = Get-AzKeyVaultCertificate -VaultName the-company-kv -Name the-real-cert
    $Secret = Get-AzKeyVaultSecret -VaultName the-company-kv -Name $OrigCert.Name
    $Cert = Import-AzKeyVaultCertificate -VaultName my-kv -Name $OrigCert.Name -CertificateString $Secret.SecretValueText
}

我没有意识到,当我在命令提示符下输入 $Secret 时,PowerShell 没有显示所有属性,因此一开始我没有看到 $Secret.SecretValueText