0

I have a self signed certificate that I am trying to import to Azure Key Vault Certificate, and I am facing issues. I am not doing it using the Import-AzKeyVaultCertificate command, but using the API.

I was successfully able to create a Key via the API route, but for the life of me, I am not able to Import a certificate. FYI, it also works when I do it over an Azure DevOps pipeline, so I know the Service Principle isn't the issue.

Here's how I am creating the certificate (over PowerShell locally - all examples here will be local and not for Azure DevOps):

$certroopath = "C:\cert"
$location = "eastus"
$vmName = "arsmpvm"
$certname = "$vmName"
$certpassword = "P@ssw0rd1234"

$cert = New-SelfSignedCertificate -DnsName "$certname" -CertStoreLocation cert:\LocalMachine\My
$pwd = ConvertTo-SecureString -String $certpassword -Force -AsPlainText
$certwithThumb = "cert:\localMachine\my\"+$cert.Thumbprint
$filepath = "$certroopath\$certname.pfx"
Export-PfxCertificate -cert $certwithThumb -FilePath $filepath -Password $pwd
Remove-Item -Path $certwithThumb 

Here's how I am importing the certificate over a POST operation:

$pfxcontent = Get-Content 'C:\cert\arsmpvm.pfx' -Encoding Byte
$base64Stringpfxcontent = [System.Convert]::ToBase64String($pfxcontent)

#The payload
$json_new = '{
  "value": "$base64Stringpfxcontent",
  "pwd": "$pwd",
  "policy": {
    "key_props": {
      "exportable": true,
      "kty": "RSA",
      "key_size": 2048,
      "reuse_key": false
    },
    "secret_props": {
      "contentType": "application/x-pem-file"
    }
  }
}'

$header = @{Authorization = "Bearer " + $token.access_token}
Invoke-RestMethod -Method Post -Uri "https://$kvname.vault.azure.net/certificates/$certname/import?api-version=7.0" -Body $json_new -Headers $header -ContentType "application/json"

Here's the error I am thrown: Invoke-RestMethod : {"error":{"code":"BadParameter","message":"The specified PEM X.509 certificate content is in an unexpected format. Please check if certificate is in valid PEM format."}}

Even if I replace the value of $base64Stringpfxcontent (in $json_new) to the content of it, which is like a 3500 char string, I get the same issue. Even if I change $pwd to its hard-coded value, which is P@ssw0rd1234, I am thrown the same error.

Reference taken from: https://learn.microsoft.com/en-us/rest/api/keyvault/importcertificate/importcertificate

Screenshot of the error: enter image description here

Anonymous Person
  • 1,437
  • 8
  • 26
  • 47
  • Try "contentType" of "application/x-pkcs12" – jfrmilner Feb 15 '20 at 22:46
  • Yea, I've tried that too. It's failed. Here's the error: `Invoke-RestMethod : {"error":{"code":"BadParameter","message":"The specified Base64-encoded PKCS#12 X.509 certificate content can not be read. Please check if certificate is valid, and is correctly Base64 encoded."}}` – Anonymous Person Feb 16 '20 at 04:22

1 Answers1

1

If you use the $base64Stringpfxcontent and $pwd in '', they will be recognized as string instead of variable, and from the doc, the pwd is string, you could not use a SecureString instead of it, you need to pass P@ssw0rd1234 directly to the request body.

Try the script below, it works fine on my side.

$kvname = "joykeyvault"
$certname = "testcer123"

$pfxcontent = Get-Content 'C:\Users\joyw\Desktop\arsmpvm.pfx' -Encoding Byte
$base64Stringpfxcontent = [System.Convert]::ToBase64String($pfxcontent)

$json_new = @{
  value= $base64Stringpfxcontent
  pwd= "P@ssw0rd1234"
  policy= @{
    secret_props= @{
      contentType= "application/x-pkcs12"
    }
  }
}

$json = $json_new | ConvertTo-Json

$header = @{Authorization = "Bearer " + $token.access_token}
Invoke-RestMethod -Method Post -Uri "https://$kvname.vault.azure.net/certificates/$certname/import?api-version=7.0" -Body $json -Headers $header -ContentType "application/json"

enter image description here

Check in the portal:

enter image description here

Joy Wang
  • 39,905
  • 3
  • 30
  • 54