Статус: Новичок
Группы: Участники
Зарегистрирован: 16.02.2019(UTC) Сообщений: 5
|
Собственно сравнение двух наборов данных.[/img]Добрый вечер. Возможно не совсем корректно сформулировал тему, но постараюсь объяснить суть проблемы. При поиске сертификата по CERT_ID получаю на вход данные по издателю и серийный номер сертификата. Сертификат в виде строки. Полученную строку конвертирую в ASN.1 для заполнения структуры CERT_ISSUER_SERIAL_NUMBER . И тут начинается темная магия. Полученные мной данные издателя отличаются от тех, что хранятся в самом сертификате. Но только тем, что в оригинале у нас NumericString для ИНН и ОГРН. В полученной вручную строке - это OCTET STRING. Соответственно поиск не срабатывает. Как быть? Ниже работающий код и скриншот из ASN.1 редактора. Код:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <wtypes.h>
#include <wincrypt.h>
#include <fstream>
#include <Windows.h>
#include <vector>
#pragma comment(lib, "crypt32.lib")
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define MY_STRING_TYPE (CERT_SIMPLE_NAME_STR)
using ByteArray = std::vector<uint8_t>;
static std::vector<uint8_t> read_file(const std::string& path)
{
std::ifstream file(path, std::ifstream::binary);
if (!file)
throw std::runtime_error("Couldn't open file: " + path);
file.seekg(0, std::ios::end);
std::vector<uint8_t> data(static_cast<size_t>(file.tellg()));
file.seekg(0, std::ios::beg);
file.read(reinterpret_cast<char*>(data.data()), data.size());
if (!file)
throw std::runtime_error("Couldn't read file: " + path);
file.close();
return data;
}// read_file
static ByteArray string2asn1(const LPCSTR pszString, const int str_type)
{
ByteArray result;
DWORD cbSize;
CERT_NAME_BLOB cryptoapi_blob;
if (!(CertStrToNameA(
MY_ENCODING_TYPE,
pszString,
str_type,
NULL,
NULL,
&cbSize,
NULL)))
{
std::cout << "\nCould not get the length of the BLOB.\n";
return result;
}
if (!(cryptoapi_blob.pbData = (LPBYTE)malloc(cbSize)))
{
std::cout << "\nMemory Allocation for the BLOB failed.\n";
return result;
}
cryptoapi_blob.cbData = cbSize;
if (!(CertStrToNameA(
MY_ENCODING_TYPE | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
pszString,
str_type,
NULL,
cryptoapi_blob.pbData,
&cryptoapi_blob.cbData,
NULL)))
{
std::cout << "\nCould not write the blob.\n";
return result;
}
return ByteArray(cryptoapi_blob.pbData, cryptoapi_blob.pbData + cryptoapi_blob.cbData);
}// wstring2asn1
static void write_file(IN const std::string& path, IN const void* data, int size)
{
std::ofstream file(path, std::ofstream::binary | std::ofstream::trunc);
if (!file) {
throw std::runtime_error("Couldn't open file: " + path);
}
file.write(reinterpret_cast<const char*>(data), size);
file.close();
}// write_file
int main(int argc, char* argv[])
{
{
std::string issuer = R"(CN="Тестовый УЦ ООО \"КРИПТО-ПРО\"", O="ООО \"КРИПТО-ПРО\"", C=RU, EMAILADDRESS=info@cryptopro.ru, L=Москва, ST=77 г. Москва, STREET="ул. Сущёвский вал, д. 18", OID.1.2.643.3.131.1.1=#120C303037373137313037393931, OID.1.2.643.100.1=#120D31303337373030303835343434)";
std::string email = "EMAILADDRESS";
issuer.replace(issuer.find(email), email.length(), "E");
ByteArray result((BYTE*)issuer.data(), (BYTE*)issuer.data() + issuer.length());
auto counter = 0;
for (auto& symbol : result)
{
if (symbol == '\\')
symbol = '\"';
}
for (auto& symbol : issuer)
{
if (symbol == '\\')
symbol = '\"';
}
auto calc_issuer = string2asn1(issuer.data(), CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG);
write_file("C:\\test\\issuer_new.txt", calc_issuer.data(), calc_issuer.size());
CERT_ISSUER_SERIAL_NUMBER cert_issuer_serial_number;
auto serial_orig = read_file("C:\\test\\serial.txt");// здесь оригинальный серийник
cert_issuer_serial_number.Issuer.pbData = calc_issuer.data();
cert_issuer_serial_number.Issuer.cbData = static_cast<DWORD>(calc_issuer.size());
cert_issuer_serial_number.SerialNumber.pbData = (BYTE*)(serial_orig.data());
cert_issuer_serial_number.SerialNumber.cbData = static_cast<DWORD>(serial_orig.size());
CERT_ID cert_id;
cert_id.dwIdChoice = 1;
cert_id.IssuerSerialNumber = cert_issuer_serial_number;
HCERTSTORE store_handle;
// Открываем хранилище сертификатов
if (!(store_handle = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY")))
{
std::cout << "cert not found";
}
PCCERT_CONTEXT pCertCtx = CertFindCertificateInStore(
store_handle,
MY_ENCODING_TYPE,
0,
CERT_FIND_CERT_ID,
&cert_id,
nullptr);
if (!pCertCtx)
{
std::cout << "cert not found\n";
}
else
std::cout << "cert found\n";
system("pause");
return 0;
}
}
данные по издателю, полученные из строкиОригиналСравнение двух наборов данныхОтредактировано пользователем 19 февраля 2019 г. 21:54:21(UTC)
| Причина: Не указана
|