Key Vault Keys crypto samples (#2450)

* encrypt_decrypt

* sign verify

* wrap and unwrap

* Apply suggestions from code review

Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>

Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>
This commit is contained in:
Victor Vazquez 2021-06-21 11:34:41 -07:00 committed by GitHub
parent 0163b09994
commit a11e69a18c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 555 additions and 0 deletions

View File

@ -0,0 +1,80 @@
# Encrypting and decrypt keys
This sample demonstrates how to encrypt and decrypt a single block of plain text with an RSA key.
To get started, you'll need a URL to an Azure Key Vault. See the [README](https://github.com/Azure/azure-sdk-for-cpp/blob/master/sdk/keyvault/azure-security-keyvault-keys/README.md) 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.
Key Vault Keys client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and client secret as environment variables.
```cpp Snippet:KeysSample1CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:KeysSample1KeyClient
KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating a key
First, we create a RSA key which will be used to encrypt and decrypt.
```cpp
// Let's create a RSA key which will be used to encrypt and decrypt
auto rsaKeyName = "CloudRsaKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto keyOptions = CreateRsaKeyOptions(rsaKeyName, false);
keyOptions.KeySize = 2048;
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(keyOptions).Value;
std::cout << " - Key is returned with name " << cloudRsaKey.Name() << " and type "
<< cloudRsaKey.GetKeyType().ToString() << std::endl;
```
## Creating a CryptographyClient
We create the `CryptographyClient` which can perform cryptographic operations with the key we just created using the same credential created above.
```cpp
CryptographyClient cryptoClient(cloudRsaKey.Id(), credential);
```
## Encrypting a key
Next, we'll encrypt some arbitrary plaintext 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.
```cpp
uint8_t const data[] = "A single block of plaintext";
std::vector<uint8_t> plaintext(std::begin(data), std::end(data));
EncryptResult encryptResult = cryptoClient.Encrypt(EncryptionAlgorithm::RsaOaep, plaintext);
std::cout << " - Encrypted data using the algorithm " << encryptResult.Algorithm.ToString()
<< ",with key " << encryptResult.KeyId << ". The resulting encrypted data is: "
<< Azure::Core::Convert::Base64Encode(encryptResult.Ciphertext) << std::endl;
```
## Decrypting a key
Now decrypt the encrypted data. Note that the same algorithm must always be used for both encrypt and decrypt.
```cpp
DecryptResult decryptResult
= cryptoClient.Decrypt(EncryptionAlgorithm::RsaOaep, encryptResult.Ciphertext);
std::cout << " - Decrypted data using the algorithm " << decryptResult.Algorithm.ToString()
<< ", with key " << decryptResult.KeyId << ". The resulting decrypted data is: "
<< std::string(decryptResult.Plaintext.begin(), decryptResult.Plaintext.end())
<< std::endl;
```
## Source
To see the full example source, see:
- sample4_encrypt_decrypt.cpp

View File

@ -0,0 +1,148 @@
# Signing and verifying keys
This sample demonstrates how to sign data with both a RSA key and an EC key.
To get started, you'll need a URI to an Azure Key Vault. See the [README](https://github.com/Azure/azure-sdk-for-cpp/blob/master/sdk/keyvault/azure-security-keyvault-keys/README.md) 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.
Key Vault Keys client for C++ currently supports the `ClientSecretCredential` for authenticating.
In the sample below, you can create a credential by setting the Tenant ID, Client ID and client secret as environment variables.
```cpp Snippet:KeysSample1CreateCredential
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
```
Then, in the sample below, you can set `keyVaultUrl` based on an environment variable, configuration setting, or any way that works for your application.
```cpp Snippet:KeysSample1KeyClient
KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
```
## Creating keys
First, we'll create both an RSA key and an EC key which will be used to sign and verify.
```cpp
auto rsaKeyName = "CloudRsaKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto keyOptions = CreateRsaKeyOptions(rsaKeyName, false);
keyOptions.KeySize = 2048;
auto ecKeyName = "CloudEcKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto ecKeyOptions = CreateEcKeyOptions(ecKeyName, false);
ecKeyOptions.CurveName = KeyCurveName::P256K;
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(keyOptions).Value;
std::cout << " - Key is returned with name " << cloudRsaKey.Name() << " and type "
<< cloudRsaKey.GetKeyType().ToString() << std::endl;
KeyVaultKey cloudEcKey = keyClient.CreateEcKey(ecKeyOptions).Value;
std::cout << " - Key is returned with name " << cloudEcKey.Name() << " and type "
<< cloudEcKey.GetKeyType().ToString() << std::endl;
```
## Creating CryptographyClients
Then, we create the `CryptographyClient` which can perform cryptographic operations with the key we just created using the same credential created above.
```cpp
CryptographyClient rsaCryptoClient(cloudRsaKey.Id(), credential);
CryptographyClient ecCryptoClient(cloudEcKey.Id(), credential);
```
## Signing keys with the Sign and Verify methods
Next, we'll sign some arbitrary data and verify the signatures using the `CryptographyClient` with both the EC and RSA keys we created.
The `Sign` and `Verify` methods expect a precalculated digest, and the digest needs to be calculated using the hash algorithm which matches the signature algorithm being used.
SHA256 is the hash algorithm used for both RS256 and ES256K which are the algorithms we'll be using in this sample.
```cpp
uint8_t const dataSource[]
= "This is some sample data which we will use to demonstrate sign and verify";
std::vector<uint8_t> data(std::begin(dataSource), std::end(dataSource));
std::vector<uint8_t> digest;
{
Azure::Security::KeyVault::SHA256 hashAlgo;
digest = hashAlgo.Final(data.data(), data.size());
}
// Sign and Verify from digest
SignResult rsaSignResult = rsaCryptoClient.Sign(SignatureAlgorithm::RS256, digest);
std::cout << " - Signed digest using the algorithm " << rsaSignResult.Algorithm.ToString()
<< ", with key " << rsaSignResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(rsaSignResult.Signature) << std::endl;
SignResult ecSignResult = ecCryptoClient.Sign(SignatureAlgorithm::ES256K, digest);
std::cout << " - Signed digest using the algorithm " << ecSignResult.Algorithm.ToString()
<< ", with key " << ecSignResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(ecSignResult.Signature) << std::endl;
```
## Verifying signatures
Verify the digest by comparing the signature you created previously.
```cpp
VerifyResult rsaVerifyResult
= rsaCryptoClient.Verify(SignatureAlgorithm::RS256, digest, rsaSignResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< rsaVerifyResult.Algorithm.ToString() << ", with key " << rsaVerifyResult.KeyId
<< ". Signature is valid: " << (rsaVerifyResult.IsValid ? "True" : "False")
<< std::endl;
VerifyResult ecVerifyResult
= ecCryptoClient.Verify(SignatureAlgorithm::ES256K, digest, ecSignResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< ecVerifyResult.Algorithm.ToString() << ", with key " << ecVerifyResult.KeyId
<< ". Signature is valid: " << (ecVerifyResult.IsValid ? "True" : "False") << std::endl;
```
## Signing keys with the SignData and VerifyData methods
The `SignData` and `VerifyData` methods take the raw data which is to be signed. The calculate the digest for the user so there is no need to compute the digest.
```cpp
SignResult rsaSignDataResult = rsaCryptoClient.SignData(SignatureAlgorithm::RS256, data);
std::cout << " - Signed data using the algorithm " << rsaSignDataResult.Algorithm.ToString()
<< ", with key " << rsaSignDataResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(rsaSignDataResult.Signature) << std::endl;
SignResult ecSignDataResult = ecCryptoClient.SignData(SignatureAlgorithm::ES256K, data);
std::cout << " - Signed data using the algorithm " << ecSignDataResult.Algorithm.ToString()
<< ", with key " << ecSignDataResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(ecSignDataResult.Signature) << std::endl;
```
## Verifying signatures with VerifyData methods
You can provide the same data for which you generated a signature above to `VerifyData` to generate and compare the digest. To be valid, the generated digest must match the given signature.
```cpp
VerifyResult rsaVerifyDataResult
= rsaCryptoClient.VerifyData(SignatureAlgorithm::RS256, data, rsaSignDataResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< rsaVerifyDataResult.Algorithm.ToString() << ", with key "
<< rsaVerifyDataResult.KeyId
<< ". Signature is valid: " << (rsaVerifyDataResult.IsValid ? "True" : "False")
<< std::endl;
VerifyResult ecVerifyDataResult
= ecCryptoClient.VerifyData(SignatureAlgorithm::ES256K, data, ecSignDataResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< ecVerifyDataResult.Algorithm.ToString() << ", with key " << ecVerifyDataResult.KeyId
<< ". Signature is valid: " << (ecVerifyDataResult.IsValid ? "True" : "False")
<< std::endl;
```
## Source
To see the full example source, see:
- sample5_sign_verify.cpp

View File

@ -6,3 +6,6 @@ cmake_minimum_required (VERSION 3.13)
add_subdirectory(sample1-hello-world)
add_subdirectory(sample2-backup-and-restore)
add_subdirectory(sample3-get-keys)
add_subdirectory(sample4-encrypt-decrypt)
add_subdirectory(sample5-sign-verify)
add_subdirectory(sample6-wrap-unwrap)

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample4-encrypt-decrypt LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample4-encrypt-decrypt
sample4_encrypt_decrypt.cpp
)
target_link_libraries(sample4-encrypt-decrypt PRIVATE azure-security-keyvault-keys azure-identity)

View File

@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample demonstrates how to encrypt and decrypt a single block of plain text with an
* RSA key using the methods of the CryptographyClient.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/core.hpp>
#include <azure/identity.hpp>
#include <azure/keyvault/key_vault_keys.hpp>
#include <chrono>
#include <iostream>
#include <vector>
using namespace Azure::Security::KeyVault::Keys;
using namespace Azure::Security::KeyVault::Keys::Cryptography;
using namespace std::chrono_literals;
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
// Let's create a RSA key which will be used to encrypt and decrypt
auto rsaKeyName = "CloudRsaKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto keyOptions = CreateRsaKeyOptions(rsaKeyName, false);
keyOptions.KeySize = 2048;
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(keyOptions).Value;
std::cout << " - Key is returned with name " << cloudRsaKey.Name() << " and type "
<< cloudRsaKey.GetKeyType().ToString() << std::endl;
CryptographyClient cryptoClient(cloudRsaKey.Id(), credential);
uint8_t const data[] = "A single block of plaintext";
std::vector<uint8_t> plaintext(std::begin(data), std::end(data));
EncryptResult encryptResult = cryptoClient.Encrypt(EncryptionAlgorithm::RsaOaep, plaintext);
std::cout << " - Encrypted data using the algorithm " << encryptResult.Algorithm.ToString()
<< ", with key " << encryptResult.KeyId << ". The resulting encrypted data is: "
<< Azure::Core::Convert::Base64Encode(encryptResult.Ciphertext) << std::endl;
DecryptResult decryptResult
= cryptoClient.Decrypt(EncryptionAlgorithm::RsaOaep, encryptResult.Ciphertext);
std::cout << " - Decrypted data using the algorithm " << decryptResult.Algorithm.ToString()
<< ", with key " << decryptResult.KeyId << ". The resulting decrypted data is: "
<< std::string(decryptResult.Plaintext.begin(), decryptResult.Plaintext.end())
<< std::endl;
// Delete the key
auto deleteOperation = keyClient.StartDeleteKey(rsaKeyName);
deleteOperation.PollUntilDone(2min);
keyClient.PurgeDeletedKey(rsaKeyName);
}

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample5-sign-verify LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample5-sign-verify
sample5_sign_verify.cpp
)
target_link_libraries(sample5-sign-verify PRIVATE azure-security-keyvault-keys azure-identity)

View File

@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample demonstrates how to sign data with both a RSA key and an EC key using the
* synchronous methods of the CryptographyClient.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/core.hpp>
#include <azure/identity.hpp>
#include <azure/keyvault/common/sha.hpp>
#include <azure/keyvault/key_vault_keys.hpp>
#include <chrono>
#include <iostream>
#include <vector>
using namespace Azure::Security::KeyVault::Keys;
using namespace Azure::Security::KeyVault::Keys::Cryptography;
using namespace std::chrono_literals;
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
auto rsaKeyName = "CloudRsaKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto keyOptions = CreateRsaKeyOptions(rsaKeyName, false);
keyOptions.KeySize = 2048;
auto ecKeyName = "CloudEcKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto ecKeyOptions = CreateEcKeyOptions(ecKeyName, false);
ecKeyOptions.CurveName = KeyCurveName::P256K;
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(keyOptions).Value;
std::cout << " - Key is returned with name " << cloudRsaKey.Name() << " and type "
<< cloudRsaKey.GetKeyType().ToString() << std::endl;
KeyVaultKey cloudEcKey = keyClient.CreateEcKey(ecKeyOptions).Value;
std::cout << " - Key is returned with name " << cloudEcKey.Name() << " and type "
<< cloudEcKey.GetKeyType().ToString() << std::endl;
CryptographyClient rsaCryptoClient(cloudRsaKey.Id(), credential);
CryptographyClient ecCryptoClient(cloudEcKey.Id(), credential);
uint8_t const dataSource[]
= "This is some sample data which we will use to demonstrate sign and verify";
std::vector<uint8_t> data(std::begin(dataSource), std::end(dataSource));
std::vector<uint8_t> digest;
{
Azure::Security::KeyVault::SHA256 hashAlgo;
digest = hashAlgo.Final(data.data(), data.size());
}
// Sign and Verify from digest
SignResult rsaSignResult = rsaCryptoClient.Sign(SignatureAlgorithm::RS256, digest);
std::cout << " - Signed digest using the algorithm " << rsaSignResult.Algorithm.ToString()
<< ", with key " << rsaSignResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(rsaSignResult.Signature) << std::endl;
SignResult ecSignResult = ecCryptoClient.Sign(SignatureAlgorithm::ES256K, digest);
std::cout << " - Signed digest using the algorithm " << ecSignResult.Algorithm.ToString()
<< ", with key " << ecSignResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(ecSignResult.Signature) << std::endl;
VerifyResult rsaVerifyResult
= rsaCryptoClient.Verify(SignatureAlgorithm::RS256, digest, rsaSignResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< rsaVerifyResult.Algorithm.ToString() << ", with key " << rsaVerifyResult.KeyId
<< ". Signature is valid: " << (rsaVerifyResult.IsValid ? "True" : "False")
<< std::endl;
VerifyResult ecVerifyResult
= ecCryptoClient.Verify(SignatureAlgorithm::ES256K, digest, ecSignResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< ecVerifyResult.Algorithm.ToString() << ", with key " << ecVerifyResult.KeyId
<< ". Signature is valid: " << (ecVerifyResult.IsValid ? "True" : "False") << std::endl;
// Sign and Verify from data
SignResult rsaSignDataResult = rsaCryptoClient.SignData(SignatureAlgorithm::RS256, data);
std::cout << " - Signed data using the algorithm " << rsaSignDataResult.Algorithm.ToString()
<< ", with key " << rsaSignDataResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(rsaSignDataResult.Signature) << std::endl;
SignResult ecSignDataResult = ecCryptoClient.SignData(SignatureAlgorithm::ES256K, data);
std::cout << " - Signed data using the algorithm " << ecSignDataResult.Algorithm.ToString()
<< ", with key " << ecSignDataResult.KeyId << ". The resulting signature is: "
<< Azure::Core::Convert::Base64Encode(ecSignDataResult.Signature) << std::endl;
VerifyResult rsaVerifyDataResult
= rsaCryptoClient.VerifyData(SignatureAlgorithm::RS256, data, rsaSignDataResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< rsaVerifyDataResult.Algorithm.ToString() << ", with key "
<< rsaVerifyDataResult.KeyId
<< ". Signature is valid: " << (rsaVerifyDataResult.IsValid ? "True" : "False")
<< std::endl;
VerifyResult ecVerifyDataResult
= ecCryptoClient.VerifyData(SignatureAlgorithm::ES256K, data, ecSignDataResult.Signature);
std::cout << " - Verified the signature using the algorithm "
<< ecVerifyDataResult.Algorithm.ToString() << ", with key " << ecVerifyDataResult.KeyId
<< ". Signature is valid: " << (ecVerifyDataResult.IsValid ? "True" : "False")
<< std::endl;
// Delete the key
auto deleteOperation = keyClient.StartDeleteKey(rsaKeyName);
auto ecDeleteOperation = keyClient.StartDeleteKey(ecKeyName);
deleteOperation.PollUntilDone(2min);
ecDeleteOperation.PollUntilDone(2min);
keyClient.PurgeDeletedKey(rsaKeyName);
keyClient.PurgeDeletedKey(ecKeyName);
}

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.13)
project (sample6-wrap-unwrap LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (
sample6-wrap-unwrap
sample6_wrap_unwrap.cpp
)
target_link_libraries(sample6-wrap-unwrap PRIVATE azure-security-keyvault-keys azure-identity)

View File

@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This sample demonstrates how to sign data with both a RSA key and an EC key using the
* synchronous methods of the CryptographyClient.
*
* @remark The following environment variables must be set before running the sample.
* - AZURE_KEYVAULT_URL: To the Key Vault account URL.
* - AZURE_TENANT_ID: Tenant ID for the Azure account.
* - AZURE_CLIENT_ID: The Client ID to authenticate the request.
* - AZURE_CLIENT_SECRET: The client secret.
*
*/
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <azure/core.hpp>
#include <azure/identity.hpp>
#include <azure/keyvault/common/sha.hpp>
#include <azure/keyvault/key_vault_keys.hpp>
#include <chrono>
#include <iostream>
#include <vector>
using namespace Azure::Security::KeyVault::Keys;
using namespace Azure::Security::KeyVault::Keys::Cryptography;
using namespace std::chrono_literals;
int main()
{
auto tenantId = std::getenv("AZURE_TENANT_ID");
auto clientId = std::getenv("AZURE_CLIENT_ID");
auto clientSecret = std::getenv("AZURE_CLIENT_SECRET");
auto credential
= std::make_shared<Azure::Identity::ClientSecretCredential>(tenantId, clientId, clientSecret);
KeyClient keyClient(std::getenv("AZURE_KEYVAULT_URL"), credential);
auto rsaKeyName = "CloudRsaKey-" + Azure::Core::Uuid::CreateUuid().ToString();
auto keyOptions = CreateRsaKeyOptions(rsaKeyName, false);
keyOptions.KeySize = 2048;
KeyVaultKey cloudRsaKey = keyClient.CreateRsaKey(keyOptions).Value;
std::cout << " - Key is returned with name " << cloudRsaKey.Name() << " and type "
<< cloudRsaKey.GetKeyType().ToString() << std::endl;
CryptographyClient cryptoClient(cloudRsaKey.Id(), credential);
// keyDataSource simulates a symmetric private key created locally in the system. It is not
// relevant for the sample how to create the private key as it depends on the OS.
// For example, on linux, the key can be created using openSSL.
uint8_t const keyDataSource[]
= "MIIBOgIBAAJBAKUFtjMCrEZzg30Rb5EQnFy6fFUTn3wwVPM9yW4Icn7EMk34ic+"
"3CYytbOqbRQDDUtbyUCdMEu2OZ0RPqL4GWMECAwEAAQJAcHi7HHs25XF3bbeDfbB/"
"kae8c9PDAEaEr6At+......";
std::vector<uint8_t> keyData(std::begin(keyDataSource), std::end(keyDataSource));
std::cout << " - Using a sample generated key: " << Azure::Core::Convert::Base64Encode(keyData)
<< std::endl;
WrapResult wrapResult = cryptoClient.WrapKey(KeyWrapAlgorithm::RsaOaep, keyData);
std::cout << " - Encrypted data using the algorithm " << wrapResult.Algorithm.ToString()
<< ", with key " << wrapResult.KeyId << ". The resulting encrypted data is: "
<< Azure::Core::Convert::Base64Encode(wrapResult.EncryptedKey) << std::endl;
UnwrapResult unwrapResult
= cryptoClient.UnwrapKey(KeyWrapAlgorithm::RsaOaep, wrapResult.EncryptedKey);
std::cout << " - Decrypted data using the algorithm " << unwrapResult.Algorithm.ToString()
<< ", with key " << unwrapResult.KeyId << ". The resulting decrypted data is: "
<< Azure::Core::Convert::Base64Encode(unwrapResult.Key) << std::endl;
// Delete the key
auto deleteOperation = keyClient.StartDeleteKey(rsaKeyName);
deleteOperation.PollUntilDone(2min);
keyClient.PurgeDeletedKey(rsaKeyName);
}