15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту

 

Шифруем в PGP


Автор: Селин Дмитрий


Многие наверное слышали про PGP, но может не все знают, что мелкософт
также включил поддержку криптования в Windows. Из моего желания с этим
разобраться и появилась эта программа.

Дальше я немного процитирую "С/С++ Архив программ" Арта Фридмана и
других т.к. врядли напишу понятнее
Криптографический интерфейс прикладного программирования (CrpytoAPI)
представляет собой набор функций, которые вы можете вызывать из
программы на Visual C++, Visual Basic и других языках
программирования, предоставляет пользователям ваших программ услуги по
шифровке/дешифровке данных.
Программный интерфейс CryptoAPI прзволяет вам ввести в сои программы
криптографические функции. Он использует архитектуру открытых услуг
Windows(WOSA) и предусматривает три набора функций
+Сертификатные функции
+Упрощенные криптографические функции
+Базовые криптографические функции

Модель, который вы будете следовать при реализации этих функций такова

                         ->[сервер]
[приложение]->[CryptoAPI]->[сервер RSA]
                         ->[специальнй сервер]

Упрощенные криптографические функции включают в себя функции высокого
уровня для создания ключей и шифровки/дешифровки информации.
Сертификатные функции предоставляют средства для хранения, извлечения
и проверки сертификатов цифровых подписей.
На нижнем уровне расположены базовые функции. Вы должны избегать
вызовов этих функций, тк это может привести к конфликтам.
Криптографический API поддерживает использование нескольких
криптографических серверов.<что-то типа программ, которые шифруют по
какому-то своему алгоритму, либо выполняют другие специфические
действия>

Некоторые криптографические серверы

   сервер                      шифровка              подпись
   PROV_RSA_FULL               RC2, RC4               RSA
   PROV_RSA_SIG                нет                    RSA
   PROV_SSL                    RSA                    RSA


CryptoAPI использует ключевую базу данных для хранения паролей.<у
каждого пользователя свой база данных, в которых храняться эти
пароли. Изначально там ничего не хранится. В проге есть проверка,
ассоциирована ли пользователю ключевая база данных и есть ли там
ключи, если нет, то база и ключи создаются. Прога также может
удалить базу данных со всеми ключами. Параметр "r" при запуске >
Когда вы разрабатываете приложение, использующее CryptoAPI то
прежде всего должны создать для него необходимые ключевые базы
данных, чтоб гарантировать, что при работе приложения ему будет
доступна ключевая база данных, лучше всего проверять, существует
ли база данных при каждом запуске приложения, и инициализировать ее
в случае, если ее еще не существует.<микрософт рекомендует для каждого приложения
сохдавать свою базу. В проге создаеться база данных для пользователя, если нет, и
используються ключи из нее, но они не повреждаються>

<Несколько слов О CSP>
Типичный CSP(CryptoGraphic Service Provider) состоит из dll и фйла
подписей, который CrytpoAPI использует для проверки целостности и
идентификации пльзователей.<...>Если сформулировать иначе, CSP -
это сервер, способный пвыполнять стандартный набор здач,
инициализируемых вызовом функций из CryptoAPI.
Чтобы обеспечить нужную конфеденциальность все данные, которыми
манипулирует CSP (особенно ключи) возвращаются в вызывающую
программу в форме безликих дескрипторов. <...>Роль программы
ограничивается передачей данных серверу и указанием требуемого
вида шифровки. Сервер всегда может возвратить тип, сообщающий,что
он омжет делать и каким образом.
С CryptoAPI SDK поставляется CSP по умолчанию, называемый Microsoft
RSA Base ProviderЮ реализуемый библиотекой rsabase.dll. Это сервер
типа PROV_RSA_FULL, поддерживающий алгоритм RSA с общим ключом для
обмена ключами и подписей.(ключ имеет длину 512 бит)
Каждый CSP имеет ассоциированную базу данных для ключевых
контейнеров, которая содержит все личные и общие ключи всех
пользователей, имеюющих доступ к машине<если они их создали, эти
ключи>
Каждый контейнер имеет уникальное имя. Без ключевой базы любые
вызовы CryptoAPI приняты не будут. Бызы данных обычно имеет
контейнер по умолчанию, с регистрационными именами всех
пользователей. Однако конкретное приложение может во время установки
создать специальный ключевой контейнер и пары ключей, присвоив им
собственное имя.<насколько я понял, это делате функция

  CryptAquireContext(&hCryptProv,       // Handle to the CSP
                        UserName,           // имя контейнера
                        MS_DEF_PROV,        // имя провайдера
(default)="Microsoft Base Cryptographic Provider v1.0"
                        PROV_RSA_FULL,      // тип провайдера
                        0))                 // флаги

