Denis Gladkikh

outcoldman

My personal blog about software development

  • 29 Nov 2009
  • SSL, Сертификаты, CryptoAPI, Cryptography, CryptoPro, Криптография, КриптоПро, ЭЦП
  • 0 comments

Этой статьей я бы хотел начать небольшую серию топиков о том, как работать с сертификатами, а так же в каких задачах и как их можно применить. К сожалению, в свое время, когда мне пришлось знакомиться с этой темой – мне удалось найти очень мало литературы, которая бы в полной мере описывала точно мне нужную информацию о том, как использовать сертификаты в моем ASP.NET приложении. На данном этапе я не могу назвать себя экспертом, но все же хочу этой серией топиков поделиться тем, что я узнал, а так же, надеюсь, избавить в будущем кого-то от поиска информации.

В университетах на профильных специальностях (математика и информатика), обычно, присутствуют курсы по криптографии. У кого мало знакомства с данной темой, а так же для освежения, приведу пару примеров, где можно и нужно использовать криптографию. Потому, если вы хорошо знакомы с терминами криптографии и SSL, то вы можете пропустить эту часть. Так же с удовольствием приму конструктивные комментариев и предложений на эту тему. В следующих топиках, я постараюсь рассказать, о том как можно создавать сертификаты для тестирования и разработки, а так же как можно настроить аутентификацию при помощи сертификатов, ну и что еще придет в голову. На данный момент за мной уже числится одна статья про использование сертификатов под названием “Использование сертификатов: Подпись данных на стороне клиента.”

Криптография

Предположим, у вас есть сервер, который принимает данные. Есть задача – идентифицировать пользователя А, который будет отправлять данные, и, более того, иметь некоторый ключ, по которому в будущем можно определить, что эти данные принадлежат (переданы) именно пользователем А, а не Б. На первый взгляд задача тривиальна – у каждого пользователя будет идентификатор, его же мы будем класть рядом с переданной информацией в хранилище данных. А что если вы не можете обеспечить 100% безопасность сервера (он может быть взломан и данные могут быть подменены?), или пользователь А вам тоже не очень доверяет и он хочет знать, что вы его данные не подмените или не укажите, что эти данные были переданы пользователем Б? Привести пример ситуации просто – аукцион и ставки: пользователи хотят, чтобы все было честно и их ставки были бы только их - в случае выигрыша (никаких подтасовок и изменений сумм – неприятно же было бы, когда вы купили на электронном аукционе вещь за 10 рублей, а счет вам придет на 1000 рублей), а приложение-сервер (или заказчик аукциона) хотел бы иметь возможность точно быть уверенным, что пользователи не будут отказываться от ставок со словами – “ставка не наша, заходил кто-то другой”. Так вот, в этом случае и приходят на помощь сертификаты и ЭЦП (электронная цифровая подпись).

Сертификат, в отличие от логина и пароля пользователя, это уже юридически прикрепленный идентификатор пользователя (сервера/компании), который по правилам (которое часто нарушается) безопасности должен находится на сменном носителе, вроде дискеты (такое и в наше время встречаю), флешки или самый лучший вариант eToken. В случае утери данного носителя (сравните это с ключами от квартиры) – пользователь предпримет любые меры, чтобы избежать использования этого “ключа” во вред ему: для этого он сообщит в удостоверяющий центр (УЦ) о его потере и УЦ сделает отзыв данного сертификата. После, когда “вор” попытается воспользоваться ключом, то УЦ (при запросе от сервера на проверку сертификата) скажет о его недействительности.

Еще один момент: как серверу удостовериться, что принятые данные именно от пользователя А, и что их в процессе передачи не повредили? У сертификата (пользователя) существует два ключа, один называют открытый ключ, который можно отдавать любому, и закрытый ключ, тот, который хранится на том самом сменном носителе (и который является “ключом от квартиры”). Сервер знает, что данные должны быть переданы пользователем А, в свою очередь пользователь А создает данные, подписывает их закрытым ключом и отправляет пару данные + ЭЦП на сервер. Сервер принимает данные и ЭЦП и проверяет равенство, в котором участвуют открытый ключ, данные и ЭЦП.

Рекомендую ознакомиться хотя бы с одним криптоалгоритмом из книги [1], например, с RSA. Важно знать еще понятие хеширования и хеш-функции – при помощи алгоритмов хеширования (например, MD5 или SHA) определенному набору данных ставиться в соответствие битовая строка фиксированной строки. При скачивании файлов рядом часто кладут хеш-код, чтобы можно было определить, что данные остались в целостности после передачи.

Secure Sockets Layer (SSL)

Итак, мы уже знаем, что существуют сертификаты пользователей, а какие еще могут быть сертификаты? На самом деле большинство сертификатов с которыми встречается большинство пользователей – это сертификаты серверов и сертификаты УЦ. Первый тип сертификатов мы встречаем когда переходим на сайты по ссылке https, это и есть SSL (версия 3.0 так же называется TLS) [4]. Сразу скажу, что в отличие от стандартного http запроса, который происходит на 80 порт, SSL работает по умолчанию с 443 портом (это следует учитывать при разворачивании инфраструктуры). Из названия становится ясно, что SSL – это уже шифрованный канал, по которому передаются данные. Сервер дает вам свой сертификат с открытым ключом, шифрует отдаваемые данные закрытым ключом, а вы в свою очередь расшифровываете данные и уверены, в том, что это данные приходят именно от того сайта, который прописан в url строке браузера. Вы же, в свою очередь, так же отсылаете данные серверу в зашифрованном виде (шифруя их открытым ключом сервера) для того, чтобы злоумышленник не смог украсть у вас пароль или код вашей банковской карточки. Точнее при установлении сеанса клиент генерирует пару ключей, зашифровывает открытый ключ при помощи открытого ключа сервера и отправляет его на сервер в зашифрованном виде. Далее клиент может шифровать данные, передаваемые на сервер при помощи закрытого ключа, сгенерированного для данного сеанса. Зашифрованные данные возможно прочитать только при помощи закрытого ключа сервера. Правда существуют случаи взлома старых алгоритмов, либо подбора ключей (всегда идет борьба на нахождение способа взлома криптографического алгоритма за полиномиальное время, а так же придумывание новых алгоритмов и способы защиты). 

