Добрый день.
Я использую CSP для шифрования/расшифрования произвольного блока памяти кузнечиком в режиме MGM. К сожалению в моём тесте после цикла шифрование->расшифрование расшифрованный текст не совпадает с оригинальным. При этом KP_AUTH_TAG операций шифрования и расшифрования совпадают. Судя по всему я что-то упускаю в своём коде. Но не могу понять чего. Подскажите пожалуйста где искать ошибку.
ОС: Red Hat Enterprise Linux Server release 7.9 (Maipo)
Тест:
#include <iostream>
#include <string_view>
#include <gtest/gtest.h>
#include <stdlib.h>
#include <CSP_WinDef.h>
#include <CSP_WinCrypt.h>
#include <CSP_WinError.h>
#include <reader/tchar.h>
#ifndef UNIX
#define UNIX
#endif
#include <WinCryptEx.h>
TEST(CryptoProSuite, MgmEncryptDecrypt) {
// initialization
HCRYPTPROV provider = 0;
ASSERT_TRUE(CryptAcquireContext(&provider, "Demo", nullptr, PROV_GOST_2012_256, CRYPT_NEWKEYSET | CRYPT_SILENT))
<< "Error code: " << GetLastError();
ASSERT_NE(provider, 0);
std::string_view encrypt_key_derive_data = "encrypt key derive data";
HCRYPTKEY base_key = 0;
HCRYPTHASH derive_hash = 0;
ASSERT_TRUE(CryptCreateHash(provider, CALG_GR3411_2012_256, 0, 0, &derive_hash))
<< "Error code: " << GetLastError();
ASSERT_TRUE(CryptHashData(derive_hash,
reinterpret_cast<const BYTE*>(encrypt_key_derive_data.data()), encrypt_key_derive_data.size(), 0))
<< "Error code: " << GetLastError();
ASSERT_TRUE(CryptDeriveKey(provider, CALG_GR3412_2015_K, derive_hash, CRYPT_EXPORTABLE, &base_key))
<< "Error code: " << GetLastError();
const DWORD mode = CRYPT_MODE_MGM;
ASSERT_TRUE(CryptSetKeyParam(base_key, KP_MODE, reinterpret_cast<const BYTE*>(&mode), 0))
<< "Error code: " << GetLastError();
const std::vector<BYTE> stub_iv = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
ASSERT_TRUE(CryptSetKeyParam(base_key, KP_IV, stub_iv.data(), 0)) << "Error code: " << GetLastError();
HCRYPTKEY encrypt_key = 0;
ASSERT_TRUE(CryptDuplicateKey(base_key, nullptr, 0, &encrypt_key)) << "Error code: " << GetLastError();
CRYPT_DATA_BLOB encrypt_additional_data = {};
ASSERT_TRUE(CryptSetKeyParam(encrypt_key, KP_AUTH_DATA, reinterpret_cast<BYTE*>(&encrypt_additional_data), 0))
<< "Error code: " << GetLastError();
std::string original = "original string";
std::string encrypted = original;
DWORD data_len = encrypted.size();
ASSERT_TRUE(CryptEncrypt(encrypt_key, 0, true, 0, reinterpret_cast<BYTE*>(encrypted.data()), &data_len, encrypted.size()))
<< "Error code: " << GetLastError();
DWORD auth_tag_len = 0;
ASSERT_TRUE(CryptGetKeyParam(encrypt_key, KP_AUTH_TAG, nullptr, &auth_tag_len, 0))
<< "Error code: " << GetLastError();
constexpr size_t expected_auth_tag_len = 16;
ASSERT_EQ(auth_tag_len, expected_auth_tag_len);
std::vector<BYTE> encrypt_auth_tag(expected_auth_tag_len);
ASSERT_TRUE(CryptGetKeyParam(encrypt_key, KP_AUTH_TAG, encrypt_auth_tag.data(), &auth_tag_len, 0))
<< "Error code: " << GetLastError();
ASSERT_EQ(data_len, original.size());
ASSERT_NE(encrypted, original);
HCRYPTKEY decrypt_key = 0;
ASSERT_TRUE(CryptDuplicateKey(base_key, nullptr, 0, &decrypt_key)) << "Error code: " << GetLastError();
CRYPT_DATA_BLOB decrypt_additional_data = {};
ASSERT_TRUE(CryptSetKeyParam(encrypt_key, KP_AUTH_DATA, reinterpret_cast<BYTE*>(&decrypt_additional_data), 0))
<< "Error code: " << GetLastError();
auto decrypted = encrypted;
data_len = decrypted.size();
ASSERT_TRUE(CryptDecrypt(decrypt_key, 0, true, 0, reinterpret_cast<BYTE*>(decrypted.data()), &data_len))
<< "Error code: " << GetLastError();
ASSERT_TRUE(CryptGetKeyParam(encrypt_key, KP_AUTH_TAG, nullptr, &auth_tag_len, 0))
<< "Error code: " << GetLastError();
ASSERT_EQ(auth_tag_len, expected_auth_tag_len);
std::vector<BYTE> decrypt_auth_tag(expected_auth_tag_len);
ASSERT_TRUE(CryptGetKeyParam(encrypt_key, KP_AUTH_TAG, decrypt_auth_tag.data(), &auth_tag_len, 0))
<< "Error code: " << GetLastError();
ASSERT_EQ(encrypt_auth_tag, decrypt_auth_tag);
ASSERT_EQ(data_len, original.size());
ASSERT_EQ(decrypted, original);
CryptDestroyKey(decrypt_key);
CryptDestroyKey(encrypt_key);
CryptDestroyKey(base_key);
CryptDestroyHash(derive_hash);
CryptReleaseContext(provider, 0);
}
Отредактировано пользователем 23 января 2025 г. 14:14:25(UTC)
| Причина: Не указана