Skip to content

Commit

Permalink
Updating readme and samples for Azure.Security.KeyVault.Keys.Cryptog…
Browse files Browse the repository at this point in the history
…raphy (Azure#7280)

* Updating readme and samples for Azure.Security.KeyVault.Keys.Cryptography

* fixing name copy paste error

* updates addressing PR feedback

* fix for sample issue
  • Loading branch information
schaabs authored Aug 13, 2019
1 parent 15ba8c7 commit ffe3f8a
Show file tree
Hide file tree
Showing 8 changed files with 643 additions and 2 deletions.
47 changes: 46 additions & 1 deletion sdk/keyvault/Azure.Security.KeyVault.Keys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,26 @@ Key key = await Client.CreateKey("key-name", KeyType.EllipticCurve);
> new DefaultAzureCredential():
> Uses the environment variables previously set (`AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, and `AZURE_TENANT_ID`).
#### Create CryptographyClient
Once you've created a `Key` in the key vault, you can also create the [CryptographyClient][crypto_client_class]:

```c#
using Azure.Identity;
using Azure.Security.KeyVault.Keys.Cryptography;

// Create a new cryptography client using the default credential from Azure.Identity
var cryptoClient = new CryptographyClient(keyId: key.Id, credential: new DefaultAzureCredential());
```
## Key concepts
### Keys
Azure Key Vault supports multiple key types and algorithms, and enables the use of Hardware Security Modules (HSM) for high value keys.

### Key Client:
A KeyClient providing both synchronous and asynchronous operations exists in the SDK allowing for selection of a client based on an application's use case. Once you've initialized a KeyClient, you can interact with the primary resource types in Key Vault.

### Cryptography Client:
A CryptographyClient providing both synchronous and asynchronous operations exists in the SDK allowing for selection of a client based on an application's use case. Once you've initialized a CryptographyClient, you can use it to perform cryptographic operations with keys stored in Key Vault.

## Examples
The Azure.Security.KeyVault.Keys package supports synchronous and asynchronous APIs.

Expand All @@ -99,7 +112,7 @@ The following section provides several code snippets using the [above created](#
* [Update an existing Key](#update-an-existing-key)
* [Delete a Key](#delete-a-key)
* [List Keys](#list-keys)

* [Encrypt and Decrypt](#encrypt-and-decrypt)
### Async examples
* [Create a Key](#async-create-a-key)

Expand Down Expand Up @@ -177,6 +190,19 @@ IEnumerable<Response<KeyBase>> allKeys = client.GetKeys();
}
```

### Encrypt and Decrypt
This example creates a CryptographyClient and uses it to encrypt and decrypt with a key in Key Vault.

```c#
byte[] plaintext = Encoding.UTF8.GetBytes("A single block of plaintext");

// encrypt the data using the algorithm RSAOAEP
EncryptResult encryptResult = cryptoClient.Encrypt(EncryptionAlgorithm.RSAOAEP, plaintext);

// decrypt the encrypted data.
DecryptResult decryptResult = cryptoClient.Decrypt(EncryptionAlgorithm.RSAOAEP, encryptResult.Ciphertext);
```

### Async create a Key
Async APIs are identical to their synchronous counterparts. Note that all methods end with `Async`.

Expand Down Expand Up @@ -266,6 +292,18 @@ Several Key Vault Keys client library samples are available to you in this GitHu
* Delete keys from the Key Vault
* List deleted keys in the Key Vault

* [EncryptDecrypt.cs][encrypt_decrypt_sync] and [EncryptDecryptAsync.cs][encrypt_decrypt_async] - Example code for performing cryptographic operations with Key Vault keys, including:
* Encrypt and Decrypt data with the CryptographyClient

* [SignVerify.cs][sign_verify_sync] and [SignVerifyAsync.cs][sign_verify_async] - Example code for working with Key Vault keys, including:
* Sign a precalculated digest and verify the signature with Sign and Verify
* Sign raw data and verify the signature with SignData and VerifyData


* [WrapUnwrap.cs][wrap_unwrap_sync] and [WrapUnwrapAsync.cs][wrap_unwrap_async] - Example code for working with Key Vault keys, including:
* Wrap and Unwrap a symmetric key


### Additional Documentation
- For more extensive documentation on Azure Key Vault, see the [API reference documentation][keyvault_rest].
- For Secrets client library see [Secrets client library][secrets_client_library].
Expand All @@ -289,9 +327,16 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con
[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
[get_secrets_async]: samples/Sample3_GetKeysAsync.cs
[get_secrets_sync]: samples/Sample3_GetKeys.cs
[encrypt_decrypt_async]: samples/Sample4_EncryptDecryptAsync.cs
[encrypt_decrypt_sync]: samples/Sample4_EncryptDecrypt.cs
[sign_verify_async]: samples/Sample5_SignVerifyAsync.cs
[sign_verify_sync]: samples/Sample5_SignVerify.cs
[wrap_unwrap_async]: samples/Sample6_WrapUnwrapAsync.cs
[wrap_unwrap_sync]: samples/Sample6_WrapUnwrap.cs
[hello_world_async]: samples/Sample1_HelloWorldAsync.cs
[hello_world_sync]: samples/Sample1_HelloWorld.cs
[key_client_class]: src/KeyClient.cs
[crypto_client_class]: src/Cryptography/CryptographyClient.cs
[key_client_nuget_package]: https://www.nuget.org/packages/Azure.Security.KeyVault.Keys/
[key_client_samples]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/keyvault/Azure.Security.KeyVault.Keys/samples
[key_client_src]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/keyvault/Azure.Security.KeyVault.Keys/src
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void HelloWorldSync()
// The Cloud RSA Key is no longer needed, need to delete it from the Key Vault.
client.DeleteKey(rsaKeyName);

// To ensure secret is deleted on server side.
// To ensure key is deleted on server side.
Assert.IsTrue(WaitForDeletedKey(client, rsaKeyName));

// If the keyvault is soft-delete enabled, then for permanent deletion, deleted key needs to be purged.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
using Azure.Security.KeyVault.Keys.Cryptography;
using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace Azure.Security.KeyVault.Keys.Samples
{

/// <summary>
/// Sample demonstrates how to encrypt and decrypt a single block of plain text with an RSA key using the synchronous methods of the CryptographyClient.
/// </summary>
[Category("Live")]
public partial class Sample4_EncryptDecypt
{
[Test]
public void EncryptDecryptSync()
{
// Environment variable with the Key Vault endpoint.
string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

// Instantiate a key client that will be used to create a key. Notice that the client is using default Azure
// credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
// 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
var keyClient = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

// Let's create a RSA key which will be used to encrypt and decrypt
string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}";
var rsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 2048);

Key cloudRsaKey = keyClient.CreateRsaKey(rsaKey);
Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyMaterial.KeyType}");

// Let's create the CryptographyClient which can perform cryptographic operations with the key we just created.
// Again we are using the default Azure credential as above.
var cryptoClient = new CryptographyClient(cloudRsaKey.Id, new DefaultAzureCredential());

// Next we'll encrypt some arbitrary plain text with the key using the CryptographyClient. Note that RSA encryption
// algorithms have no chaining so they can only encrypt a single block of plaintext securely. For RSAOAEP this can be
// calculated as (keysize / 8) - 42, or in our case (2048 / 8) - 42 = 214 bytes.
byte[] plaintext = Encoding.UTF8.GetBytes("A single block of plaintext");

// First encrypt the data using RSAOAEP with the created key.
EncryptResult encryptResult = cryptoClient.Encrypt(EncryptionAlgorithm.RSAOAEP, plaintext);
Debug.WriteLine($"Encrypted data using the algorithm {encryptResult.Algorithm}, with key {encryptResult.KeyId}. The resulting encrypted data is {Convert.ToBase64String(encryptResult.Ciphertext)}");

// Now decrypt the encrypted data. Note that the same algorithm must always be used for both encrypt and decrypt
DecryptResult decryptResult = cryptoClient.Decrypt(EncryptionAlgorithm.RSAOAEP, encryptResult.Ciphertext);
Debug.WriteLine($"Decrypted data using the algorithm {decryptResult.Algorithm}, with key {decryptResult.KeyId}. The resulting decrypted data is {Encoding.UTF8.GetString(decryptResult.Plaintext)}");

// The Cloud RSA Key is no longer needed, need to delete it from the Key Vault.
keyClient.DeleteKey(rsaKeyName);

// To ensure key is deleted on server side.
Assert.IsTrue(WaitForDeletedKey(keyClient, rsaKeyName));

// If the keyvault is soft-delete enabled, then for permanent deletion, deleted key needs to be purged.
keyClient.PurgeDeletedKey(rsaKeyName);

}

private bool WaitForDeletedKey(KeyClient client, string keyName)
{
int maxIterations = 20;
for (int i = 0; i < maxIterations; i++)
{
try
{
client.GetDeletedKey(keyName);
return true;
}
catch
{
Thread.Sleep(5000);
}
}
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Azure.Identity;
using Azure.Security.KeyVault.Keys.Cryptography;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;

namespace Azure.Security.KeyVault.Keys.Samples
{

/// <summary>
/// Sample demonstrates how to encrypt and decrypt a single block of plain text with an RSA key using the asynchronous methods of the CryptographyClient.
/// </summary>
[Category("Live")]
public partial class Sample4_EncryptDecypt
{
[Test]
public async Task EncryptDecryptAsync()
{
// Environment variable with the Key Vault endpoint.
string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

// Instantiate a key client that will be used to create a key. Notice that the client is using default Azure
// credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
// 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
var keyClient = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

// First we create a RSA key which will be used to encrypt and decrypt
string rsaKeyName = $"CloudRsaKey-{Guid.NewGuid()}";
var rsaKey = new RsaKeyCreateOptions(rsaKeyName, hsm: false, keySize: 2048);

Key cloudRsaKey = await keyClient.CreateRsaKeyAsync(rsaKey);
Debug.WriteLine($"Key is returned with name {cloudRsaKey.Name} and type {cloudRsaKey.KeyMaterial.KeyType}");

// Then we create the CryptographyClient which can perform cryptographic operations with the key we just created.
// Again we are using the default Azure credential as above.
var cryptoClient = new CryptographyClient(cloudRsaKey.Id, new DefaultAzureCredential());

// Next we'll encrypt some arbitrary plain text with the key using the CryptographyClient. Note that RSA encryption
// algorithms have no chaining so they can only encrypt a single block of plaintext securely. For RSAOAEP this can be
// calculated as (keysize / 8) - 42, or in our case (2048 / 8) - 42 = 214 bytes.
byte[] plaintext = Encoding.UTF8.GetBytes("A single block of plaintext");

// First encrypt the data using RSAOAEP with the created key.
EncryptResult encryptResult = await cryptoClient.EncryptAsync(EncryptionAlgorithm.RSAOAEP, plaintext);
Debug.WriteLine($"Encrypted data using the algorithm {encryptResult.Algorithm}, with key {encryptResult.KeyId}. The resulting encrypted data is {Convert.ToBase64String(encryptResult.Ciphertext)}");

// Now decrypt the encrypted data. Note that the same algorithm must always be used for both encrypt and decrypt
DecryptResult decryptResult = await cryptoClient.DecryptAsync(EncryptionAlgorithm.RSAOAEP, encryptResult.Ciphertext);
Debug.WriteLine($"Decrypted data using the algorithm {decryptResult.Algorithm}, with key {decryptResult.KeyId}. The resulting decrypted data is {Encoding.UTF8.GetString(decryptResult.Plaintext)}");

// The Cloud RSA Key is no longer needed, need to delete it from the Key Vault.
await keyClient.DeleteKeyAsync(rsaKeyName);

// To ensure key is deleted on server side.
Assert.IsTrue(await WaitForDeletedKeyAsync(keyClient, rsaKeyName));

// If the keyvault is soft-delete enabled, then for permanent deletion, deleted key needs to be purged.
await keyClient.PurgeDeletedKeyAsync(rsaKeyName);

}

private async Task<bool> WaitForDeletedKeyAsync(KeyClient client, string keyName)
{
int maxIterations = 20;
for (int i = 0; i < maxIterations; i++)
{
try
{
await client.GetDeletedKeyAsync(keyName);
return true;
}
catch
{
await Task.Delay(5000);
}
}
return false;
}
}
}
Loading

0 comments on commit ffe3f8a

Please sign in to comment.