Следует рассказать так же про сертификаты УЦ. Зададим вопрос, возможно ли создать самому сертификат? Да конечно, об этом я постараюсь рассказать в следующей статье. Тогда возникает другой вопрос, а зачем тогда платить третьим фирмам за сертификат для своего сайта, когда можно сделать свой? Давайте вспомним, видели вы предупреждения о том, когда переходите на страницу по https, что браузер не знает УЦ, выдавший сертификат? Конечно же встречали, и скорее всего (у меня так точно было в первый раз) находит сомнения: “а стоит ли переходить на данную страницу”. Так вот, чтобы у пользователей вашего сайта не было таких сомнений существуют проверенные УЦ (а страница предупреждения обычно красная, и большинство пользователей чуя угрозу, даже не читая, просто закрывают страничку).

У каждого УЦ есть свой собственный сертификат с открытым ключом, который они публикуют, и который помогает проверить сертификат проверки сервера (либо пользователя) на то, что он выдан именно этим УЦ. В Windows есть хранилище доверенных УЦ, в котором по умолчанию (при установке) лежит уже некоторый список таких сертификатов. Думаю, что становится ясно, для сертификатов, использующихся в проверки серверов (https) не всплывают окна с предупреждением, если сертификат выдан УЦ, сертификат которого лежит в доверенных (если же не нарушены другие правила). Вот в этом и есть плюс купленных сертификатов, что к ним больше доверия у пользователей (а точнее они вообще не замечают дискомфорта). Пользователь может положить так же сертификат любого УЦ, который он посчитает нужным, в список доверенных.

Помимо серверных сертификатов, существует так же и клиентские сертификаты. В этом случае, кроме сертификата сервера в SSL соединении так же участвует сертификат пользователя. Для того, чтобы установить SSL соединение сертификаты сервера и пользователя должны иметь некоторый схожий набор параметров, такие как: алгоритм шифрования, длину ключа и другое. При помощи клиентского сертификата можно точно определять и идентифицировать пользователя, установившего соединение. Чтобы работало SSL соединение с использованием клиентского сертификата необходимо правильно настроить веб-север, в моем случае у IIS существует возможность при поддержки сайтом SSL “не принимать сертификаты пользователей”, “спрашивать при возможности” и “требовать”. В последнем случае пользователь не увидит страницу, если не предоставит свой сертификат.

В нашем государстве всегда все по ГОСТам, и в криптографии у нас так же есть несколько алгоритмов ГОСТ (см. [1]). И иногда нет выхода, как только использовать криптографические алгоритмы ГОСТ (государственные проекты), поэтому нужно искать сертифицированную реализацию данных алгоритмов, я работал с системой КриптоПро.

CryptoAPI

В Windows существует стандартный набор функций для работы с сертификатами и для использования криптографии вообще. Важно знать, что при разработке нет необходимости задумываться о том, какой тип сертификатов (будет это либо КриптоПро с ГОСТ, либо обычный RSA алгоритм), если вы не собираетесь выходить за рамки стандартных функций CryptoAPI, что, думаю, вряд ли случится. При использовании сертификата и попытки что то подписать или зашифровать или расшифровать CryptoAPI автоматически сам определит какой алгоритм (какого криптопровайдера) нужно выбрать и как обрабатывать. Если в сертификате используется какой то специализированный криптопровайдер, который не установлен в вашей системе, то работать конечно же на системе функции с использованием этого сертификата не будут. В случае использования CryptoAPI функций в .NET – это набор классов в пространстве System.Security.Cryptography [3]. Опять же, чтобы работать с КриптоПро в .NET (даже просто читать сертификаты) нужно поставить: во-первых сам криптопровайдер, а так же еще и дополнительный набор .NET сборок для работы с ними. Когда я начал использовать и изучать КриптоПро, к сожалению, этих библиотек не было в публичном доступе, а мне повезло: как-то в разговоре мне сказали, что могут предоставить beta вариант этой сборки для разработки, что мне сильно облегчило жизнь.

Для более подробного ознакомления с CryptoAPI можно почитать [2].

Литература

  1. Баричев С.Г., Серов Р.Е. Основы современной криптографии (Ссылка на google search). Отличная книга об основах криптографии, будет понятна любому. Советую для сдачи экзаменов по криптографии.
  2. Алексей Остапенко - Хеширование, шифрование и цифровая подпись с использованием CryptoAPI и .NET (RSDN Magazine).
  3. System.Security.Cryptography Namespace (MSDN библиотека).
  4. Secure Sockets Layer (SSL): How It Works (На сайте http://www.verisign.com очень познавательных статьей про SSL).

Comments