-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support serializing JWK using RFC 7517 (#24282)
* Support serializing JWK using RFC 7517 Resolves #16155 * Make JsonWebKeyConverter internal
- Loading branch information
Showing
10 changed files
with
376 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
sdk/keyvault/Azure.Security.KeyVault.Keys/samples/Sample7_SerializeJsonWebKey.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Serializing and encrypting with a JWK | ||
|
||
This sample demonstrates how to serialize a [JSON web key (JWK)][JWK] and use it in a `CryptographyClient` to perform | ||
cryptographic operations requiring only the public key. We subsequently verify the operation by decrypting the | ||
ciphertext in Key Vault or Managed HSM using the same key. | ||
|
||
To get started, you'll need a URI to an Azure Key Vault or Managed HSM. See the [README][] for links and instructions. | ||
|
||
## Creating a KeyClient | ||
|
||
To create a new `KeyClient` to create, get, update, or delete keys, you need the endpoint to an Azure Key Vault and credentials. | ||
You can use the [DefaultAzureCredential][] to try a number of common authentication methods optimized for both running as a service and development. | ||
|
||
In the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application. | ||
|
||
```C# Snippet:KeysSample7KeyClient | ||
var keyClient = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); | ||
``` | ||
|
||
## Creating a key | ||
|
||
First, create an RSA key which will be used to wrap and unwrap another key. | ||
|
||
```C# Snippet:KeysSample7CreateKey | ||
string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}"; | ||
var rsaKey = new CreateRsaKeyOptions(rsaKeyName, hardwareProtected: false) | ||
{ | ||
KeySize = 2048, | ||
}; | ||
|
||
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(rsaKey); | ||
Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyType}"); | ||
``` | ||
|
||
## Serialize the JWK | ||
|
||
The `KeyVaultKey.Key` property is the JSON web key (JWK) which can be serialized using `System.Text.Json`. You might | ||
serialize the JWK to save it for future sessions or use it with other libraries. | ||
|
||
```C# Snippet:KeysSample7Serialize | ||
using FileStream file = File.Create(path); | ||
using (Utf8JsonWriter writer = new Utf8JsonWriter(file)) | ||
{ | ||
JsonSerializer.Serialize(writer, cloudRsaKey.Key); | ||
} | ||
|
||
Debug.WriteLine($"Saved JWK to {path}"); | ||
``` | ||
|
||
## Encrypting with the JWK | ||
|
||
Assuming you had saved the serialized JWK for future sessions, you can decrypt it before you need to use it: | ||
|
||
```C# Snippet:KeysSamples7Deserialize | ||
byte[] buffer = File.ReadAllBytes(path); | ||
JsonWebKey jwk = JsonSerializer.Deserialize<JsonWebKey>(buffer); | ||
|
||
Debug.WriteLine($"Read JWK from {path} with ID {jwk.Id}"); | ||
``` | ||
|
||
You can then create a new `CryptographyClient` from the JWK to perform cryptographic operations using what public | ||
key information is contained within the JWK: | ||
|
||
```C# Snippet:KeysSample7Encrypt | ||
var encryptClient = new CryptographyClient(jwk); | ||
|
||
byte[] plaintext = Encoding.UTF8.GetBytes(content); | ||
EncryptResult encrypted = encryptClient.Encrypt(EncryptParameters.RsaOaepParameters(plaintext)); | ||
|
||
Debug.WriteLine($"Encrypted: {Encoding.UTF8.GetString(plaintext)}"); | ||
``` | ||
|
||
## Decrypting with Key Vault or Managed HSM | ||
|
||
Because Key Vault and Managed HSM do not return the private key material, you can decrypt the ciphertext encrypted above | ||
remotely in the Key Vault or Managed HSM. We'll get a `CryptographyClient` from our original `KeyClient` that shares | ||
the same policy, including any customized pipeline policies, diagnostic information, and more. | ||
|
||
```C# Snippet:KeysSample7Decrypt | ||
CryptographyClient decryptClient = keyClient.GetCryptographyClient(cloudRsaKey.Name, cloudRsaKey.Properties.Version); | ||
DecryptResult decrypted = decryptClient.Decrypt(DecryptParameters.RsaOaepParameters(ciphertext)); | ||
|
||
Debug.WriteLine($"Decrypted: {Encoding.UTF8.GetString(decrypted.Plaintext)}"); | ||
``` | ||
|
||
## Source | ||
|
||
To see the full example source, see: | ||
|
||
* [Synchronous Sample7_SerializeJsonWebKey.cs](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Keys/tests/samples/Sample7_SerializeJsonWebKey.cs) | ||
* [Asynchronous Sample7_SerializeJsonWebKeyAsync.cs](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Keys/tests/samples/Sample7_SerializeJsonWebKeyAsync.cs) | ||
|
||
[DefaultAzureCredential]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/README.md | ||
[JWK]: https://datatracker.ietf.org/doc/html/rfc7517 | ||
[README]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Keys/README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
sdk/keyvault/Azure.Security.KeyVault.Keys/src/JsonWebKeyConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using Azure.Core; | ||
|
||
namespace Azure.Security.KeyVault.Keys | ||
{ | ||
/// <summary> | ||
/// Converts a <see cref="JsonWebKey"/> to or from JSON. | ||
/// </summary> | ||
internal sealed class JsonWebKeyConverter : JsonConverter<JsonWebKey> | ||
{ | ||
/// <inheritdoc/> | ||
public override JsonWebKey Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
{ | ||
using JsonDocument doc = JsonDocument.ParseValue(ref reader); | ||
|
||
JsonWebKey value = new(); | ||
value.ReadProperties(doc.RootElement); | ||
|
||
return value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void Write(Utf8JsonWriter writer, JsonWebKey value, JsonSerializerOptions options) | ||
{ | ||
Argument.AssertNotNull(writer, nameof(writer)); | ||
Argument.AssertNotNull(value, nameof(value)); | ||
|
||
writer.WriteStartObject(); | ||
value.WriteProperties(writer, withId: true); | ||
writer.WriteEndObject(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.