Azure / azure-rest-api-specs

The source for REST API specifications for Microsoft Azure.
MIT License
2.61k stars 5.03k forks source link

`Keyvault`: encrypt and decrypt operation not symmetrical #23829

Open wuxu92 opened 1 year ago

wuxu92 commented 1 year ago

when we try encrypt/decrypt with APIs in terraform, we find that the result of decrypt operation of the encrypt result is not equal to the origin encrypted value. more discussion see https://github.com/hashicorp/terraform-provider-azurerm/issues/20763

there are two different cases here:

with simple string

if pass a value like some-secret to encrypt, then call decrypt with the result, the decrypted value changed to some-secres key-enc

with base64

when we pass a base64 encoded string with paddings(=), like c29tZS1zZWNyZXQ=, to encrypt, the result of decrypt will lost the padding characters.

key-enc-base64

To

Is this result as expected or any wrong with my usage on encrypt/decrypt APIs?

related operation definition:

https://github.com/Azure/azure-rest-api-specs/blob/b2fe1573f29f056930d79b1b8abf2611b98fa81a/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/keys.json#L463-L468

ghost commented 1 year ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @RandalliLama, @schaabs, @jlichwa.

Issue Details
when we try encrypt/decrypt with APIs in terraform, we find that the result of decrypt operation of the encrypt result is not equal to the origin encrypted value. more discussion see https://github.com/hashicorp/terraform-provider-azurerm/issues/20763 there are two different cases here: ## with simple string if pass a value like `some-secret` to encrypt, then call decrypt with the result, the decrypted value changed to `some-secres` ![key-enc](https://user-images.githubusercontent.com/2633022/236387935-41a69e33-e976-4196-940b-a4ac231ae186.gif) ## with base64 when we pass a base64 encoded string with paddings(`=`), like `c29tZS1zZWNyZXQ=`, to encrypt, the result of decrypt will lost the padding characters. ![key-enc-base64](https://user-images.githubusercontent.com/2633022/236388233-cfe18c69-00a4-4b5e-9834-cc2b63f18358.gif) ## To Is this result as expected or any wrong with my usage on encrypt/decrypt APIs? related operation definition: https://github.com/Azure/azure-rest-api-specs/blob/b2fe1573f29f056930d79b1b8abf2611b98fa81a/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/keys.json#L463-L468
Author: wuxu92
Assignees: -
Labels: `KeyVault`, `Service Attention`, `needs-triage`
Milestone: -
dalzhao commented 1 year ago

@wuxu92 , this is expected behavior. Key Vault API uses base64-url encoding for the content to be encrypted / decrypted. Each character in the base64 encoding string represetns 64 possible states, or 6 bits of information. It is not always aligned with the 8-bit bytes we directly work with. E.g. "some-secret" contains 11 base64 characters, or 66 bits of information. But we are only using 64 bits to encode the 8-byte of data, rendering the last 2 bits redundant. So we can use any of the 4 characters of "stuv" as the last character to encode the same data.

Also, base64-url encoding removes the "=" padding. So the response will not contain the "=" padding even if you send it in the request.

thomastrinamix commented 3 weeks ago

@dalzhao So this means one should not directly encrypt strings. The correct way would be to create a base64 string from "some-secret" which is "c29tZS1zZWNyZXQ=" and then encrypt. This will ensure the correct padding and not loosing the last character. Right?

If so one should adjust the docu regarding the base64-input for encryption https://learn.microsoft.com/en-us/rest/api/keyvault/keys/decrypt/decrypt?view=rest-keyvault-keys-7.4&tabs=HTTP