04.02.2006 19:24:38Вопросы новичка Ответов: 6
ian
Добрый день.
Сразу оговорюсь, что абсолютный новичок по отношению к CryptoAPI, да и к криптографии вобщем-то(всего несколько дней разбираюсь с этим пока и впечатления достаточно противоречивые), так что сильно не пинайте.
Есть следующая задачка: на серваке хранится "документ", который нужно "подписывать" нескольким "клиентам". Здесь и начинаются проблемы(моего понимания). Документ не пересылается клиентам, подписывается хеш, выданный сервером, а значит используются низкоуровневые функции(CryptSignHash,...).
То есть нужно использовать заранее определённую схему кеширования(алгоритм), а это ведёт к несовместимости в условиях наличия нескольких CSP. Пока я ничего нигде не "проморгал"?
Далее, сам процесс подписи - тут, как я понимаю, лучше(нужно) использовать сертификаты открытых ключей(из них уже вытягивать ключи), а не просто ключи(как потом выйти от ключей к "людям", и более "серьёзная" проверка самого сертификата на валидность, например)? Прав?
И хранить подпись вместе с сертификатом опять же на сервере. Что обычно находится у клиента на защищённом носителе(дискета, флэщка), ключи вместе с сертификатом?

Кстати, как создать пару ключей и сертификат с помощью КриптоПро(у меня имеется демо)? Выполняю следующее(пытаюсь создать пару ключей):

csptest-2-0.exe -keyset -newkeyset -provtype 71 -keytype signature -container MyContainer

в ответ:

CryptAcquireContext succeeded.HCRYPTPROV: 1269048
CryptGetProvParam succeeded.
Provider name: Crypto-Pro GOST R 34.10-94 KC2 CSP
A crypto context has been acquired and
The name on the key container is "MyContainer"

No signature key is available.
The signature key does not exist.
Create a signature key pair.
An error occurred in running the program.
ctkey.c:1290:Error occurred creating a signature key.

Error number 80090020 (-2146893792).
An internal error occurred.
Program terminating.
Press Enter to exit.

Заранее благодарен всем ответившим.
 
Ответы:
06.02.2006 11:21:47Kirill Sobolev
Отвечаю по порядку:
"Документ не пересылается клиентам, подписывается хеш, выданный сервером, а значит используются низкоуровневые функции(CryptSignHash,...)." - неудачная схема.
"Получается, что клиент не видит что реально подписывает.
заранее определённую схему кеширования(алгоритм), а это ведёт к несовместимости в условиях наличия нескольких CSP". Схему хеширования? Да, только если CSP, реализующие один и тот же алгоритм, несовместимы между собой. Это легко учесть и включить в требования на стадии проектирования - вообщем то достаточно требовать наличия какого-то определенного провайдера.
"Прав?" Абсолютно.
"Что обычно находится у клиента на защищённом носителе(дискета, флэщка), ключи вместе с сертификатом?" Да, именно это и находится.
"Error number 80090020 (-2146893792)." У Вас, скорее всего, нету аппаратного генератора случайных чисел, в КС2 биологический не установлен. 2 варианта - либо поставьте КриптоПро CSP КС1, либо добавьте биологический датчик случайных чисел в KC2.
06.02.2006 17:35:17ian
Кирилл, спасибо за ответы.
По поводу неудачной схемы - это да, но если нужно не перекачивать файлы с сервера клиенту, то какое решение может тут иметь своё место?... К слову, Множественная подпись - это просто подписание подписанного документа энное количество раз? Хотелось бы иметь подписи к исходному документу, а не к документу, "нагруженному" другими подписями - выход "detached signing" или есть некий стандарт?

