Извините, я стараюсь ничего не путать.
Начнем всё по порядку.
В цикле я опрашиваю список алгоритмов, доступных провайдеру.
Код:void EnumAlgs(HCRYPTPROV hProv) {
PROV_ENUMALGS_EX data;
DWORD dataLen = sizeof(PROV_ENUMALGS_EX);
for( DWORD flags = CRYPT_FIRST;
CryptGetProvParam(hProv, PP_ENUMALGS_EX, (BYTE*)&data, &dataLen, flags);
flags = CRYPT_NEXT)
FindOIDs(&data);
}
void FindOIDs(PROV_ENUMALGS_EX *alg) {
ALG_ID algID = alg->aiAlgid;
PCCRYPT_OID_INFO pOidInf = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY, &algID, 0);
ALG_ID algClass = GET_ALG_CLASS(algID);
BOOL isHash = algClass == ALG_CLASS_HASH;
BOOL isSignature = algClass == ALG_CLASS_SIGNATURE;
BOOL isKeyExchange = algClass == ALG_CLASS_KEY_EXCHANGE;
BOOL isCipher = algClass == ALG_CLASS_DATA_ENCRYPT;
char* type =
isHash ? "Hash" :
isSignature ? "Signature" :
isKeyExchange ? "KeyExchange" :
isCipher ? "Cipher" : "other";
printf("name:%s longName:%s algId:%d(%X) OID:%s type:%s\n",
alg->szName,
alg->szLongName,
alg->aiAlgid,
alg->aiAlgid,
(pOidInf == NULL ? NULL : pOidInf->pszOID),
type);
}
Ничего сложного тут нет. Разве, что метод CryptFindOIDInfo.
Последний параметр выставлен в 0.
Цитата:Setting this parameter to zero searches all groups according to the dwKeyType parameter.
Я показываю, что
1) название алгоритма - ГОСТ хеш функция.
2) группа алгоритма - хеш функция.
А вот, OID - это алгоритм подписи.
Гдето, глубоко в коде своей программы, эти идентификаторы запомнил.
Надо подписать документ. Беру OID ключа из сертификата. Примерно так же, как делает ваш пример, /opt/cprocsp/src/doxygen/CSP/SignUtility/SignUtility.c
Код:stSignMessagePara.HashAlgorithm.pszObjId = GetHashOidByKeyOid(pCertCtx->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
Но вместо жестко пробитых OID, идет поиск алгоритма по названию "GOST R 34.11-94".
И естественно, моя система возвращает тот OID, который был получен ранее - "1.2.643.2.2.3".
Да, на текущем этапе, сделал отдачу OID так же, как сделано в вашем примере. Подпись заработала.
Можно было бы поступить еще хитрее. Можно было бы расковырять сертификат или полное описание алгоритма и получить OID нужной функции.
Да, обратите внимание, какой OID возвращает наш алгоритм подписи.
Цитата:name:GOST R 34.10-2001 longName:GOST R 34.10-2001 256 algId:11811(2E23) OID:1.2.643.2.2.19 type:isSignature
OID соответствует "Алгоритм ГОСТ Р 34.10-2001, используемый при экспорте/импорте ключей".
А должен был выдать OID ""1.2.643.2.2.3"" "Алгоритм цифровой подписи ГОСТ Р 34.10-2001". Потому, как это подпись. А "1.2.643.2.2.19" - это, кажется, KeyExchange.
Буду рад, если это глюки моей машины.
Отредактировано пользователем 8 апреля 2016 г. 17:54:08(UTC)
| Причина: маленькое дополнение