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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline miser  
#1 Оставлено : 8 апреля 2016 г. 13:48:00(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 152
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Добрый день.
Стоит сборки 4.0.9708 Nechaev. 64 разрядная.

Вот, возник такой интересный вопрос по поводу OID идентификаторов хеш функций.
Использую перебор реализуемых алгоритмов каждым провайдером.
Код:

provider index:0, name:Crypto-Pro GOST R 34.10-2001 KC1 CSP type:75
provider index:1, name:Crypto-Pro GOST R 34.10-2012 KC1 CSP type:80
provider index:2, name:Crypto-Pro GOST R 34.10-2012 KC1 Strong CSP type:81


Поскольку сертификаты сейчас всё еще выпускаются в старом стандарте, будем рассматривать только первого провайдера.

Код:
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) { ... }


В теле цикла выдаем все идентификаторы и OID алгоритмов.

name:GOST 28147-89 longName:GOST 28147-89 algId:26142(661E) OID:1.2.643.2.2.21 type:isCipher
name:GOST R 34.11-94 longName:GOST R 34.11-1994 256 algId:32798(801E) OID:1.2.643.2.2.3 type:isHash
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
name:DH 34.10-2001 longName:GOST R 34.10-2001 256 DH algId:43556(AA24) OID:1.2.643.2.2.98 type:isKeyExchange
name:DH 34.10-2001 longName:GOST R 34.10-2001 256 DH algId:43557(AA25) OID:(null) type:isKeyExchange
name:HMAC GOST 28147-89 longName:HMAC GOST 28147-89 algId:32799(801F) OID:(null) type:isHash



А вопрос вот в чем. В ваших примерах, файл /opt/cprocsp/src/CadesSamples/SimplifiedSignCadesBes/SimplifiedSignCadesBes.cpp

Код:
// Задаем параметры
CRYPT_SIGN_MESSAGE_PARA signPara = { sizeof(signPara) };
signPara.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
signPara.pSigningCert = context;
signPara.HashAlgorithm.pszObjId = (LPSTR) szOID_CP_GOST_R3411; // Хэш считается по ГОСТ Р 34.11-94

/* CRYPT_HASH_ALG_OID_GROUP_ID */
#define szOID_CP_GOST_R3411 "1.2.643.2.2.9"


Но такой алгоритм не реализуется вашим провайдером.
Как они работают?


Попытка указать реализуемый идентификатор OID:1.2.643.2.2.3, приводит к ошибке работы функции CryptSignMessage.
Offline cross  
#2 Оставлено : 8 апреля 2016 г. 14:08:54(UTC)
Анатолий Беляев

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

Группы: Администраторы, Участники
Зарегистрирован: 24.11.2009(UTC)
Сообщений: 965
Откуда: Crypto-Pro

Сказал(а) «Спасибо»: 3 раз
Поблагодарили: 174 раз в 152 постах
"1.2.643.2.2.9" - Функция хэширования ГОСТ Р 34.11-94
"1.2.643.2.2.3" - Алгоритм цифровой подписи ГОСТ Р 34.10-2001 см список
Они имеют одинаковый AlgId, но находятся в разных группах ( Если говорить в терминах функции CryptFindOIDInfo()). Первый в CRYPT_HASH_ALG_OID_GROUP_ID второй в CRYPT_SIGN_ALG_OID_GROUP_ID
Техническую поддержку оказываем тут.
Наша база знаний.
Наша страничка в Instagram.
Offline miser  
#3 Оставлено : 8 апреля 2016 г. 15:43:21(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 152
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Извините, не совсем понял вашу мысль про группы.
Вот, получил я идентификатор алгоритма
Код:
PROV_ENUMALGS_EX *alg;
ALG_ID  algID = alg->aiAlgid;
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;

// печатаю
printf("... type:%s\n", ...
 (isHash ? "isHash" :
 isSignature ? "isSignature" :
 isKeyExchange ? "isKeyExchange" :
 isCipher ? "isCipher" : "other"));


Если бы алгоритм попадал в обе группы, я бы получил "other", а не
Код:
name:GOST R 34.11-94 longName:GOST R 34.11-1994 256 algId:32798(801E) OID:1.2.643.2.2.3 type:isHash