"Схему хеширования? Да, только если CSP, реализующие один и тот же алгоритм, несовместимы между собой. Это легко учесть и включить в требования на стадии проектирования - вообщем то достаточно требовать наличия какого-то определенного провайдера."
Суть вопроса в том, что КриптоПро CSP не будет подписывать MD5-хэш, так же как, скажем, ' Microsoft Enhanced Cryptographic Provider v1.0' не будет это же делать с ГОСТовским хэшем ... :( А значит, требования - наличия единого провайдера.

"У Вас, скорее всего, нету аппаратного генератора случайных чисел, в КС2 биологический не установлен. 2 варианта - либо поставьте КриптоПро CSP КС1, либо добавьте биологический датчик случайных чисел в KC2."
Спасибо, заработало.

Еще, если не против, вопрос. Как узнать ALGORITHM_ID(не прописывая его явно в коде) алгоритма, которым "следует" генерировать хэш, конкретного провайдера? C помощью CryptGetProvParam(...,PP_ENUMALGS_EX,...) можно их перечислить, причём некоторые провайдеры возвращают в dwProtocols что-то(0x20(CRYPT_FLAG_SIGNING) для подписи), а некоторые нет...
06.02.2006 17:51:41Kirill Sobolev
Все зависит от клиентов. Если они согласны подписывать "кота в мешке", то такая схема пройдет. Однако возможна подмена данных на сервере перед или в момент подписания.
Сами подписи друг другу не мешают. Зависит от того каким способом Вы будете подписывать - добавлять подпись к существующим, заверять уже существующие, удалять предыдущую и добавлять новую - в любом случае исходный документ без подписей можно получить без проблем. Detached нужно для того чтобы хранить подпись отдельно от документа. Допустим у Вас есть база документов и Вы хотите каждый подписать - создавать новое поле, которое будет содержать подпись + исходный документ плохой вариант, для этого и существует detached.
Вопрос про хэш не совсем понятен. Если провайдер поддерживает несколько алгоритмов, то хешировать можно любым из них, а каким именно - должно определяться дополнительными требованиями.
06.02.2006 18:32:19ian
"Все зависит от клиентов. Если они согласны подписывать "кота в мешке", то такая схема пройдет. Однако возможна подмена данных на сервере перед или в момент подписания."
Это конечно. А также интересен вопрос о "самописном" софте, не должен ли он быть каким либо образом "сертифицирован", ведь при желании, ничто не мешает отказаться от подписи ввиду отсутствия "сертифицированного инструмента".

"Вопрос про хэш не совсем понятен."
Тут вопрос о возможности узнать метод(даже не знаю..., рекомендованный что-ли) хэширования данного криптопровайдера(и не из документации :) ). Вот например, список поддерживаемых алгоритмов:

ALG_ID(OID) | (key length(min,def,max)) | dwProtocols | Name
---
26142(1.2.643.2.2.21) | (256,256,256) | 0x0 | GOST
28147-89(ProCSP ГОСТ 28147-89)
32798(1.2.643.2.2.9) | (256,256,256) | 0x0 | GOST R
34.11-94(ProCSP ГОСТ Р 34.11-94)
32799(NULL) | (32,32,32) | 0x0 | HMAC GOST
28147-89(ProCSP Имитовставка ГОСТ 28147-89)
11806(1.2.643.2.2.20) | (1024,1024,1024) | 0x0 | GOST R
34.10-94(ProCSP ГОСТ Р 34.10-94)
43550(1.2.643.2.2.99) | (1024,1024,1024) | 0x0 |
Diffie-Hellman(ProCSP Диффи-Хелман Крипто Про ГОСТ)
43551(NULL) | (1024,1024,1024) | 0x0 |
Diffie-Hellman(ProCSP Диффи-Хелман Крипто Про ГОСТ)

как тут узнать какой протокол используется для "signing", а про "рекомендуемый" и говорить не приходится(или я не прав - буду очень обрадован, если не прав :) )? То есть протокол необходимо "зашивать"...
07.02.2006 10:29:56Kirill Sobolev
Про равнозначность подписи и сертифицированность лучше почитать в Законе об ЭЦП http://www.cryptopro.ru/cryptopro/documentation/pdf/podpis.pdf.
Тип алгоритма содержится в его ALG_ID. Например
#define CALG_GR3411 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_GR3411), #define CALG_GR3410EL (ALG_CLASS_SIGNATURE | ALG_TYPE_GR3410 | ALG_SID_GR3410EL). Эти константы прописаны в wincryptex.h. Рекомендуемый алгоритм, конечно, по ним определить нельзя.
07.02.2006 18:29:18ian
Кирилл, спасибо за подсказки.