| ||||
| ||||
Доброго времени суток, Возникла следующая проблема. Импортирую открытый ключ в BYTE* (в C++ используя CryptoAPI), получаю последовательность байтов размером 100. Далее мне нужно сравнить этот открытый ключ с открытым ключом сертификата, при этом для сравнения я вытаскиваю открытый ключ из сертификата уже в программе на C# .NET, используя X509Certificate2 класс. ТАк вот, при получении открытого ключа сертификата в .NET я получаю последовательность байтов размером 65-66 байт (у каждого сертификата по разному почему то). И так получается что эти 65-66 байтов совпадают с последними 66-65ю байтами ранее импортированного открытогоключа (размером 100 байт) начиная со второго байта. В чём подвох? Как сравнить открытые ключи полученные из .NET и из CryptoAPI (C++)? | ||||
Ответы: | ||||
| ||||
66 байт - это закодированный ОК, который лежит в CERT_INFO::SubjectPublicKeyInfo.PublicKey.pbData, его и надо сравнивать. Еще, конечно, помимо значения надо сравнивать алгоритм. | ||||
| ||||
Дело в том, что у меня есть только импортированный открытый ключ в файле. А почему он туда размером 100 байт записался тогда? | ||||
| ||||
Туда еще попадает инфа об алгоритме и параметрах. struct CRYPT_PUBLICKEYBLOB { CRYPT_PUBKEY_INFO_HEADER tPublicKeyParam; BYTE bASN1GostR3410_94_PublicKeyParameters [1]; BYTE bPublicKey [1]; }; Вам нужен собственно только bPublicKey. | ||||
| ||||
Ясно. А вот у меня в результате имеется 100 байт с открытым ключём и некой информацией. Теперь мне отсюда нужно вытащить именно сам открытый ключ (нет сертификата в наличии, открытый ключ передаётся для проверки ЭЦП). Это возможно? | ||||
| ||||
Конечно. Собственно обратная процедура - CryptImportKey, получается хендл ОК. Затем CryptExportPublicKeyInfoEx в структуру CERT_PUBLIC_KEY_INFO, там уже отдельно лежат сам ОК и его алгоритм/параметры. | ||||
| ||||
CryptExportPublicKeyInfo - тут вот вторым параметром идёт keySpec, а у меня его нет. Его можно как то получить из провайдера? Если до этого провайдер был проинициализирован так: CryptAcquireContext(&hProv, NULL, NULL, 75, CRYPT_VERIFYCONTEXT) | ||||
| ||||
Я ошибся, CryptExportPublicKeyInfo вообще похоже без секретного ключа не работает :( | ||||
| ||||
То есть без секретного ключа получается что я не могу из 100 байтов в результате получить открытый ключик? | ||||
| ||||
Если есть блоб ОК ГОСТа 2001-го года (100 байт) и он не зашифрован, то значение ОК имеется в нём в открытом виде (последние 64 байта). Если делаем CryptImportKey - получаем хендл ОК, который можно использовать для операций, не требующих закрытого ключа, например, при проверке подписи. | ||||
| ||||
А оставшиеся 2 байта (до 66), которые я получаю когда импортирую открытый ключ из X509Certificate2 (.NET) в byte[], это что? Всмысле мне сранивать последние 64 байта из 100 и последние 64 из 66? | ||||
| ||||
2 байта перед ключом (ГОСТ.. 2001) - заголовок ASN.1, означающий - тип содержимого (OCTET STRING) и длину содержимого (64 байта). | ||||