где UserName - это "собственное имя">
Поскольку тип сервера влияет на поведение криптографических функций,
два связанных между собой приложения должны пользоваться одним и тем
же CSP, или по крайней мере серверами с общим подмножеством функций
Программная модель CryptoAPI
Перед тем как вводить криптографию в свои реальные приложения, <нужно
ознакомиться> с такими понятиями как конекст, кллючи сеанса, ключи
ознакомиться> обмена и ключи подписей.
Контекст представляет собой установленный сеанс взаимодействия между
CryptoAPI и приложением клиентом. Чтобыначатьработу, нжно сначала
получить контекст. Для этого <вызывается функция CryptAquireContext?
которой> Вы передаете имя ключевого контейнера(UserName) и имч
которой> сервера, с которым хотите установить связь<еще и тип сервера>.
Полученный дескриптор контекста используется во всех последующих
вызовах функций CryptoAPI.
Ключ сеанса вступает в игру когда дело доходит до шифровки/дешифровки
данных. Ключ сеанса определяет, как файл <данные>должен быть
кодирован. Если ВАм нужно извлечь ключ сеанса из CSP <например в целях
хранения или обмена, чтобы потом/другие могли расщифровать вашие
послание> вы используете ключевые блоки blob's, который может
рассмтариватьс как зашифрованный вариант ключа, пригодный для экспорта.
Механизм защиты завершают ключи обмена. Это пары ключей(один общий,
один личный), которые отвечают за шифровку/дешифровку ключей сеанса
в ключевых блоках при экспорте и за обработку цифровых подписей.
<к сожалению , шифровать данные публичным ключом, и расшифровывать
личным неполучилось, не разрешает такое винда:-( надо шифровать
сеансовым, потом зашифровывать его публичным. Потом расшифровывать
приватным сеансовый и расшифровывать сенасовым данные. Именно такой
алгоритм реализован в проге>

Подержка криптографии не трубет от Вас знакомства с деталями RSA,
DES, или любого другого стандартного алгоритма.
--



В MSDN много подробной документации по этой теме, в частности как
шифровать с паролем, и как шифровать с использованием сеансового
ключа (но только для одной машины), как ставить подписи и т.д.
Но как шифровать так, чтобы потом смог расшифровать именно один
человек,такого примера я не нашел.
Тут я реализовал программу, которая шифрует с помощью сеансового
ключа, который экспотрируется в зашифрованный файл, будучи сам
зашифрован ключом, заданным при шифровке(по идее чей-то общий ключ).
Затем человек, который обладает сооветствующим личным ключом может
расшифровать (с помощю этой же проги) сеансовый ключ, а уже им можно
расшифровать сообщение.
Если програма не обнаруживает ключевого контейнера для данного
пользователя, или ключей в нем(ключей обмена и ключей подписи) то она
создает их.
Также, используя эту прогу можно удалиь контейнер со всеми ключами.

P.S. Тут весьма корявая обработка ошибок, так что если кто-то решит
использовать это прогу в качестве отправной точки для собственных нужд, совет:
перераотайте систему обработки ошибок.
P.P.S. Для компиляции этого проэкта не в winnt Вам нужно будет либо
слегка модифицировать файл wincrypt.h закоментировав вначала строчку
if(_WIN32_WINNT) и в конце нужно закоментировать к нему endif, либо в
вначалу своей проге до #include &lt;wincrypt.h&gt;написать
ifndef(_WIN32_WINNT) define _WIN32_WINNT 0x0500
за правильность второго метода не ручаюсь, сам я менял файл
wincrypt.
Счастливые обладатели winNT могут не беспокоиься. Про работу под Win2K
ничего сказать не могу.


Еще в основной файл я включил шаполчку от какой-то лицензии на
open-source программное обесспечение, вроде бы от GNU, не помню точно.
Прогу погонял на вин 98 вроде работает нармально. Если вдруг у Вас
не 98 и не рабоает, отсылайте обратно, буду прогу дорабатывать.;)
Да, вот еще что я туда положил два екзешника 16 кб и 8 кб.(это одна и
та же прога) у меня
запускаются оба, проверьте , какой у Вас будет запускаться.

Download

Скачать исходник - 35 Kb