Лабораторная работа №5 Программирование под CryptoAPI

advertisement
Лабораторная работа №5
Программирование под CryptoAPI
ТЕОРЕТИЧЕСКИЕ ОСНОВЫ
Введение
3
Алгоритмы электронной цифровой подписи
Алгоритм электронной цифровой подписи RSA
Алгоритм электронной цифровой подписи DSA
Хэш-функции
5
6
8
9
ПРОГРАММИРОВАНИЕ ЭЛЕКТРОННОЙ ЦИФРОВОЙ ПОДПИСИ, ИСПОЛЬЗУЯ CRYPTOAPI 1.0
Функции CryptoAPI 1.0
Функции обеспечения криптопровайдера
Функции управления и обмена ключевой информацией
Функции шифрования данных
Функции хэширования и электронной цифровой подписи
9
10
10
11
11
ОПИСАНИЕ ФУНКЦИЙ CRYPTOAPI 1.0 НЕОБХОДИМЫХ ДЛЯ ВЫПОЛНЕНИЯ ЛАБОРАТОРНОЙ
РАБОТЫ
Описание функций CryptiAPI
• CryptAcquireContext
• CryptReleaseContext
• CryptGetUserKey
• CryptGenKey
• CryptExportKey
• CryptlmportKey
• CryptCreateHash
• CryptHashData
• CryptSignHash
• CryptDestroyHash
• CryptVerifySignature
11
p
Введение
При обмене электронными документами по сети связи существенно снижаются затраты на обработку
и хранение документов, убыстряется их поиск. Но при этом возникает проблемы аутентификации
автора документа и самого документа, т. е. установления подлинности автора и отсутствия
изменений в полученном документе. В обычной (бумажной) информатике эти проблемы решаются за
счет того, что информация в документе и рукописная подпись автора жестко связаны с физическим
носителем (бумагой). В электронных документах на машинных носителях такой связи нет.
Целью аутентификации электронных документов является их защита от возможных видов
злоумышленных действий, к которым относятся:
•
•
•
•
•
активный перехват - нарушитель, подключившийся к сети, перехватывает документы
(файлы) и изменяет их;
маскарад - абонент С посылает документ абоненту В от имени абонента А;
ренегатство - абонент А заявляет, что не посылал сообщения абоненту В, хотя на самом
деле послал;
подмена - абонент В изменяет или формирует новый документ и заявляет, что получил его
от абонента А;
повтор - абонент С повторяет ранее переданный документ, который абонент А посылал
абоненту В.
•
Эти виды злоумышленных действий могут нанести существенный ущерб банковским и
коммерческим структурам, государственным предприятиям и организациям, частным лицам,
применяющим в своей деятельности компьютерные информационные технологии.
При обработке документов в электронной форме совершенно непригодны традиционные
способы установления подлинности по рукописной подписи и оттиску печати на бумажном документе.
Принципиально новым решением является электронная цифровая подпись (ЭЦП). Электронная цифровая
подпись используется для аутентификации текстов, передаваемых по телекоммуникационным каналам.
Функционально она аналогична обычной рукописной подписи и обладает ее основными достоинствами:
•
•
•
удостоверяет, что подписанный текст исходит от лица, поставившего подпись;
не дает самому этому лицу возможности отказаться от обязательств, связанных с
подписанным текстом;
гарантирует целостность подписанного текста.
Цифровая подпись представляет собой относительно небольшое количество дополнительной
цифровой информации, передаваемой вместе с подписываемым текстом. Система ЭЦП включает две
процедуры: 1) процедуру постановки подписи; 2) процедуру проверки подписи. В процедуре постановки
подписи используется секретный ключ отправителя сообщения, в процедуре проверки подписи - открытый
ключ отправителя.
При формировании ЭЦП отправитель прежде всего вычисляет хэш-функцию h(M)
подписываемого текста М. Вычисленное значение кэш-функции h(M) представляет собой один короткий блок
информации т, характеризующий весь текст М в целом. Затем число m шифруется секретным ключом
отправителя. Получаемая при этом пара числе представляет собой ЭЦП для данного текста М.
При проверке ЭЦП получатель сообщения снова вычисляет хэш-функции m=h(M) принятого
по каналу текста М, после чего при помощи открытого клоча отправителя проверяет, соответствует
ли полученная подпись вычисленному значению m хэш-функции.
Принципиальным моментом в системе ЭЦП является невозможность подделки ЭЦП
пользователя без знания его секретного ключа подписывания.
В качестве подписываемого документа может быть использован любой файл. Подписанный
файл создается из неподписанного путем добавления в него одной или более электронных
подписей.
Желательно, чтобы каждый подписанный файл содержал следующую информацию:
•
•
•
•
•
дату подписи;
срок окончания действия ключа данной подписи;
информацию о лице, подписавшем файл (Ф.И.О., должность, краткое наименование
фирмы);
идентификатор подписавшего (имя открытого ключа);
собственно цифровую подпись.
Электронная подпись позволяет проверять целостность данных, но не обеспечивает их
конфиденциальность. Электронная подпись добавляется к сообщению и может шифроваться вместе
с ним при необходимости сохранения данных в тайне. Добавление временных меток к электронной
подписи позволяет обеспечить ограниченную форму контроля участников взаимодействия.
Предположим, что нам нужно передать какой-либо текст, не обязательно секретный, но
важно то, чтобы в него при передаче по незащищенному каналу не были внесены изменения. К
таким текстам обычно относятся различные распоряжения, справки, и тому подобная документация,
не представляющая секрета. Вычислим от нашего текста какую-либо хэш-функцию - это будет число,
которое более или менее уникально характеризует данный текст.
В принципе, можно найти другой текст, который дает то же самое значение хэш-функции, но
изменить в нашем тексте десять-двадцать байт так, чтобы текст остался полностью осмысленным, да
еще и изменился в выгодную нам сторону (например, уменьшил сумму к оплате в два раза) чрезвычайно сложно. Именно для устранения этой возможности хэш-функции создают такими же
сложными как и криптоалгоритмы - если текст с таким же значением хэш-функции можно будет
подобрать только методом полного перебора, а множество значений будет составлять как и для
блочных шифров 232-2128 возможных вариантов, то для поиска подобного текста злоумышленнику
«потребуются» миллионы лет.
Таким образом, если мы сможем передать получателю защищенным от изменения методом
хэш-сумму от пересылаемого текста, то у него всегда будет возможность самостоятельно вычислить
хэш-функцию от текста уже на приемной стороне и сверить ее с присланной нами. Если хотя бы
один бит в вычисленной им самостоятельно контрольной сумме текста не совпадает с
соответствующим битом в полученном от нас хэш-значении, значит, текст по ходу пересылки
подвергался несанкционированному изменению.
Можно сказать, что манипуляции с хэш-суммой текста представляют из себя «асимметричное
шифрование наоборот»: при отправке используется закрытый ключ отправителя, а для проверки
сообщения - открытый ключ отправителя. Подобная технология получила название «электронная
подпись». Информацией, которая уникально идентифицирует отправителя (его виртуальной
подписью), является закрытый ключ d. Ни один человек, не владеющий этой информацией, не может
создать такую пару (текст, Si), что описанный выше алгоритм проверки дал бы положительный
результат.
Подобный обмен местами открытого и закрытого ключей для создания из процедуры
асимметричного шифрования алгоритма электронной подписи возможен только в тех системах, где
выполняется свойство коммутативности ключей. Для других асимметричных систем алгоритм
электронной подписи либо значительно отличается от базового, либо вообще не реализуем.
Алгоритмы электронной цифровой подписи
Технология применения системы ЭЦП предполагает наличие Сети абонентов, посылающих
друг другу подписанные электронные документы. Для каждого абонента генерируется пара ключей:
секретный и открытый. Секретный ключ хранится абонентом в тайне и используется им для
формирования ЭЦП. Открытый ключ известен всем другим пользователям и предназначен для
проверки ЭЦП получателем подписанного электронного документа. Иначе говоря, открытый ключ
является необходимым инструментом, позволяющим проверить подлинность электронного документа
и автора подписи. Открытый ключ не позволяет вычислить секретный ключ.
Для генерации пары ключей (секретного и открытого) в алгоритмах ЭЦП, как и в
асимметричных системах шифрования, используются разные математические схемы, основанные на
применении однонаправленных функций. Эти схемы разделяются две группы. В основе такого
разделения лежат известные сложные вычислительные задачи:
•
•
задача факторизации (разложения на множители) больших целых чисел;
задача дискретного логарифмирования
Таблица. Основные алгоритмы ЭЦП.
Тип
DSA (Digital
Signature
Authorization)
RSA
MAC (код
аутентификации
сообщения)
DTS (служба
электронных
временных меток)
Комментарии
Алгоритм с использованием открытого ключа для создания электронной
подписи, но не для шифрования. Секретное создание хэш-значения и
публичная проверка ее - только один человек может создать хэш-значение
сообщения, но любой может проверить ее корректность. Основан на
вычислительной сложности взятия логарифмов в конечных полях.
Запатентованная RSA электронная подпись, которая позволяет проверить
целостность сообщения и личность лица, создавшего электронную подпись.
Отправитель создает хэш-функцию сообщения, а затем шифрует ее с
использованием своего секретного ключа. Получатель использует открытый
ключ отправителя для расшифровки хэша, сам рассчитывает хэш для
сообщения, и сравнивает эти два хэша.
Электронная подпись, использующая схемы хэширования, аналогичные MD
или SHA, но хэш-значение вычисляется с использованием как данных
сообщения, так и секретного ключа.
Выдает пользователям временные метки, связанные с данными документа,
криптографически стойким образом.
Алгоритм цифровой подписи RSA
Первой и наиболее известной во всем мире конкретной системой ЭЦП стала система
RSA, математическая схема которой была разработана в 1977 г. В Массачусетском
технологическом институте США.
Сначала необходимо вычислить пару ключей (секретный ключ и открытый ключ). Для этого
отправитель (автор) электронных документов вычисляет два больших простых числа Р и Q, затем
находит их произведение N=P*Q и значение функции ц(N)=(P-1)(Q-1).
Далее отправитель вычисляет число Е из условий: Е<(ц(N), НОД (Е, ц(N))=1 и число D из
условий: D<N, E*D=(mod ц(N))
Пара чисел (E,N) является открытым ключом. Эту пару чисел автор предает партнерам по
переписке для проверки его цифровых подписей. Число D сохраняется автором как секретный ключ
для подписывания.
Допустим, что отправитель хочет подписать сообщение М перед его отправкой. Сначала
сообщение М (блок информации, файл, таблица) сжимают с помощью хэш-функции h(-) в целое
число m:
m = h(М)
Затем вычисляют цифровую подпись S под электронным документом М, используя хэшзначение m и секретный ключ D:
S=mD(mod N).
Пара (M,S) передается партнеру-получателю как электронный документ М, подписанный
цифровой подписью S, причем подпись S сформирована обладателем секретного ключа D.
После приема пары (M,S) получатель вычисляет хэш-значение сообщения М двумя разными
способами. Прежде всего, он восстанавливает хэш-значение т, применяя криптографическое
преобразование подписи S с использованием открытого ключа Е:
m'=SE(mod N)
Кроме того, он находит результат хэширования принятого сообщения М с помощью такой же
хэш-функции h(-):
m=h(M)
Если соблюдается равенство вычислительных значений, т. е. SE(mod N) = h(M), то получатель
признает пару (M,S) подлинной. Доказано, что только обладатель секретного ключа D может
сформировать цифровую подпись S по документу М, а определить секретное число D по открытому
числу Е не легче, чем разложить модуль на множители.
Кроме того, можно строго математически доказать, что результат проверки цифровой
подписи S будет положительным только в том случае, если при вычислении S был использован
секретный ключ D, соответствующий открытому ключу Е. Поэтому открытый ключ Е иногда
называют «идентификатором» подписавшего. Недостатки алгоритма цифровой подписи RSA.
1.
2.
3.
При вычислении модуля N, ключей Е и D для системы цифровой подписи RSA
необходимо проверять большое количество дополнительных условий, что сделать
практически трудно. Невыполнение любого из этих условий делает возможным
фальсификацию цифровой подписи со стороны того, кто обнаружит такое
невыполнение. При подписании важных документов нельзя допускать такую
возможность даже теоретически.
Для обеспечения криптостойкости цифровой подписи RSA по отношению к
попыткам фальсификации на уровне, например, национального стандарта США на
шифрование информации (алгоритм DES), т. е. 1018, необходимо использовать при
вычислениях N, D и Е целые числа не менее 2512 (или около 10154) каждое, что
требует больших вычислительных затрат, превышающих на 20...30%
вычислительные затраты других алгоритмов цифровой подписи при сохранении
того же уровня криптостойкости.
Цифровая подпись RSA уязвима к так называемой мультипликативной атаке. Иначе
говоря, алгоритм цифровой подписи RSA позволяет злоумышленнику без знания
секретного ключа D сформировать подписи под теми документами, у которых
результат хэширования можно вычислить как произведение результатов
хэширования уже подписанных документов.
Пример.
Допустим, что злоумышленник может сконструировать три сообщения M1,M2 и М3, у которых хэшзначения
m1=h(M1), m2=h(M2), m3=h(M3), причем m3=m1*m2 (mod N) Допустим также,
что для двух сообщений M1 и М2 получены законные подписи
S1 = m1d (mod N) и S2=m2d (mod N)
Тогда злоумышленник может легко вычислить подпись S3 для документа М3, даже не зная
секретного ключа D:
S3=S1*S2(mod N)
Действительно:
S1*S2 (mod N) = m1D * m2D (mod N) = (m1m2)D(mod N) = m3D(mod N) = S3
Алгоритм цифровой подписи DSA
Алгоритм цифровой подписи DSA (Digital Signature Algorithm) предложен в 1991 г. в НИСТ
США для использования в стандарте цифровой подписи DSS (Digital Signature Standart). Алгоритм
DSA является развитием алгоритмов цифровой подписи Эль Гамаля и К. Шнорра.
Отправитель и получатель электронного документа используют при вычислении большие
целые числа: G и Р - простые числа, L бит каждое (512 $ L $ 1024); q - простое число длиной 160
бит (делитель числа (Р-1)). Числа G, P, q являются открытыми и могут быть общими для всех
пользователей сети.
Отправитель выбирает случайное целое число X, l<X<q. Число X является секретным
ключом отправителя для формирования электронной цифровой подписи.
Затем отправитель вычисляет значении
Y=GX mod P
Число Y является открытым ключом для проверки подписи отправителя. Число Y передается
всем получателям документов. Этот алгоритм также предусматривает использование односторонней
функции хэширования h(-). В стандарте DSS определен алгоритм безопасного хэширования SHA
(Secure Hash algorithm).
Для того, что подписать документ М, отправитель хэширует его в целое хэш-значение m:
m=h(M), 1<m<q,
затем генерирует случайное целое число К, 1<K<q, и вычисляет число r:
r=(G mod P) mod q.
Затем отправитель вычисляет с помощью секретного ключа X целое число s:
s = ((m + r * Х)/К) mod q
Пара чисел r и s образует цифровую подпись S=(r,s) под документом М.
Таким образом, подписанное сообщение представляет собой тройку чисел [M,r,s].
Получатель подписанного сообщения [M,r,s] проверяет выполнение условий 0<r<q, 0<s<q и
отвергает подпись, если хотя бы одно из этих условий не выполнено.
Затем получатель вычисляет значение: m = (1/S)mod q, хэш-значение m=h(M) и числа u1 = (m*w)
mod q, u2=(r*w) mod q.
Далее получатель с помощью открытого ключа Y вычисляет значение v=((Gu1*Yu2) mod P)
mod q и проверяет выполнение условия v=r.
Если условие v=r выполняется, тогда подпись S=(r,s) под документом М признается
получателем подлинной.
Можно строго математически доказать, что последнее равенство будет выполняться тогда, и
только тогда, когда подпись S(r,s) под документом М получена с помощью именно того секретного
ключа X, из которого был получен открытый ключ Y. Таким образом, можно надежно удостовериться,
что отправитель сообщения владеет именно данным секретным ключом X (не раскрывая при этом
значения ключа X) и что отправитель подписал именно данный документ М.
По сравнению с алгоритмом цифровой подписи Эль Гамаля алгоритм DSA имеет
следующие основные преимущества:
1.
2.
3.
При любом допустимом уровне стойкости, т. е. при любой паре чисел G и Р (от 512
до 1024 бит), числа q, X, r, s имеют длину по 160 бит, сокращая длину подписи до
320 бит.
Большинство операций с числами К, r, s, X при вычислении подписи производится
по модулю числа q длиной 160 бит, что сокращает время вычисления подписи.
При проверке подписи большинство операций с числами u1, u2, v, w также
производится по модулю числа q длиной 160 бит, что сокращает объем памяти и
время вычисления.
Недостатком алгоритма DSA является то, что при подписывании и при проверке подписи приходится
выполнять сложные операции деления по модулю q:
s = ((m + r * Х)/К) mod q
w=l (mod q), что не позволяет получать максимальное быстродействие.
Следует отметить, что реальное исполнение алгоритма DSA может быть ускорено с помощью
выполнения предварительных вычислений. Заметим, что значение r не зависит от сообщения М и его
хэш-значения т. Можно заранее создать строку случайных значений К и затем для каждого из этих
значений вычислить значения r. Можно также заранее вычислить обратные значения К-1 для каждого
из значений К. Затем, при поступлении сообщения М, можно вычислить значение s для данных
значений r и К-1. Эти предварительные вычисления значительно ускоряют работу алгоритма DSA.
Хэш - функции
Хэш-функции являются одним из важных элементов криптосистем на основе ключей. Их
относительно легко вычислить, но почти невозможно расшифровать. Хэш-функция имеет исходные
данные переменной длины и возвращает строку фиксированного размера (иногда называемую
дайджестом сообщения - MD), обычно 128 бит. Хэш-функции используются для обнаружения
модификации сообщения (то есть для электронной подписи).
Хэш-функция предназначена для сжатия подписываемого документа М до нескольких
десятков или сотен бит. Хэш-функция п(-) принимает в качестве аргумента сообщение (документ) М
произвольной длины и возвращает хэш-значение h(M)=H фиксированной длины. Обычно
хэшированная информация является сжатым довичным представлением основного сообщения
произвольной длины. Следует отметить, что значение хэш-функции h(M) сложным образом зависит от
документа М и не позволяет восстановить сам документ М.
Хэш-функция должна удовлетворять целому ряду условий:
- хэш-функция должна быть чувствительна к всевозможным изменениям в тексте М, таким
как вставки, выбросы, перестановки и т. п.;
- хэш-функция должна обладать свойством необратимости, то есть задача подбора
документа М', который обладал бы требуемым значением хэш-функции, должна быть вычислительно
неразрешима;
- вероятность того, что значения хэш-функции двух различных документов (вне зависимости
от их длин) совпадут, должна быть ничтожно мала.
Большинство хэш-функций строится на основе однонаправленной функции f(-), которая
образует выходное значение длиной п при задании двух входных значений длиной п. Этими
входами являются блок исходного текста Mi и хэш-значение Hi-1 предыдущего блока текста:
Hi=f(Mi,Hi-l).
Хэш-значение, вычисляемое при вводе последнего блока текста, становится хэш-значением
всего сообщения М.
В результате однонаправленная хэш-функция всегда формирует выход фиксированной
длины п (независимо от длины входного текста).
Таблица. Основные алгоритмы хэширования.
Тип
MD2
MD4
MD5
SHA
(Secure
Hash
Algorithm)
Описание
Самая медленная, оптимизирована для 8-битовых машин
Самая быстрая, оптимизирована для 32-битных мащин
Наиболее распространенная из семейства MD-функций. Похожа на MD4,
но средства повышения безопасности делают ее на 33% медленнее, чем
MD4 Обеспечивает целостность данных Считается безопасной
Создает 160-битное значение хэш-функций из исходных данных переменного
размера. Предложена NIST и принята правительством США как стандарт
Предназначена для использования в стандарте DSS
Программирование цифровых подписей в CryptoApi 1.0.
CryptoApi 1.0 - это интерфейс для Win 32 программ обеспечивающий доступ данных программ к
алгоритмам шифрования. При этом приложения не обязательно должны знать об алгоритме
реализации этого метода и тем самым облегчается реализация самих программ. При этом за написание
самого алгоритма отвечает сама фирма разработчик алгоритма или фирма Micrsoft. Помимо этого
может быть обеспечен доступ к аппаратным средствам шифрования. Написание программ становится
простым и удобным. Чтобы сменить алгоритм шифрования достаточно поменять определенные
параметры вызова функции, что гораздо проще, чем писать заново программу шифрования. Тем
более сам алгоритм шифрования может публично не публиковаться, и следовательно собственная
реализация данных алгоритмов становится очень сложной.
Реализация алгоритмов шифрования обеспечивается с помощью специальных служб,
называемых криптопровайдерами (Cryptographic Service Provider (CSP)). Криптопровайдеры
представляют из себя библиотеки (обычно DLL), имеющие стандартные для всех криптопровайдеров
внешние функции, обеспечивающие реализацию всех необходимых функций шифрования, и
сопутствующих им функций.
Функции CryptoAPI
Среди всего множества функций можно выделить основные группы:
Функции обеспечения криптопровайдера. Включают создание и управление
криптопровайдерами, включая настройку их операций.
Функции управления и передачи ключевой информации. Обеспечивают создание,
конфигурирование и уничтожение криптографических ключей, а также обмен ключами с другими
пользователями.
Функции шифрования данных. Обеспечивают операции шифрования и расшифровки.
Функции хэширования и электронной цифровой подписи. Обеспечивают вычисление
значения функции хэширования от сообщения, а также создание и проверку цифровой подписи
сообщения.
Функции обеспечения криптопровайдера
Данные функции используются приложениями для подключения криптопровайдеров и работы
с дескрипторами криптопровайдеров. Следующая таблица кратко описывает каждую функцию.
Функция
CryptAcquireContext
СгуptContextAddRef
CryptEnumProviders
CryptEnumProviderTypes
CryptGetDefaultProvider
CryptGetProvParam
CryptReleaseContext
CryptSetProvider
CryptSetProviderEx
CryptSetProvParam
Краткое описание
Используется для получения дескриптора ключевого контейнера
внутри соответствующего криптопровайдера
Инкрементирует счетчик ссылок на HCRYPTPROV дескриптор
Перечисляет криптопровайдеры, установленные на компьютере
Перечисляет типы криптопровайдеров, установленных на компьютере
Определяет криптопровайдер, используемый по умолчанию, для
текущего пользователя или для компьютера
Получает параметры криптопровайдера
Освобождает дескриптор криптопровайдера, полученный через вызов
функции CryptAcquierContext
Устанавливает криптопровайдер, используемый по умолчанию, для
соответствующего типа криптопровайдера
Устанавливает параметры криптопровайдера
Функции управления и обмена ключевой информацией
Данные функции используются приложениями для создания, конфигурирования и
уничтожения криптографических ключей, а также для передачи ключей другим пользователям.
Следующая таблица кратко описывает каждую функцию.
Функция
CryptDeriveKey
CryptDestroyKey
CryptDuplicateKey
CryptExportKey
CryptGenKey
CryptGenRandom
CryptGetKeyParam
CryptGetUserKey
CryptlmportKey
CryptSetKeyParam
Краткое описание
Создает ключ, получаемый из пароля
Уничтожает ключ
Делает точную копию ключа и его характеристик
Экспортирует ключ из криптопровайдера в ключевой блоб в памяти
приложения
Создает случайный ключ
Генерирует случайный блок данных
Получает параметры ключа
Получает дескриптор обмена или электронной подписи
Импортирует ключ из ключевого блоба в криптопровайдер
Устанавливает параметры ключа
Функции шифрования данных
Данные функции реализуют операции шифрования и расшифровки. Следующая таблица
кратко описывает каждую функцию.
Функция
CryptDecrypt
CryptEncrypt
Краткое описание
Расшифровывает фрагмент шифртекста, используя указанный ключ
шифрования
Шифрует раздел открытого текста, используя указанный ключ
шифрования
Функции хэширования и электронной цифровой подписи
Данные функции используются приложениями для вычисления значения функции
хэширования от сообщения, а также создание и проверку цифровой подписи сообщения.
Следующая таблица кратко описывает каждую функцию.
Функция
Краткое описание
CryptCreateHash
CryptDestroyHash
CryptDuplicateHash
CryptGetHashParam
CryptHashData
CryptHashSessionKey
CryptSerHashParam
CryptSiqnHash
CryptVerifySignature
Создает «пустой»объект хэша
Уничтожает объект хэша
Дублирует объект хэша
Получает параметры объекта хэша
Хэширует блок данных, добавляя хэш к указанному объекту хэша
Хэширует сессионный ключ и добавляет значение хэша к указанному
объекту хэша
Устанавливает параметры объекта хэша
Подписывает указанный объект хэша
Проверяет цифровую подпись
Описание функций CryptiAPI, необходимых для выполнения лабораторной работы,.
Все функции работы с CryptoAPI имеют прототир функции в модуле Wincrypt.h, библиотека
advapi32.dll.
Для своей работы требуют WindowsNT/2000 (Windows NT 4.0 SP4 или старше) или Windows
95/98 (Windows 95 OSR2 или старше, или Windows 95 и Internet Explorer 3.02 или старше).
Функция CryptAcquireContext используется для создания дескриптора определенного
ключевого контейнера в рамках определенного криптопровайдера. Возвращаемый дескриптор
может использоваться при осуществлении вызовов данного криптопровайдера.
Функция выполняет две операции. Сначала она пытается найти криптопровайдер с
характеристиками, описанными в параметрах dwProvType и pszProvider. Если криптопровайдер
найден, то функция пытается найти ключевой контейнер в рамках криптопровайдера в
соответствии с именем, указанным pszContainer параметром.
Эта функция также может использоваться для создания и уничтожения ключевых
контейнеров в зависимости от значения параметра dwFlags.
BOOL WINAPI CryptAcquireContext (
HCRYPYPROV *phProv,
LPCSTR pszContainer,
//in
LPCSTR pszProvider,
//in
DWORD dwProvType,
//in
DWORD dwFlags
);
//out
//in
Параметры
phProv
Указатель на дескриптор криптопровайдера (CSP).
pszContainer
Имя ключевого контейнера. Это указатель на строку, заканчивающуюся нулем,
идентифицирующую
ключевой
контейнер.
Если
в
dwFlags
установлен
флаг
CRYPT_VERIFYCONTEXT, то pszContainer Должен быть равен NULL.
Если данные параметр - NULL, то будет использовать имя по умолчанию.
Криптопровайдеры
Microsoft в этом случае используют имя пользователя, вошедшего в систему, в качестве имени
контейнера. Приложения могут получить имя контейнера, с которым они работают, прочитав
значение PP_CONTAINER. Через вызов функции CryptGetProvParam
pszProvider
Указатель на строку, заканчивающуюся нулем, содержащую имя криптопровайдера. Если
этот параметр равен NULL, то используется криптопровайдер по умолчанию. В настоящее время
определены следующие типы криптопровайдеров:
PROV_RSA_FULL PROV_RSA_SIG PROVJDSS PROV_DSS_DH
PROV_DH_SCHANNEL PROV_FORTEZZA PROV_MS_EXCHANGE
PROV_RSA_SCHANNEL PROV_SSL
dwFlags
Параметр имеет нулевое или одно из следующих значений:
Значение dwFlags
Описание
CRYPTVERIFYCONTEXT
Е с л и ф ла г ус т а но вл е н, т о п р ил о ж е ние н е им е е т д о с т упа к
секретным ключам ключевого контейнера. Флаг предназначен для
использования с приложениями, целью которых является проверка
цифровой подписи. Операции, обычно необходимые в этом случае,
получение дескрипторов открытых ключей , хэширование
ипроверка подписи.
CRYPTNEWKEYSET
Если флаг установлен, то будет создан новый ключевой контейнер с
именем, соответствующим pszContainer. Если pszContainer - NULL, то будет
создан ключевой контейнер с именем, заданным по умолчанию.
CRYPTMACHINEKEYSET
По умолчанию ключи сохраняются в разделе HKEYCURRENTUSER
системного реестра. Флаг CRYPTMACHNEKEYSET может использоваться при
вызове CryptAcquireContext с флагом CRYPTNEWKEYSET или CRYPT
JDELETEKEYSET, в этом случае ключи будут сохранены в разделе
HKEYLOCALMACHINE системного реестра.
CRYPTDELETEKEYSET
Если флаг установлен, то ключевой контейнер, соответствующий
pszContainer, удаляется. Если pszContainer - NULL, то удаляется ключевой
контейнер с именем , заданным по умолчанию. Все ключевые пары
в
ключевом
контейнере
также
уничтожаются.
Когда
флаг
CRYPTDELETEKEYSET установлен, значение, возвращенное в phProv, не
определено и функция CryptReleaseContext не должна вызываться
повторно.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если
возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может быть получен через
функцию GetLastError.
Функция
CryptReleaseContext
используется
для
освобождения
дескриптора
криптопровайдера, созданного CryptAcquireContext. Это действие должно быть выполнено, когда
приложение, использующее данный ключевой контейнер криптопровайдера, завершается. После
вызова этой функции дескриптор ключевого контейнера, указанный hProv параметром, больше не
существует.
BOOL CryptReleaseContext (
HCRYPTPROV hProv, //in
DWORD dwFlags
//in
);
Параметры hProv
Д ескри пт ор кри пт опров айде ра ,
CryptAcqireContext
по л уче нный
при ло же нием
чере з
вы з ов
ф унк ции
dwFlags
Значение флагов. Это параметр зарезервирован для будущего использования и должен быть
нулевым.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если
возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию
GetLastError.
Функция CryptGetUserKey возвращает дескриптор одной из постоянных ключевых пар.
BOOL CryptGetUserKey (
HCRYPTPROV hProv,
DWORD dwKeySpec,
//in
//in
HCRYPTKEY *phllserKey
//out
Параметры
hProv Дескриптор криптопровайдера. Указанный дискриптор получается через запрос к функции
CryptAcquireContext.
DwKeySpec Спецификация возвращаемого ключа. Параметр может принимать значения AT
SIGNATURE или AT KEYEXCHANGE.
phUserKey Адрес, по которому функция копирует дескриптор ключа.
Возвращаемое значение
При успешном завершении функции возвращает TRUE, в противном случае возвращается FALSE. Если
возвращается FALSE, соответствующий код ошибки (см. таблицу) мжет быть получен через функцию
GetLastError.
Функция CryptGetUserKey производит случайные криптографические ключи. Дескриптор
вырабатываемого ключа возвращается через параметр phKey. Этот дескриптор может затем
использоваться по необходимости с любой из функций CryptoAPI, требующих дескриптор ключа на
входе.
При вызове этой функции приложение должно определить алгоритм криптографических
преобразований. Провайдер сохраняет тип алгоритма совместно с ключом, поэтому приложению нет
необходимости обращаться к этому параметру позже при выполнении криптографических функций.
BOOL CryptGetUserKey (
HCRYPTPROV hProv,
DWORD dwKeySpec,
HCRYPTKEY *phUserKey
//in //in
//out
); Параметры
hProv
Дескриптор криптопровайдера. Указанный дескриптор получается через запрос к функции
CryptAcquireContext.
Algid
Идентификатор алгоритма шифрования или ЭЦП, для которого должен быть произведен ключ.
Значение этого параметра зависит от используемого криптопровайдера. Для Microsoft® Base
Cryptographic Provider определены следующие значения индентификаторов алгоритмов:
•
CALG_RC2 - алгоритм блочного шифрования RC2.
•
CALG_RC4 - алгоритм поточного шифрования RC4.
Для криптопровайдеров, поддерживающих ключевой обмен по Диффи-Хеллману, определены
следующие значения идентификаторов алгоритмов:
•
CALG_DH_EPHERM - определяет «Ephemeral» ключ Диффи-Хелллмана.
•
CALG_DH_SF - определяет «Store and Forvard» ключ Диффи-Хелллмана.
Если должна быть произведена ключевая пара (открытый /секретный ключи), эта величина
определяет тип ключевой пары:
•
AT_K.EYEXCHANGE - определяет ключевую пару обмена.
.
•
AT_SIGNATURE - определяет ключевую пару подписи.
dwFlags
Флаги определяют признаки производимого ключа. Размеры ключей подписи и ключей обмена могут
быть установлены при выработке ключа. Размер ключа устанавливается в старших 16 битах параметра dwFlags,
эти 16 бит представляют длину модуля в байтах. В настоящее время определены флаги:
Значение dwFlags
CRY PTEXPORTABLE
Описание
Если этот флаг установлен, то ключ сессии может быть
передан из криптопровайдера в ключевой блоб через
функцию CryptExportKey. Поскольку ключи, как правило,
должны быть экспортируемыми, это флаг не установлен, то
ключ сессии не будет экспортируемым. Это означает, что
ключ будет доступен только в пределах текущей сессии и
только приложению, которое создало этот ключ. Действие
этого флага не распространяется на ключевые пары
(открытый/секретный ключи) ___________________________
CRYPTPREGEN
Этот флаг определяет инициализацию генерации пар Диффи-Хеллман
DSS/ Флаг используется только с криптопровайдерами,
поддерживающими
Диффи-Хеллмана/DSS алгоритмы.
и
phKey
Адрес, по которому функция копирует дескриптор произведённого ключа.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE.
Если возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может быть
получен через функцию GetLastError.
Функция CryptExportKey используется для экспорта криптографических ключей из ключевого
контейнера криптопровайдера, сохраняя их в защищенном виде. На вход функции предается
дескриптор экспортируемого ключа, функция возвращает ключевой блоб. Ключевой блоб может
передаваться по открытым каналам связи или может быть записан на незащищённый носитель.
Использование ключа из ключевого блоба возможно только после того, как получатель ключа
импортирует его в свой криптопровайдер, используя функцию CryptlmportKey.
BOOL CryptGetUserKey (
HCRYPTPROV hKey,
HCRYPTPROV hExpKey,
DWORD dwBlodType.
DWORD dwFlags
BYTE *pbData,
DWORD dwDataLen.
.
// in
//in
//in
//in
//out
// in, out
);
Параметры
hKey
Дескриптор экспортируемого ключа.
hExpKey
Дескриптор ключа, на котором осуществляется криптографическая защита экспортируемого ключа.
Для обеспечения связи в сети это должен быть ключ с пользователем, кому корреспонденция
предназначена. Зашифрованные данные ключа помещаются в ключевой блоб, предназначенный для
внешнего хранения и передачи по каналам связи. Обычно hExpKey является открытым ключом экспорта был
сессионный ключ. Если ключевой блоб не должен быть зашифрован (например, тип ключевого блоба PUBLICKEYBLOB), этот параметр не используется и должен быть нулевой.
dwBlobType
Ти п к л юче во го бло ба , пре д на з нач е нно го д ля экспо рт а к лю ча . В нас тояще е в ремя о пред еле ны
следующие типы ключевых блобов:
•
SIMPLEBLOB - используется для экспорта сессионных ключей;
•
PUBLICKEYBLOB - используется для экспорта открытых ключей ключевых пар подписи или
обмена ключами;
•
PUBLICKEYBLOBEX - используется для обмена значениями Р, G, и (G^) mod P в обмене
ключами по алгоритму Диффи-Хеллмана;
•
PRIVATEKEYBLOB - используется для транспортировки пары открытый/секретный ключи.
dwFlags
З н а че ние фла го в . Э то т па раме тр з аре зер виро ва н для б уд ущ ег о ис пол ьз ов а ния и д ол же н бы ть
нулевым.
pbData
Буфер данных, куда функция копирует ключевой блоб. Параметр может содержать значение NULL, в этом
случае необходимый размер буфера возвращается в параметре pdwDataLen.
pdwDataLen
Адрес длинны ключевого блоба. При вызове функции указанный параметр содержит число байтов в
буфере pbData. После её исполнения параметр будет установлен числом байтов данных параметра,
скопированных в буфер pbData.
Если буфер, соответствующий pbData, недостаточно большой, чтобы в него копировать
запрошенные данные, будет возвращен код ошибки ERROR_MORE_DATA через функцию
SetLastError. В этом случае требуемый размер буфера возвращается в pdwDataLen.
Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре
возвращается ноль.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если
возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию
GetLastError.
Функция CryptlmportKey используется для импорта криптографического ключа из ключевого блоба в
контейнер криптопровайдера.
BOOL CryptoImportKey
HCRYPTPROV hProv,
CONST BYTE *pbData,
DWORD dwDataLen.
HCRYPTPROV MmpKey,
DWORD dwFlags.
HCRYPTPROV *phKey,
);
// in
//in
//in
//in
//out
// in, out
Параметры
hProv
Д е ск р ип т о р к р ип т о пр о ва й д ер а . У ка з а нны й д еск р и п т ор п о л уч ае т с я ч ер е з з а пр ос к ф унк ц и и
CryptAcquireContext.
PbData
Буфер, содержащий ключевой блоб. Этот блоб был произведен функцией CryptExportKey данным
криптопровайдером или иным криптопровайдером , исполняющим на удаленном компьютере.
Ключевой блоб состоит из стандартного заголовка и зашифрованного ключа.
.
pdwDataLen
Длинна ключевого блоба (в байтах).
MmpKey
Дескриптор ключа, на котором осуществляется снятие криптографической защиты импортируемого
ключа. Значение этого параметра должно соответствовать значению hExpKey
,
Определенному для функции CryptExportKey при создании ключевого блоба.
Если ключевой блоб зашифрован на ключевой паре обмена ключей (например, SIMPLEBLOB), этот
параметр должен быть дескриптором на ключ обмена.
Если ключевой блоб зашифрован на сессионном ключе, этот параметр должен содержать
дескриптор на этот сессионный ключ.
Если ключей блоб не зашифрован (например, PUBLICKEYBLOB), то этот параметр не используется и
должен быть установлен в ноль.
dwFlags
З н а че ние фла га . Э т от пар аме тр в нас тоя щее врем я исп ол ьз уетс я тол ьк о ко г да к лю че вая п ара
(публичный/секретный ключи) импортируется в криптопровайдер (в форме PRIVATEKEYBLOB). В
этом случае, если импортируемый ключ должен, в конечном счете, заново экспортировался, флаг не
используется, тогда вызовы CryptExportKey с дескриптором ключа будут неудачны.
phKey
Адрес, по которому функция копирует дескриптор импортированного ключа.
Возвращаемое значение
При успешном завершении функции возвращает TRUE, в противном случае возвращается FALSE.
Если возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может быть
получен через функцию GetLastError.
Функция CryptCreateHash используется для инициализации объекта хэширования потока данных. Ф ункция
возвращает дескриптор объекта хэширования . Этот дескриптор используебтся в последующих
вызовах CryptHashData и CryptHashSessionKey для хэширования потока данных и сессионных ключей.
BOOL CryptCreateHash (
HCRYPTPROV hProv,
ALGJD hProv,
HCRYPTKEY hKey,
DWORD dwFlags,
HCRYPTPROV *phHesh,
// in
// in
// in
// in
//out
hProv
Дескриптор ключевого контейнера криптопровайдера. Указанный дескриптор получается через
запрос к функции CryptAcquireContext.
Algid
Идентификатор используемого алгоритма хэширования. Значение параметра зависит от
используемого криптопровайдера.
В криптопровайдерах Microsoft определены следующие алгоритмы хэширования:
CALGHMAC
CALGMAC
CALGMD2
CALGMD5
CALGSHA
CALGSHA1
CALGSSL3SHAMD5
Алгоритм хэширования НМАС
Message Authentication Code
Алгоритм хэширования MD2
Алгоритм хэширования MD5
US DSA Secure Hash Algorithm
Аналогичен CALGSHA
SАутентификация клиента в SSL3
Параметры
hHasn
Дескриптор объекта функции хэширования, значение которой будет подписано.
dwKeySpec
Тип ключевой пары, использующейся при подписи значения функции хэширования. Этот
параметр может принимать значения AT_SIGNATURE или ATKEYEXCHANGE.
sDescription
Последовательность, описывающая подписываемые данные. Текст описания добавляется к
объекту hHash перед тем, как будет произведена подпись. Всякий раз, когда подпись проверяется
(CryptVerifySignature), та же самая последовательность описания должна быть определена. Это
гарантирует, что и подписывающая сторона, и проверяющая знают то, что подписывается или
проверяется. Если последовательность описания не включается в подпись, этот параметр может
быть NULL.
dwFlags
Значения флагов. Этот параметр зарезервирован для будущего использования и должен
быть нулевым.
pbSignature
Адрес буфера, через который возвращается значение подписи.
Если через этот параметр передается NULL, то подпись не вычисляется. В этом случае
требуемый размер буфера (в байтах) возвращается через параметр pdwSigLen.
pdwSigLen
Адрес длины данных подписи. При вызове функции указанный параметр содержит число
байтов в буфере pbSignature. После ее исполнении параметр будет установлен числом байтов
данных, скопированных в буфер pbSignature.
Если буфер, соответствующий pbSignature, недостаточно большой, чтобы в него копировать
подпись, будет возвращен код ошибки ERROR_MORE_DATA, в этом параметре возвращается ноль.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается
FALSE, соответствующий код ошибки может быть получен через функцию GetLastError.
После завершения работы приложения с объектами хэширования все они должны быть
уничтожены функцией CryptDestroyHash
BOOL CryptDestroyHash ( HCRYPTHASH hHash
//in);
Параметры
hHash
Дескриптор разрушаемого объекта функции хэширования.
Функция CryptVerifySignature осуществляет проверку цифровой подписи, соответствующей
объекту функции хэширования.
BOOL CryptVerifySignature (
HCRYPTHASH hHash,
//in
CONST BYTE *pbSignature, //in
DWORD dwSigLen,
//in
HCRYPTKEY hPubKey,
//in
LPCWSTR sDescription,
//in
DWORD dwFlags
//in );
Параметры
hHash
Дескриптор объекта функции хэширования, подпись которого проверяется.
pbSignature
Буфер, содержащий значение проверяемой подписи.
dwSigLen
Длина (в байтах) значения подписи.
hPubKey
Дескриптор открытого ключа, который необходимо использовать для проверки подписи.
sDescription
Последовательность описания подписанных данных. Это должна быть точно та же самая
последовательность, что использовалась в функции CryptSignHash при создании подписи. Если эта
последовательность не соответствует использованной в функции CryptSignHash, проверка подписи
сообщит, что подпись неверна.
Значение флагов. Этот параметр зарезервирован для будущего использования и должен
быть нулевым.
Возвращаемое значение
При успешном завершении функция возвращает TRUE, в противном случае возвращается
FALSE. Если возвращается величина FALSE, соответствующий код ошибки (см. таблицу) может
быть получен через функцию GetLastError.
Комментарии: Функция CryptVerifySignature выполняет следующие внутренние шаги.
1.
Если параметр описания sDescription поддержан, он добавляется к объекту
функции хэширования.
2.
Объект функции хэширования «закрывается», и значение функции хэширования
извлекается.
3.
Значение функции хэширования дополняется, как это требуется алгоритмом
подписи.
4.
Осуществляется проверка подписи, используя открытый ключ hPubKey.
Если подпись, переданная через буфер pbSignature и вычисленное значение подписи не совпадают,
возвращается код ошибки NTE_BAD_SIGNATURE.
После выполнения проверки подписи приложение не может добавлять новые данные к объекту
функции хэширования. Приложение должно разрушить объект функции хэширования через вызов
функции CryptDestroyHash.
Контрольные вопросы
1. Основные виды атак, создающие сомнение в подлинности присылаемых документов
2. Что такое ЭЦП?
3. Сфера применения ЭЦП.
4. Пример применения ЭЦП.
5. Как обеспечивается проверка подлинности сообщения, подписанного ЭЦП?
6. Назовите основные этапы создания ЭЦП.
7. Назовите основные алгоритмы создания электронной подписи.
8. Принципы создания цифровых подписей алгоритмом RSA.
9. Принципы создания цифровых подписей алгоритмом DSA.
10. Что такое хэш-функция?
11. Назовите несколько алгоритмов хэширования и дайте им краткую характеристику.
12. Назначение CryptoAPI?
13. Основные группы функций CryptoAPI и их назначение.
14. Назначение функций получения контекста криптопровайдера.
15. Назначение функций генерации ключей.
16. Какие действия необходимо совершить для получения значения хэш-функции.
17. Основные функции CryptoAPI, необходимые для создания ЭЦП.
18. Основные функции CryptoAPI для проверки подлинности ЭЦП.
19. Назовите порядок вызова функций CryptoAPI, необходимых для создания и
проверки подлинности ЭЦП.
Download