Azure KeyVault 加密 API 终结点不返回 Base64 编码的字符串

Azure KeyVault Encrypt API Endpoint Not Returning Base64 Encoded String

在 PowerShell 中,我调用 KeyVault Encrypt API 端点来加密连接字符串。

首先,我创建了一个连接字符串的字节数组,然后创建了一个 base64 字符串。然后我调用 /encrypt 端点

[byte[]]$bytes = [System.Text.Encoding]::Unicode.GetBytes($targetConnectionString)

echo "Plain Bytes" $bytes

#$base64Array = [Convert]::ToBase64String($bytes)

#$EncryptedTargetConnectionString = Encrypt-ByteArray -accessToken $kvToken -vaultName $kvName -keyID $encryptionKeyId -plainArray $bytes

# converting the byte array to Base64 string
  # Note from [Chris Clayton (AzureCAT)].
  # "When performing the post methods there is a common theme of converting to Base64 strings which just makes sense so we do not introduce any invalid characters etc. and creating a JSON body as you can see here"
  $base64Array = [Convert]::ToBase64String($bytes)
  
  echo "Base 64 Array" $base64Array

  # constructing the url for the vault encrypt operation by specifying the KeyID and Key version. If key version is not specified, then the most recent key version will be used
  $queryUrl = "$encryptionKeyId" + '/encrypt?api-version=2016-10-01'   

  #echo "Query URL: " $queryUrl

  # injecting the access token we obtained in the authorization header
  $headers = @{ 'Authorization' = "Bearer $kvToken"; "Content-Type" = "application/json" }

  echo "KV Token" $kvToken

  # construct the body with our data to be encrypted and specifying RSA as encryption alg.
  $bodyObject = @{ "alg" = "RSA-OAEP"; "value" = $base64Array }
  $bodyJson = ConvertTo-Json -InputObject $bodyObject

  # invoking a POST call to do the magic
  $encryptionResponse = Invoke-RestMethod -Method POST -Ur $queryUrl -Headers $headers -Body $bodyJson

这似乎有效,因为当我使用 Postman 调用 Decrypt 端点时,我得到了我期望的响应。

然后我调用需要能够解密此连接字符串的 Azure 函数。

$EncryptedTargetConnectionString = $encryptionResponse.value

$webRequestBody = @"
{
        "BlobUrl" : "$blobUrl",
        "Environment" : "$env",
        "State" : "$state",
        "EncryptedConnectionStrings" : [ 
            {
            "EncryptedConnectionString": "$EncryptedTargetConnectionString"
            }
        ]
    }
"@

$webRequest = Invoke-WebRequest http://localhost:7071/api/DisableReplication -Headers @{"Accept" = "application/json"} -Method 'POST' -ContentType 'application/json; charset=utf-8' -Body $webRequestBody -UseBasicParsing

然而,这里的疯狂之处在于 /encrypt 端点的响应似乎不是 base64 格式。

当我尝试在 C# 中针对加密字符串 运行 Convert.FromBase64String(encryptedString) 时,它不起作用。它告诉我它不是 base64 格式。

C#代码

byte[] inputAsByteArray = Convert.FromBase64String(encryptedString);

            // Encryption algorithm MUST match what was used in the PowerShell task in the Release Pipeline to encrypt the string
            // Ex: $bodyObject = @{ "alg" = "RSA-OAEP"; "value" = $base64Array }
            DecryptResult decryptResult = await cryptographyClient.DecryptAsync(JsonWebKeyEncryptionAlgorithm.RSAOAEP, inputAsByteArray);

            string decryptedString = Encoding.UTF8.GetString(decryptResult.Plaintext);

            return decryptedString;

None 我为 .NET Core 找到的 Key Vault SDK 客户端支持直接解密字符串,但我似乎无法按照我的方式将字符串转换为字节数组希望能够。

知道微软在玩什么心理游戏吗?

Key Vault 使用与 Base64 编码略有不同的 Base64Url 编码。

Base64URL 编码几乎与 Base64 编码相同,只是它用 URL('+'、'~' 等)替换了不安全的字符其他角色。此外,它不使用填充('=')。