Столкнулся с такой непонятной для меня ситуацией. Установил несколько тестовых сертификатов от КриптоПро, чтобы проверить корректность наложения ЭЦП. В одном сертификате такие параметры:
Алгоритм подписи: ГОСТ Р 34.11-2012/34.10-2012 256 бит
Хэш-алгоритм подписи: ГОСТ Р 34.11-2012 256 бит
Открытый ключ: ГОСТ Р 34.11-2012 512 бит
В другом
Алгоритм подписи: ГОСТ Р 34.11-2012/34.10-2012 256 бит
Хэш-алгоритм подписи: ГОСТ Р 34.11-2012 256 бит
Открытый ключ: ГОСТ Р 34.11-2012 256 бит
Я сперва посчитал, что раз в обоих случаях алгоритм подписи и хэш-алгоритм подписи одинаковы, то для формирования хэша будет использоваться один и тот же алгоритм - CALG_GR3411_2012_256 (32801). Ага, щаз. В случае использования второго сертификата с открытым ключом на 256 бит это было справедливо. А вот для сертификата с открытым ключом в 512 бит опытным путём удалось установить, что надо использовать другой алгоритм - CALG_GR3411_2012_512 (32802). Тогда всё накладывается корректно и запрос получается правильным.
И я сейчас пытаюсь понять, как программно вытащить информацию о правильном хэш-алгоритме. Пишу на Делфи, вот код
repeat
pCertContext := CertEnumCertificatesInStore(hStoreHandle, pCertContext);
if (pCertContext <> nil) then
begin
pSignerCert := CertDuplicateCertificateContext(pCertContext);
if not CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, nil, @cbSize) then
continue;
if (cbSize < 1) then
continue;
GetMem(pInfo, cbSize);
CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pInfo, @cbSize);
// из pInfo запоминаю pInfo^.pwszProvName и pInfo^.dwProvType
// алгоритм пытаюсь вытащить так
pOidInfo := CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, PChar(pSignerCert^.pCertInfo.SignatureAlgorithm.pszObjId), 0);
AlgID := CertOIDToAlgId(pOidInfo^.pszOID); // получаю CALG_GR3411_2012_256 (32801) сам pszOID = 1.2.643.7.1.1.3.2
pOidInfo := CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, PChar(pSignerCert^.pCertInfo.SubjectPublicKeyInfo.Algorithm.pszObjId), 0);
// здесь у pOidInfo pszOID = 1.2.643.7.1.1.1.2, что соответствует группе { CRYPT_PUBKEY_ALG_OID_GROUP_ID } и константе в ней szOID_CP_GOST_R3410_12_512 (взято из wincryptex)
AlgID := CertOIDToAlgId(pOidInfo^.pszOID); // получаю CALG_GR3410_12_512 (11837) а надо CALG_GR3411_2012_512 (32802)
// запоминаю нужные данные
....
until (pCertContext = nil);
И я понимаю, что ищу не то, что надо искать данные именно для хэш-алгоритма, но при этом не могу понять, какими процедурами это можно сделать, используя контекст конкретного сертификата. Подскажите пожалуйста.
С уважением, Александр.