Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline cherale  
#1 Оставлено : 23 января 2025 г. 14:07:21(UTC)
cherale

Статус: Новичок

Группы: Участники
Зарегистрирован: 23.01.2025(UTC)
Сообщений: 2
Российская Федерация
Откуда: Москва

Добрый день.

Я использую 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)  | Причина: Не указана

Online Андрей *  
#2 Оставлено : 23 января 2025 г. 17:54:57(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,444
Мужчина
Российская Федерация

Сказал «Спасибо»: 552 раз
Поблагодарили: 2235 раз в 1743 постах
Здравствуйте.

decrypt_key как будет инициализирован перед расшированием на стороне получателя?

KP_IV читать ... откуда? или это константой в коде будет?

В SDK посмотреть пример \samples\CSP\DecryptFile\
Техническую поддержку оказываем тут
Наша база знаний
Offline cherale  
#3 Оставлено : 23 января 2025 г. 17:58:58(UTC)
cherale

Статус: Новичок

Группы: Участники
Зарегистрирован: 23.01.2025(UTC)
Сообщений: 2
Российская Федерация
Откуда: Москва

И encrypt_key и decrypt_key - дубликаты базового ключа. KP_IV у них одина и та же константа для теста.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.