Секреты разработки CSP

  • Вид работы:
    Статья
  • Предмет:
    Информатика, ВТ, телекоммуникации
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    420,04 kb
  • Опубликовано:
    2009-01-12
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Секреты разработки CSP

Секреты разработки CSP

Юрий Зырянов

Введение

Эта статья для тех, кто по тем или иным причинам решил написать собственный крипто-провайдер для OC семейства Windows. Если Вы хотите реализовать в вашем провайдере нестандартные алгоритмы, то вам предстоит столкнуться с определенными трудностями. Трудности могут возникнуть, например, при попытках использования вашего крипто-провайдера для проверки сертификатов в MS Internet Explorer.

Под нестандартными алгоритмами здесь понимаются не всемирные DES, RSA, DSA и т.д, а, например, алгоритмы семейства ГОСТ. Дело в том, что для RSA и подобных алгоритмов все необходимые идентификаторы уже зашиты в систему, а для ГОСТ-ов (или многих других алгоритмов) надо отдельно позаботиться о том, чтобы система их “увидела”.

Для примеров кода используется Си. Все примеры кода служат только для иллюстрации принципов изложенных в статье и не являются полноценными рабочими программами.

Также подразумевается, что у читателя есть базовые знания в области прикладной криптографии и термины “открытый ключ”, “ASN.1” и подобные для него не являются загадкой.

Интеграция провайдера в Windows

Помимо наличия библиотеки самого провайдера дополнительно требуется:

зарегистрировать провайдер и крипто-алгоритмы в системе, прописав определенные параметры в реестре;

создать библиотеку с функциями конвертирования ключей из форматов криптопровайдера во внешние форматы и зарегистрировать эти функции в реестре;

заменить функцию I_CryptGetDefaultCryptProvider в библиотеке crypt32.dll

Только после выполнения этих действий провайдер нормально интегрируется в систему и вы сможете, например, генерировать сертификаты при помощи вашего провайдера на основе стандартного компонента ОС Windows Server - Сertification services или на тестовом УЦ КриптоПро #"67167.files/image001.jpg">

Рисунок 1 - Идентификаторы алгоритмов