Где еще указывать группу, в примере, указанном в предыдущем сообщении?

Да, я вижу, описание
Код:
/* CRYPT_SIGN_ALG_OID_GROUP_ID */
...
#define szOID_CP_GOST_R3411_R3410EL "1.2.643.2.2.3"



Обращаю ваше внимание, что
alg->szName = GOST R 34.11-94
alg->szLongName = GOST R 34.11-1994 256

а функция возвращает нам OID
PCCRYPT_OID_INFO pOidInf = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY, &algID, 0);

И этот OID, отнюдь не то, что вы написали.
Должно было написать "1.2.643.2.2.9", а написало "1.2.643.2.2.3".

Отредактировано пользователем 8 апреля 2016 г. 15:58:23(UTC)  | Причина: обратите внимание на OID и название алгоритма

Offline Максим Коллегин  
#4 Оставлено : 8 апреля 2016 г. 16:49:24(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,377
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 706 раз в 614 постах
Вы путаете оиды и алгоритмы. Связь между ними весьма слабая и неочевидная - нужно долго читать и курить wincrypt.h
Оид подписи имеет алгидом алгоритм хэша, так написано в wincrypt.h
Знания в базе знаний, поддержка в техподдержке
Offline miser  
#5 Оставлено : 8 апреля 2016 г. 17:39:14(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 152
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Извините, я стараюсь ничего не путать.
Начнем всё по порядку.

В цикле я опрашиваю список алгоритмов, доступных провайдеру.
Код:
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)  | Причина: маленькое дополнение

Offline Максим Коллегин  
#6 Оставлено : 8 апреля 2016 г. 18:50:53(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,377
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 706 раз в 614 постах
В третий раз повторяю - алгид 0x801E зарегистрирован у оида подписи и хэша. Если укажите класс при поиске - небудет неоднозначности.
Знания в базе знаний, поддержка в техподдержке
Offline miser  
#7 Оставлено : 11 апреля 2016 г. 11:06:15(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 152
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Извините, я вашу мысль прекрасно понимаю.
Немного изменил механизм вызова функции CryptFindOIDInfo

Код:
ALG_ID algClass = GET_ALG_CLASS(algID);
const char* type =
    algClass == ALG_CLASS_HASH         ? "Hash" :
    algClass == ALG_CLASS_SIGNATURE    ? "Signature" :
    algClass == ALG_CLASS_KEY_EXCHANGE ? "KeyExchange" :
    algClass == ALG_CLASS_DATA_ENCRYPT ? "Cipher" : "other";

for(DWORD groupId = CRYPT_FIRST_ALG_OID_GROUP_ID; groupId <= CRYPT_LAST_ALG_OID_GROUP_ID; groupId++) {
    PCCRYPT_OID_INFO pOid = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY, &algID, groupId);

    if(pOid != NULL) {
        const char* oidGroupId =
            groupId == CRYPT_HASH_ALG_OID_GROUP_ID     ? "HASH_ALG" :
            groupId == CRYPT_HASH_ALG_OID_GROUP_ID     ? "HASH_ALG" :
            groupId == CRYPT_ENCRYPT_ALG_OID_GROUP_ID  ? "ENCRYPT_ALG" :
            groupId == CRYPT_PUBKEY_ALG_OID_GROUP_ID   ? "PUBKEY_ALG" :
            groupId == CRYPT_SIGN_ALG_OID_GROUP_ID     ? "SIGN_ALG" :
            groupId == CRYPT_RDN_ATTR_OID_GROUP_ID     ? "RDN_ATTR" :
            groupId == CRYPT_EXT_OR_ATTR_OID_GROUP_ID  ? "EXT_OR_ATTR" :
            groupId == CRYPT_ENHKEY_USAGE_OID_GROUP_ID ? "ENHKEY_USAGE" :
            groupId == CRYPT_POLICY_OID_GROUP_ID       ? "POLICY" :
            groupId == CRYPT_TEMPLATE_OID_GROUP_ID     ? "TEMPLATE" : "N/A";

        // печатаем OID алгоритма и тип алгоритма
        fprintf(stderr, "algInfo name:%s longName:%s algId:%d(%X) type:%s OID:%s OID.alg=%d(%X) OID_groupId:%d:%s \n",
            alg->szName, alg->szLongName,
            alg->aiAlgid, alg->aiAlgid,
            type,
            pOidInf->pszOID,
            pOidInf->Algid,
            pOidInf->Algid,
            pOidInf->dwGroupId,
            oidGroupId);
    }
}


