Секрети розробки CSP
По незрозумілою мені причини Windows часто вже не намагається шукати потрібний криптопровайдер по ідентифікатору алгоритму з яким потрібно працювати. У разі він викликає недокументированную функцію I_CryptGetDefaultCryptProvider, і що той провайдер, який повернула цю функцію, не вміє працювати з цим алгоритмом, то процес завершується з помилкою. Так відбувається, наприклад, при розборі в Internet… Читати ще >
Секрети розробки CSP (реферат, курсова, диплом, контрольна)
Секреты розробки CSP
Юрий Зырянов.
Введение
Эта стаття тим, хто з тим чи іншим причин вирішив написати власний крипто-провайдер для OC сімейства Windows. Якщо ви хочете реалізовувати вашому провайдеру нестандартні алгоритми, то, вам доведеться мати справу з певними труднощами. Труднощі виникатимуть, наприклад, за будь-яких спроб використання вашого крипто-провайдера для перевірки сертифікатів в MS Internet Explorer.
Под нестандартними алгоритмами тут розуміються не всесвітні DES, RSA, DSA тощо, а, наприклад, алгоритми сімейства ГОСТ. Річ у тому, що з RSA та інших алгоритмів всі необхідні ідентифікатори вже зашиті до системи, а ГОСТ-ов (чи багатьох інших алгоритмів) треба окремо подбати у тому, щоб система їх «побачила».
Для прикладів коду використовується Сі. Усі приклади коду є лише для ілюстрації принципів викладені у статті й є повноцінними робітниками програмами.
Также мається на увазі, що з читача є базові знання з прикладної криптографії і терміни «відкритий ключ», «ASN.1» і подібні йому є загадкою.
Интеграция провайдера в Windows
Помимо наявності бібліотеки самого провайдера додатково потрібно:
зарегистрировать провайдер і крипто-алгоритмы в системі, прописавши певні параметри в реєстрі;
создать бібліотеку з функціями конвертування ключів з форматів криптопровайдера в зовнішні формати і зареєструвати цих функцій в реєстрі;
заменить функцію I_CryptGetDefaultCryptProvider в бібліотеці crypt32.dll.
Только після виконання цих дій провайдер нормально інтегрується до системи і це зможете, наприклад, генерувати сертифікати з допомогою вашого провайдера з урахуванням стандартного компонента ОС Windows Server — Сertification services чи тестовому УЦ КриптоПро internet.
Корректно вказуватиметься статус перевірки підписи у сертифікатів, підписаних вашим «нестандартним» алгоритмом тощо.
Далее докладно розглянемо кожен із згаданих вище кроків, припускаючи у своїй що бібліотека з Вашим CSP вже є і коректно працюють всі функції провайдера.
Регистрация крипто-провайдера і алгоритмів в системе
Когда ви вже сьогодні є готова бібліотека у реалізації функцій CSP, необхідно зареєструвати їх у системі, щоб новий крипто-провайдер став доступний різним додатків.
Процесс реєстрації самого CSP докладно описаний в MDSN, і повторювати цю інформацію тут немає сенсу. Усе це докладно описано в [1]. Також тут думати зупинятися на проблемі підписи нового CSP в Microsoft і можливі шляхи її обходу. Проблема вже багаторазово обговорювалася на різних форумах, наприклад дивіться [3]. Значно цікавіше розглянути реєстрацію криптографічних алгоритмів. Кожен алгоритм має власний унікальний ASN.1 идентификтор Оbject Identifier — OID. Наприклад, алгоритм підписи ГОСТ-34.10−2001 має тої OID (поданий у вигляді рядки) — «1.2.643.2.2.3». Ідентифікатор кожного підтримуваного вашим CSP алгоритму слід занести до реєстру. Крім OID в кожного крипто-алгоритма в Windows є ще ідентифікатор як четырех-байтового числа — AlgID, по якому алгоритми ідентифікуються в провайдеру. Цей ідентифікатор заноситися в CSP і можна дізнатися перерахувавши алгоритми у вигляді виклику CPGetProvParam. У КриптоПро, наприклад, для алгоритму хеширования ГОСТ-34.11−94 AlgID використовується значення 0×801e.
Пусть слід зареєструвати алгоритм підписи ГОСТ-34.10−2001. Тоді, у реєстрі необхідно прописати такі ідентифікатори:
«1.2.643.2.2. 9!1» — Хэш ГОСТ-34.11−94.
«1.2.643.2.2.19!3» — Ключ підписи ГОСТ-34.10−2001.
«1.2.643.2.2.3!4» — Підпис ГОСТ-34.10−2001 — Алгоритм Хэша + Алгоритм Ключ.
.
Рисунок 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 = 0×801e;
oidInfo.ExtraInfo.cbData=0;
oidInfo.ExtraInfo.pbData=0;
rc = CryptRegisterOIDInfo (.
&oidInfo,.
);
if (rc).
printf («nHash algorithm registered»);
else.
printf («nError registering hash algorithm»);
Аналогично реєструються й інші алгоритми. Детальну інформацію про структуру CRYPT_OID_INFO можна знайти у MSDN: internet.
Для здобуття права провайдер викликався для перевірки сертифіката, підписаного нашим «нестандартним» алгоритмом необхідний іще один додаткове дію.
Дело у цьому, що Windows визначає який провайдер використовуватиме перевірки полем ExtraInfo (див. заслання у попередньому абзаці для цього поля) в ключі реєстру соответвующему алгоритму підписи — такий ключ ми створюємо, викликаючи функцію CryptRegisterOIDInfo. Тому потрібно вказати системі наш провайдер як провайдера за умовчанням для типу, який занесли у ExtraInfo алгоритму підписи.
Следующий код встановлює провайдер за умовчанням для певного типу.
#define YOUR_PROV_NAME «MY_PROV «.
#define YOUR_PROV_TYPE 75.
rc = CryptSetProvider (.
YOUR_PROV_NAME,.
YOUR_PROV_TYPE.
);
Сценарии застосування нашого CSP.
Рассмотрим тут два сценарію застосування CSP.
Первый сценарій — перевірка підписи сертифіката. Для перевірки підписи система завантажує відкритий ключ з сертифіката, яким підписано проверяемый. Потім за OID алгоритму підписи проверяемого сертифіката, оскільки описано у минулому розділі статті, визначається необхідний провайдер. Щоб перевірити підпис, потрібно імпортувати відкритий ключ в CSP і можна було подумати що Windows відразу викликає функцію нашого провайдера CPImportKey. Не так сталося!
Второй сценарій — генерація ключовою пари відправка запиту на сертифікат на Котра Засвідчує Центр. Windows завантажує наш CSP, генерує ключову пару і експортує себе нагору відкритий ключ викликаючи функцію CPExportKey. Усе добре. Начебто треба взяти й помістити отриманий буфер з ключем в PKCS#10 запит, і потім пошлють на УЦ. І тоді все знову зовсім така.
.
Рисунок 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: internet.
Привязка закритого ключа до сертификату
В на відміну від відкритого ключа закриті ключі будь-коли залишають крипто-провайдер і коли ви бачите що з даного сертифіката є закритий ключ (як у малюнку) це що означає що у контексті цього сертифіката існує явна посилання закритий ключ.
.
Рисунок 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.
);
Успехов з розробки крипто-провайдера!
internet.
Формы в HTML документах Некоторые WWW browser дозволяють користувачеві, заповнивши спеціальну форму, возвращающую отримане значення, виконувати деякі дії вашому WWW — сервері. Коли форма інтерпретується WEB — броузером, створюється спеціальні екранні елементи GUI, такі, як поля введення, checkboxes, radiobuttons, які меню, скроллируемые списки, кнопки тощо. Коли користувач заповнює форму і натискає кнопку «Підтвердження «(SUBMIT — спеціальний тип кнопки, який задається в описах документа), інформація, введена користувачем до форми, посилається HTTP-серверу для обробітку грунту і передачі інших програмах, працюючим під сервером, згідно з CGI (Common Gateway Interface) интерфейсом.
Когда ви описуєте форму, кожен елемент введення даних має тэг <INPUT>. Коли користувач поміщає дані в елемент форми, инфоромация розміщається розділ VALUE даного элемента.
Синтаксис.
Все форми починаються тэгом <FORM> і звершаются тэгом </FORM>.
<FORM METHOD= «get|post «ACTION= «URL «> Элементы_формы_и_другие_элементы_HTML </FORM>
METHOD.
Метод посилки повідомлення з цими з форми. У залежність від використовуваного методу ви можете посилати результати введення даних до форми двома путями:
GET: Інформація з форми додається насамкінець URL, який був вказаний у описі заголовка форми. Ваша CGI-программа (CGI-скрипт) отримує дані з форми як параметра перемінної середовища QUERY_STRING. Використання методу GET категорично не рекомендується.
POST: Він передає усю інформацію форму негайно після звернення до зазначеного URL. Ваша CGI-программа отримує дані з форми в стандартний потік введення. Сервер нічого очікувати пересилати вам повідомлення про закінчення пересилки даних у стандартний потік введення; натомість використовується змінна середовища CONTENT_LENGTH визначення, скільки даних вам треба вважати з стандартного потоку введення. Він рекомендується до використанню.
ACTION.
ACTION описує URL, який викликатися для обробки форми. Цей URL майже завжди свідчить про CGI-программу, обробну цю форму.
Тэги Форми.
TEXTAREA.
Тэг <TEXTAREA> використовується у тому, щоб дозволити користувачеві вводити більше рядки інформації (вільний текст). Ось приклад использовани тэга <TEXTAREA>:
<TEXTAREA NAME= «address «ROWS=10 COLS=50>Москва, Дмитровкое шоссе, д.9Б, офіс 448 </TEXTAREA>
Атрибуты, використовувані всередині тэга <TEXTAREA> описують зовнішній вигляд й ім'я який вводимо значення. Тэг </TEXTAREA> необхідний навіть, коли полі введення спочатку порожній. Опис атрибутов:
NAME — ім'я поля введення.
ROWS — висота поля входження у символах.
COLS — ширина поля входження у символах.
Если ви мені хочете, щоб у полі введення за умовчанням видавався будь-якої текст, необхідно вставити його всередині тэгов <TEXTAREA> і </TEXTAREA>.
INPUT.
Тэг <INPUT> використовується для введення рядка тексту чи слова. Атрибути тэга:
CHECKED — означає, що CHECKBOX чи RADIOBUTTON буде обраний.
MAXLENGTH — визначає кількість символів, яке користувачі можуть вводити на полі введення. У разі перевищення кількості допустимих символів броузер реагує на спробу введення нового символу звуковим сигналом і це не дає його запровадити. Не плутати з атрибутом SIZE. Якщо MAXLENGTH більш ніж SIZE, то полі здійснюється скролінг. За умовчанням значення MAXLENGTH одно нескінченності.
NAME — ім'я поля введення. Дане ім'я використовують як унікальний ідентифікатор поля, яким, згодом, ви дістанете дані, вміщені користувачем до цього полі.
SIZE — визначає візуальний розмір поля введення на екрані в символах.
SRC — URL,. який би на картинку (використовується що з атрибутом IMAGE).
VALUE — привласнює полю значення за умовчанням чи значення, що буде вибрано під час використання типу RADIO (для типу RADIO даний атрибут обов’язковий).
TYPE — визначає тип поля введення. За умовчанням це просте полі введення одній рядки тексту. Інші типи би мало бути явно, их повний перелік наведено нижче:
CHECKBOX.
Используется простих логічних (BOOLEAN) значень. Значення, асоційоване безпосередньо з ім'ям даного поля, що буде передаватимуть у викликувану CGI-программу, може приймати значення ON чи OFF.
HIDDEN.
Поля такого типу не відбиваються броузером не дають користувачеві змінювати присвоенныеданному полю за умовчанням значення. Це полі используетс передачі в CGI-программу статичної інформації, а саме ID прользователя, пароля або інший інформації.
IMAGE.
Данный тип поля введення дозволяє вам пов’язувати графічний малюнок безпосередньо з ім'ям поля. При натисканні мишею ні на яку частина малюнка буде негайно викликана асоційована формі CGI-программа. Значення, присвоєні перемінної NAME виглядатимуть так — створюється дві нових змінних: перша має ім'я, позначене на полі NAME з додаванням .x наприкінці імені. У цю зміну буде вміщена X-координата точки в пикселах (вважаючи початком координат лівий верхній кут малюнка), яку вказував курсор миші в останній момент натискання, а змінна безпосередньо з ім'ям, які мають NAME і доданим .y, міститиме Y-координату. Усі значення атрибута VALUE ігноруються. Саме опис картинки здійснюється через атрибут SRC і з синтаксису збігаються з тэгом <IMG>.
PASSWORD.
То саме, як і атрибут TEXT, але введені користувачем значення не відображається броузером на екрані.
RADIO.
Данный атрибут дозволяє вводити одне значення з кількох альтернатив. До сформування набору альтернатив вам необхідно створити кілька полів введення з атрибутом TYPE= «RADIO «з різними значеннями атрибута VALUE, але з значеннями атрибута NAME. У CGI-программу передають значення типу NAME=VALUE, причому VALUE прийме значення атрибута VALUE того поля введення, що у цей час буде вибрано (буде активним). При виборі однієї з полів введення типу RADIO й інші поля такого типу з тим самим ім'ям (атрибут NAME) механічно стануть невыбранными на экране.
RESET.
Данный тип позначає кнопку, при натисканні якій усе поля форми приймуть значення, описані їм по умолчанию.
SUBMIT.
Данный тип позначає кнопку, при натисканні якої викликана CGI-программа (чи URL), описана в заголовку форми. Атрибут VALUE може містити рядок, яка высвечена на кнопке.
TEXT.
Данный тип поля введення описує однострочное полі введення. Використовуйте атрибути MAXLENGTH і SIZE визначення максимальної довгі який вводимо значення символах та розміру відображуваного поля введення на екрані (за умовчанням приймається 20 символов).
Меню вибору формах Под меню вибору формах розуміють такий елемент інтерфейсу, як LISTBOX. Існує три типу тэгов меню вибору форм:
Select — користувач вибирає одне значення з фіксованого списку значень, представлених тэгами OPTION. Даннй вид подається як выпадающий LISTBOX.
Select single — той самий, як і Select, але екрані користувач бачить одночасно три елемента вибору. Якщо цього більше, то надається автоматичний вертикальний скролінг.
Select multiple — дозволяє вибрати кілька елементів з LISTBOX.
SELECT.
Тэг SELECT дозволяє користувачеві вибрати значення з фіксованого списку значень. Зазвичай подано випадаючого меню.
Тэг SELECT має чи більш параметр пежду стартовим тэгом <SELECT> і завершальним </SELECT>.По вмовчанням, перший елемент відображається в рядку вибору. Ось приклад тэга <SELECT>:
<FORM>
<SELECT NAME=group>
<OPTION> AT 386.
<OPTION> AT 486.
<OPTION> AT 586.
</SELECT>
</FORM>
SELECT SINGLE.
Тэг SELECT SINGLE — це саме саме, як і Select, але на екрані користувач бачить одночасно кілька елементів вибору (три — по вмовчанням). Якщо цього більше, то надається автоматичний вертикальний скролінг. Кількість одночасно відображуваних елементів визначається атрибутом SIZE. Пример:
<FORM>
<SELECT SINGLE NAME=group SIZE=4>
<OPTION> AT 386.
<OPTION> AT 486.
<OPTION> AT 586.
<OPTIONS> Pentium PRO.
</SELECT>
</FORM>
SELECT MULTIPLE.
Тэг SELECT MULTIPLE нагадує тэг SELECT SINGLE, але користувач може водночас вибрати більш як один елемент списку. Атрибут SIZE визначає величезну кількість водночас видимих на екрані елементів, атрибут MULTIPLE — якомога більше одночасно вибраних елементів. Пример:
<FORM>
<SELECT SINGLE NAME=group SIZE=4 MULTIPLE=2>
<OPTION> AT 386.
<OPTION> AT 486.
<OPTION> AT 586.
<OPTIONS> Pentium PRO.
</SELECT>
</FORM>
Если вибрано одночасно кілька значень, то серверу передаютс відповідне обраному кількість параметрів NAME=VALUE з однаковими значеннями NAME, але різними VALUE.
Отправление файлів з допомогою форм
Формы можна використовуватиме відправки як невеликих з повідомлень ввиде параметрів, в тому числі до відправки файлов.
Внимание! Оскільки дана можливість вимагає підтримки отримання файлів WEB — сервером, то, відповідно, необхідно, щоб сервер підтримував отримання файлов!
Например:
<FORM ENCTYPE= «multipart/form-data «ACTION= «url «METHOD=POST>
Отправить даний файл: <INPUT NAME= «userfile «TYPE= «file «>
<INPUT TYPE= «submit «VALUE= «Відправити файл «>
</FORM>
<FORM action= «internet encType= «multipart/form-data «method= «post «>
Отправить даний файл: <INPUT name= «userfile «type= «file «>
<INPUT type= «submit «value= «Відправити файл «>
</FORM>
Список литературы
Для підготовки даної роботи було використані матеріали із сайту internet.