Далее приведен пример кода регистрации OID алгоритма ГОСТ-34.11-94

 // Регистрация GOST-3411-94 HASH OID

 //

 CRYPT_OID_INFO oidInfo;

 int rc = 0;

 

 memset(&oidInfo, 0, sizeof(CRYPT_OID_INFO));

 oidInfo.cbSize = sizeof(CRYPT_OID_INFO);

 oidInfo.pszOID="1.2.643.2.2.9";

 oidInfo.pwszName= L"GOST-3411-94 HASH";

 oidInfo.dwGroupId = CRYPT_HASH_ALG_OID_GROUP_ID;

 oidInfo.Algid = 0x801e;

 oidInfo.ExtraInfo.cbData=0;

 oidInfo.ExtraInfo.pbData=0;

 rc = CryptRegisterOIDInfo(

  &oidInfo,

  0

 );

 if(rc)

  printf("nHash algorithm registered”);

 else

  printf("nError registering hash algorithm”);

Аналогично регистрируются и остальные алгоритмы. Подробную информацию о структуре CRYPT_OID_INFO можно найти в MSDN: #"67167.files/image002.jpg">

Рисунок 2 - Запрос на сертификат в УЦ

Рисунок 3 - Процесс создания сертификата

Оказывается, существуют промежуточные функции для экспорта/импорта открытых ключей, и без их реализации ничего хорошего с нашим CSP, в упомянутых выше двух сценариях, не получиться. Беда еще и в том, что функции эти недокументированные и найти информацию по ним крайне сложно. Их описанию посвящен следующий раздел.

Функции конвертирования ключей

Архитектура круговорота открытых ключей для “нестандартных” алгоритмов в Windows представлена на картинке:

Рисунок 4 - Импорт и экспорт открытых ключей в/из CSP

Функция A_ConvertPublicKeyInfo – на входе принимает ключ в формате ASN.1 DER и должна преобразовать его в формат, который “понимает” функция CSP CPImportKey

Функция A_EncodePublicKeyInfoAndParameters на входе принимает ключ в том формате, в котором ключ экспортирует CPExportKey. На выходе A_EncodePublicKeyInfoAndParameters должна сформировать ASN.1 DER структуру с ключом – ту же самую которая в случае импорта передается в A_ConvertPublicKeyInfo – на вход. Надеюсь, вы не запутались во всех этих входах Jи выходах 

Вот сигнатуры и краткие описания параметров этих функций:

BOOL WINAPI A_ConvertPublicKeyInfo(

 DWORD dwCertEncodingType,  // IN -

 VOID *EncodedKeyInfo,  // IN – буфер с ключом - указатель

// на структуру CERT_PUBLIC_KEY_INFO

 DWORD dwAlg,   // IN – AlgId ключа

 DWORD dwFlags,   // IN – обычно 0

BYTE **ppStructInfo, // OUT  – двойной указатель на структуру

// в заголовке структуры идет сначала PUBLICKEYSTRUC, затем DSSPUBKEY,

 // а затем сам ключ с параметрами  

 DWORD *StructLen  // OUT  – длинна структуры

);

BOOL WINAPI A_EncodePublicKeyAndParameters(

 DWORD dwCertEncodingType,   // IN

 LPCSTR lpszStructType,   // IN – OID алгоритма

 const void* pvStructInfo,   // IN – такая же структура как

// на выходе ConvertPublicKeyInfo

 DWORD nStructLen,  // IN – длинна входной структуры

 DWORD dwFlags,   // IN – обычно 0

 DWORD Unk,   // ?  - неизвестно

 BYTE **pbPubKey,  // OUT – открытый ключ в ASN.1 DER

 DWORD* pcPubKeyLen,  // OUT – длинна открытого ключа

 BYTE **pbParams,  // OUT – параметры открытого ключа

 DWORD* pcParamsLen // OUT – длинна параметров

);

Форматы ключей зависят от крипто-провайдера и используемых алгоритмов.

Функция I_CryptGetDefaultCryptProvider из crypt32.dll

По непонятной для меня причине Windows часто не пытается искать нужный крипто- провайдер по идентификатору алгоритма с которым требуется работать. В таких случаях она просто вызывает недокументированную функцию I_CryptGetDefaultCryptProvider, и если тот провайдер, который вернула эта функция, не умеет работать с данным алгоритмом, то процесс завершается с ошибкой. Так происходит, например, при разборе в Internet Explorer PKCS#7 ответа в сценарии с запросом сертификата на тестовом УЦ.

HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID algid);

Необходимо заменить эту функцию таким образом, чтобы при нулевом параметре algid на входе она возвращала наш провайдер, который уже в отличии от штатного провайдера легко справиться с “нестандартными алгоритмами”.

Обсуждение способов замены функций в системной dll выходит далеко за рамки данной статьи. Могу лишь, как один из способов решения, предложить библиотеку Microsoft Detours: #"67167.files/image005.jpg">

Рисунок 5 - Закрытый ключ сертификата

Контекст сертификата это набор дополнительных атрибутов сертификата, которые находятся не в теле сертификата, а хранятся отдельно от него. Одним из таких атрибутов и является ссылка на закрытый ключ, которая состоит из имени провайдера и имени ключевого контейнера.

Пример кода для привязки закрытого ключа к сертификату:

 PCCERT_CONTEXT pCert;

 CRYPT_KEY_PROV_INFO prov_info;

 …

 prov_info.cProvParam = 0;

 prov_info.rgProvParam = 0;

 prov_info.dwFlags = 0;

 prov_info.dwKeySpec = AT_SIGNATURE;

 prov_info.dwProvType = 0;

 prov_info.pwszContainerName = L"key-kont-name";

 prov_info.pwszProvName = L"A-CSP";

 CertSetCertificateContextProperty(

  pCert,

  CERT_KEY_PROV_INFO_PROP_ID,

  0,

  &prov_info

 );

Успехов в разработке крипто-провайдера!

#"#">http://www.realcoding.net/

Похожие работы на - Секреты разработки CSP

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!