Получаем список алгоритмов и неких OID.
Код:
Crypto-Pro GOST R 34.10-2001 KC1 CSP
algInfo name:GOST 28147-89     longName:GOST 28147-89            algId:26142(661E) type:Cipher      OID:1.2.643.2.2.21 OID.alg=26142(661E) OID_groupId:2:ENCRYPT_ALG 
algInfo name:GOST R 34.11-94   longName:GOST R 34.11-1994 256    algId:32798(801E) type:Hash        OID:1.2.643.2.2.3  OID.alg=32798(801E) OID_groupId:4:HASH_ALG 
algInfo name:GOST R 34.11-94   longName:GOST R 34.11-1994 256    algId:32798(801E) type:Hash        OID:1.2.643.2.2.3  OID.alg=32798(801E) OID_groupId:4:SIGN_ALG 
algInfo name:GOST R 34.10-2001 longName:GOST R 34.10-2001 256    algId:11811(2E23) type:Signature   OID:1.2.643.2.2.19 OID.alg=11811(2E23) OID_groupId:3:PUBKEY_ALG 
algInfo name:DH 34.10-2001     longName:GOST R 34.10-2001 256 DH algId:43556(AA24) type:KeyExchange OID:1.2.643.2.2.98 OID.alg=43556(AA24) OID_groupId:3:PUBKEY_ALG 


Crypto-Pro GOST R 34.10-2012 KC1 CSP
algInfo name:GOST 28147-89 longName:GOST 28147-89                algId:26142(661E) type:Cipher      OID:1.2.643.2.2.21 OID.alg=26142(661E)    OID_groupId:2:ENCRYPT_ALG 
algInfo name:GR 34.11-2012 256 longName:GOST R 34.11-2012 256    algId:32801(8021) type:Hash        OID:1.2.643.7.1.1.2.2 OID.alg=32801(8021) OID_groupId:1:HASH_ALG 
algInfo name:GR 34.11-2012 256 longName:GOST R 34.11-2012 256    algId:32801(8021) type:Hash        OID:1.2.643.7.1.1.2.2 OID.alg=32801(8021) OID_groupId:1:SIGN_ALG 
algInfo name:GR 34.10-2012 256 longName:GOST R 34.10-2012 256    algId:11849(2E49) type:Signature   OID:1.2.643.7.1.1.1.1 OID.alg=11849(2E49) OID_groupId:3:PUBKEY_ALG 
algInfo name:DH 34.10-2012 256 longName:GOST R 34.10-2012 256 DH algId:43590(AA46) type:KeyExchange OID:1.2.643.7.1.1.6.1 OID.alg=43590(AA46) OID_groupId:3:PUBKEY_ALG 


Crypto-Pro GOST R 34.10-2012 KC1 Strong CSP
algInfo name:GOST 28147-89 longName:GOST 28147-89                algId:26142(661E) type:Cipher      OID:1.2.643.2.2.21 OID.alg=26142(661E)    OID_groupId:2:ENCRYPT_ALG 
algInfo name:GR 34.11-2012 512 longName:GOST R 34.11-2012 512    algId:32802(8022) type:Hash        OID:1.2.643.7.1.1.2.3 OID.alg=32802(8022) OID_groupId:1:HASH_ALG 
algInfo name:GR 34.11-2012 512 longName:GOST R 34.11-2012 512    algId:32802(8022) type:Hash        OID:1.2.643.7.1.1.2.3 OID.alg=32802(8022) OID_groupId:1:SIGN_ALG 
algInfo name:GR 34.10-2012 512 longName:GOST R 34.10-2012 512    algId:11837(2E3D) type:Signature   OID:1.2.643.7.1.1.1.2 OID.alg=11837(2E3D) OID_groupId:3:PUBKEY_ALG 
algInfo name:DH 34.10-2012 512 longName:GOST R 34.10-2012 512 DH algId:43586(AA42) type:KeyExchange OID:1.2.643.7.1.1.6.2 OID.alg=43586(AA42) OID_groupId:3:PUBKEY_ALG 


