Tink для C++: инструкция
Этот документ содержит инструкции и фрагменты кода на C++ для выполнения общих задач в Tink (https://github.com/google/tink).
Tink можно собрать с помощью Bazel (https://www.bazel.build) или CMake (http://cmake.org). Использование любой другой системы сборки в настоящее время не поддерживается. Это означает, что вам нужно будет создать свой двоичный файл с нуля.
Использовать Tink в проектах, созданных с помощью Bazel, просто, и это рекомендуемый подход. Для справки см. примеры C++ (https://github.com/google/tink/tree/master/cc/examples).
Использование Tink с CMake поддерживается, см. CMAKE-HOWTO (CMAKE-HOWTO.md) для подробного описания.
Tink предоставляет настраиваемую инициализацию, которая позволяет выбирать конкретные реализации (идентифицированные типами ключей) желаемых примитивов. Эта инициализация происходит через регистрацию реализаций.
Например, если вы хотите использовать все стандартные реализации всех примитивов в текущей версии Tink, инициализация будет следующей:
#include "tink/config/tink_config.h"
// ...
auto status = TinkConfig::Register();
if (!status.ok()) /* ... обработать ошибку */;
// ...
Чтобы использовать стандартные реализации только одного примитива, скажем AEAD:
#include "tink/aead/aead_config.h"
// ...
auto status = AeadConfig::Register();
if (!status.ok()) /* ... обработать ошибку */;
// ...
Регистрация пользовательских менеджеров ключей может осуществляться напрямую через класс Registry:
#include "tink/registry.h"
#include "custom_project/custom_aead_key_manager.h"
// ...
auto status =
Registry::RegisterKeyManager(absl::make_unique<CustomAeadKeyManager>());
if (!status.ok()) /* ... обработать ошибку */;
Каждая реализация KeyManager предоставляет метод NewKey(template), который генерирует новые ключи соответствующего типа ключа. Однако, чтобы избежать случайного раскрытия конфиденциального ключевого материала, следует избегать смешивания генерации ключей с использованием ключей в коде. Чтобы поддержать разделение между этими действиями, Tink предоставляет инструмент командной строки под названием Tinkey (TINKEY.md), который можно использовать для общих задач управления ключами.
Тем не менее, если необходимо сгенерировать KeysetHandle со свежим ключевым материалом непосредственно в коде C++, можно использовать KeysetHandle (https://github.com/google/tink/blob/master/cc/keyset_handle.h):
auto new_keyset_handl_result = KeysetHandle::GenerateNew(key_template);
if (!new_keysethandl_result.ok()) return new_keysethandl_result.status();
auto keyset_handle = std::move(new_keysethandle_result.ValueOrDie());
// использовать набор ключей...
Рекомендуемые шаблоны ключей можно получить из классов утилит, соответствующих примитивам Tink, например MacKeyTemplates (https://github.com/google/tink/blob/master/cc/mac/mac_key_templates.h), AeadKeyTemplates (https://github.com/google/tink/blob/master/cc/aead/aead_key_templates.h) и HybridKeyTemplates (https://github.com/google/tink/blob/master/cc/hybrid/hybrid_key_templates.h).
Для загрузки зашифрованных наборов ключей используйте KeysetHandle (https://github.com/google/tink/blob/master/cc/keyset_handle.h) и соответствующий KeysetReader (https://github.com/google/tink/blob/master/cc/keyset_reader.h) в зависимости от формата проводов сохранённого набора ключей, например BinaryKeysetReader (https://github.com/google/tink/blob/master/cc/binary_keyset_reader.h) или JsonKeysetReader (https://github.com/google/tink/blob/master/cc/json_keyset_reader.h):
#include "tink/aead.h"
#include "tink/json_keyset_reader.h"
#include "tink/cleartext_keyset_handle.h"
#include "tink/integration/aws_kms_client.h"
// ...
std::string json_encrypted_keyset = ...;
auto reader_result = JsonKeysetReader::New(json_encrypted_keyset);
if (!reader_result.ok()) return reader_result.status();
auto reader = std::move(reader_result.ValueOrDie());
std::string master_key_uri =
``` **aws-kms://arn:aws:kms:us-east-1:007084425826:key/84a65985-f868-4bfc-83c2-366618acf147**;
auto aead = std::move(AwsKmsClient::NewAead(master_key_uri).ValueOrDie());
auto handle_result = KeysetHandle::Read(std::move(reader), *aead);
if (!handle_result.ok()) return handle_result.status();
auto keyset_handle = std::move(handle_result.ValueOrDie());
**Чтобы загрузить ключи в открытом виде, используйте CleartextKeysetHandle и соответствующий KeysetReader:**
```cpp
#include "tink/binary_keyset_reader.h"
#include "tink/cleartext_keyset_handle.h"
// ...
std::string binary_keyset = ...;
auto reader_result = BinaryKeysetReader::New(binary_keyset);
if (!reader_result.ok()) return reader_result.status();
auto reader = std::move(reader_result.ValueOrDie());
auto handle_result = CleartextKeysetHandle::Read(std::move(reader));
if (!handle_result.ok()) return handle_result.status();
auto keyset_handle = std::move(handle_result.ValueOrDie());
## Получение и использование примитивов
Примитивы (PRIMITIVES.md) представляют собой криптографические операции, предлагаемые Tink, и составляют основу API Tink. Примитив — это интерфейс, который определяет, какие операции предлагает примитив. У примитива может быть несколько реализаций, и вы выбираете желаемую реализацию, используя ключ соответствующего типа (см. этот документ для получения дополнительной информации).
Список примитивов и реализаций, поддерживаемых Tink в C++, можно найти здесь (PRIMITIVES.md#c).
Вы получаете примитив, вызывая метод GetPrimitive<> объекта KeysetHandle.
### Симметричное шифрование
Для шифрования или дешифрования данных можно использовать примитив AEAD (аутентифицированное шифрование с присоединёнными данными):
```cpp
#include "tink/aead.h"
#include "tink/keyset_handle.h"
// 1. Получите дескриптор материала ключа.
KeysetHandle keyset_handle = ...;
// 2. Получите примитив.
auto aead_result= keyset_handle.GetPrimitive<Aead>();
if (!aead_result.ok()) return aead_result.status();
auto aead = std::move(aead_result.ValueOrDie());
// 3. Используйте примитив.
auto ciphertext_result = aead.Encrypt(plaintext, aad);
if (!ciphertext_result.ok()) return ciphertext_result.status();
auto ciphertext = std::move(ciphertext_result.ValueOrDie());
Шифрование и дешифрование можно выполнять с помощью комбинации шифрования с открытым ключом и симметричного шифрования:
#include "tink/hybrid_decrypt.h"
#include "tink/keyset_handle.h"
// 1. Получите дескриптор материала ключа.
KeysetHandle keyset_handle = ...;
// 2. Получите примитив.
auto hybrid_decrypt_result = keyset_handle.GetPrimitive<HybridDecrypt>();
if (!hybrid_decrypt_result.ok()) return hybrid_decrypt_result.status();
auto hybrid_decrypt = std::move(hybrid_decrypt_result.ValueOrDie());
// 3. Используйте примитив.
auto plaintext_result = hybrid_decrypt.Decrypt(ciphertext, context_info);
if (!plaintext_result.ok()) return plaintext_result.status();
auto plaintext = std::move(plaintext_result.ValueOrDie());
Через интерфейс AEAD Tink поддерживает шифрование конвертов (KEY-MANAGEMENT.md#envelope-encryption).
Например, вы можете выполнить шифрование конверта с помощью ключа Google Cloud KMS по адресу gcp-kms://projects/tink-examples/locations/global/keyRings/foo/cryptoKeys/bar, используя учётные данные в credentials.json следующим образом:
#include "tink/aead.h"
#include "tink/aead_key_templates.h"
#include "tink/keyset_handle.h"
#include "tink/integration/gcpkms/gcp_kms_client.h"
using crypto::tink::Aead;
using crypto::tink::integration::gcpkms::GcpKmsClient;
std::string kek_uri = "gcp-kms://projects/tink-examples/locations/global/keyRings/foo/cryptoKeys/bar";
``` ```
std::string credentials = "credentials.json";
const KeyTemplate& dek_template = AeadKeyTemplates::Aes128Gcm();
// Регистрируем GcpKmsClient.
auto client_result = GcpKmsClient::RegisterNewClient(kek_uri, credentials);
if (!client_result.ok()) {
std::clog << "Ошибка регистрации клиента GCP KMS: "
<< client_result.status().error_message()
<< "\n";
exit(1);
}
// 1. Получаем дескриптор материала ключа.
const KeyTemplate& envelope_kt = AeadKeyTemplates::KmsEnvelopeAead(kek_uri, dek_template);
auto new_keyset_handle_result = KeysetHandle::GenerateNew(envelope_kt);
if (!new_keyset_handle_result.ok()) return new_keyset_handle_result.status();
// Преимущество шифрования конверта в том, что вам не нужно хранить
// этот дескриптор набора ключей, поскольку он содержит только ссылку на удалённый КЕК.
auto keyset_handle = std::move(new_keyset_handle_result.ValueOrDie());
// 2. Получаем примитив.
auto aead_result= keyset_handle.GetPrimitive<Aead>();
if (!aead_result.ok()) return aead_result.status();
auto aead = std::move(aead_result.ValueOrDie());
// 3. Используем примитив.
auto ciphertext_result = aead->Encrypt(plaintext, aad);
if (!ciphertext_result.ok()) return ciphertext_result.status();
auto ciphertext = std::move(ciphertext_result.ValueOrDie());
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )