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:
parent
0163b09994
commit
a11e69a18c
@ -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
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user