Подскажите, как надо правильно сделать, чтобы алгоритм "GOST R 34.11-94" отдал свой OID "1.2.643.2.2.9", а алгоритм "GOST R 34.10-2001" отдал свой OID "1.2.643.2.2.3" ?
Offline Максим Коллегин  
#8 Оставлено : 11 апреля 2016 г. 11:39:05(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,377
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 706 раз в 614 постах
У алгоритма подписи нет algidа, но он может идтенифицировать парой - алгидом ключа и хэша, для получения оида для алгоритма хэширования укажите CRYPT_HASH_ALG_OID_GROUP_ID в CryptFindOIDInfo.

У Вас ошибка в выводе, вот для 0x801E:
Код:

    ALG_ID algID = 0x801E;

    for (DWORD groupId = CRYPT_FIRST_ALG_OID_GROUP_ID; groupId <= CRYPT_LAST_ALG_OID_GROUP_ID; groupId++) {
	PCCRYPT_OID_INFO pOid = CryptFindOIDInfo( CRYPT_OID_INFO_ALGID_KEY, &algID, groupId );

	if (pOid != NULL) {
	    const char* oidGroupId =
		groupId == CRYPT_HASH_ALG_OID_GROUP_ID ? "HASH_ALG" :
		groupId == CRYPT_ENCRYPT_ALG_OID_GROUP_ID ? "ENCRYPT_ALG" :
		groupId == CRYPT_PUBKEY_ALG_OID_GROUP_ID ? "PUBKEY_ALG" :
		groupId == CRYPT_SIGN_ALG_OID_GROUP_ID ? "SIGN_ALG" :
		groupId == CRYPT_RDN_ATTR_OID_GROUP_ID ? "RDN_ATTR" :
		groupId == CRYPT_EXT_OR_ATTR_OID_GROUP_ID ? "EXT_OR_ATTR" :
		groupId == CRYPT_ENHKEY_USAGE_OID_GROUP_ID ? "ENHKEY_USAGE" :
		groupId == CRYPT_POLICY_OID_GROUP_ID ? "POLICY" :
		groupId == CRYPT_TEMPLATE_OID_GROUP_ID ? "TEMPLATE" : "N/A";

	    // печатаем OID алгоритма и тип алгоритма
	    fprintf( stderr, "%S, OID:%s OID.alg=%d(%X) OID_groupId:%d:%s \n",
		pOid->pwszName,
		pOid->pszOID,
		pOid->Algid,
		pOid->Algid,
		pOid->dwGroupId,
		oidGroupId );
	}
    }


Код:
GOST R 34.11-94, OID:1.2.643.2.2.9 OID.alg=32798(801E) OID_groupId:1:HASH_ALG
GOST R 34.11/34.10-2001, OID:1.2.643.2.2.3 OID.alg=32798(801E) OID_groupId:4:SIGN_ALG
Знания в базе знаний, поддержка в техподдержке
Offline Максим Коллегин  
#9 Оставлено : 11 апреля 2016 г. 11:42:21(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,377
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 706 раз в 614 постах
Получение оида подписи:
Код:

ALG_ID algID[2] = { 0x801E, 0x2e23 };
DWORD groupId = CRYPT_SIGN_ALG_OID_GROUP_ID;
PCCRYPT_OID_INFO pOid = CryptFindOIDInfo( CRYPT_OID_INFO_ALGID_KEY, &algID, groupId );

Отредактировано пользователем 11 апреля 2016 г. 11:42:58(UTC)  | Причина: Не указана

Знания в базе знаний, поддержка в техподдержке
Offline miser  
#10 Оставлено : 11 апреля 2016 г. 13:34:13(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 14.03.2011(UTC)
Сообщений: 152
Мужчина
Откуда: Санкт-Петербург

Сказал «Спасибо»: 1 раз
Поблагодарили: 7 раз в 5 постах
Перепроверил свой код. Нашел пропавший OID хеш функции. Ох, как всё сложно и не похоже на старый Win CSP 3.6. Вроде, всё то же самое, а проверок надо делать значительно больше.



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