вторник, 9 июля 2013 г.

HOWTO: использование ЭЦП и шифрования на практике

Ну такой небольшой HOWTO, по использованию электронной подписи и шифрования.

Часть первая.

Введение

Подпись применяется повсеместно, но её применение строгим образом лимитировано государством. Она называется в оффлайне "печатью", и ставится разными юр. лицами для того, что-бы было понятно, какое лицо создало данный документ. Для физ. лиц используется обычная подпись.

Для электронных документов не используется НИЧЕГО. Таким образом, получая документ, мы даже не знаем, кто его нам прислал. Для быдла это очевидно не нужно. Шибко грамотные используют обратный адрес(IP, доменное имя сайта) для установления отправителя, но никто не задумывается о том, что подделать его не просто, а очень просто. Часто используется SSL/TLS, хотя всем широко известно, что подделка этого протокола тоже возможна (ага, центр сертификации может быть скомпрометирован). Получается, что надеяться можно исключительно на себя.

Про шифрование вообще никому похоже в Этой Стране неизвестно. Его кагбэ и нет.  Ибо «честному человеку скрывать нечего». Это ложь.

Проблема в том, что честному человеку есть что скрывать, и эта информация постоянно собирается, продаётся и покупается. Личные данные нужны в основном для таргетинговой(целенаправленной) рекламы, рассылки спама, и прочей «полезной» деятельности. Естественно, иные криминальные и полукриминальные структуры также активно пользуются собранной информацией.

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

Принципы и проблемы

Достаточно просто зашифровать любой файл просто сложив его обратимым(это важно!) способом с любой известной случайной(т.е. непредсказуемой, и это тоже важно!) информацией. Доказано, что если дополнительная информация действительно непредсказуемая, то не зная её невозможно расшифровать файл. Эта дополнительная информация является ключом . Размер такого ключа должен быть равен размеру файла. Но к счастью, математики сумели придумать способ разворачивания небольшого пароля в ключ нужной длинны.

Ну следуя традиции, мы будем рассматривать передачу разведчицы Алисы резиденту Бобу. Перед передачей Алиса и Боб УЖЕ должны  знать пароль. Если его никто другой не знает, то никто не сможет прочитать переданный файл кроме Боба(Алиса тут тоже может, но это не обязательно, её же файл). Из-за того, что пароль короткий, злоумышленник может его подобрать с помощью грубой силы, используя тот факт, что о статистических данных сообщения можно заранее догадаться. Для предотвращения данной атаки, Алисе нужно рандомизировать своё сообщение так, что-бы оно было неотличимо от случайного мусора. К счастью, данная задача решена, с помощью известных всем программ сжатия -- они выкидывают лишнюю информации, оставляя только необходимую. При этом, каждый бит файла увеличивает свой "вес"(энтропию) до своего максимального значения равного ½ (как монетка, про которую мы ничего не знаем). Сообщение становится максимально непредсказуемым, что существенно затрудняет подбор.

Что-бы решить задачу аутентификации(что-бы Боб был уверен, что сообщение именно от Алисы), Алиса может отправить Бобу зашифрованную известную Бобу информацию. Этим она докажет то, что она это она.

Остаётся проблема передачи самого пароля. Данную задачу решает асимметричное шифрование. Имеются математические функции, которые можно легко(сравнительно) вычислить в прямом направлении, и намного сложнее в обратном. К примеру попробуйте разложить на простые множители 539369709830409850025883673. Мой компьютер с этим справился более чем в 400 раз дольше, чем перемножал. Числа нужно взять НАМНОГО больше, дабы разложение заняло-бы заведомо нереальное время. Такое произведение можно(и нужно) публично выкладывать где угодно, а вот сами множители нужно тщательно скрывать. Множители называются секретной частью, а произведение -- публичной(или секретным и открытым ключом соответственно).

Имея публичный ключ Боба, Алиса может зашифровать файл так, что никто кроме Боба его не прочитает (включая и саму Алису). А вот своим секретным ключом, Алиса может подписать файл так, что любой может проверить подлинность файла, и для проверки ему ничего не понадобится, кроме публичного ключа Алисы.

Технически, асимметричное шифрование длинных файлов очень долгое, потому их шифруют неким одноразовым случайным паролем, а вот этот пароль шифруют асимметрично. Также и с подписью -- используется односторонняя функция от сообщения, называемая "хеш". Зная сообщения можно просто и быстро получить его хеш, но обратное преобразование невозможно. Также и коллизии(совпадения) хешей хоть и возможны теоретически, но вероятность их равна нулю (с практической т.з.) Алиса расшифровывает хеш своим секретным ключом, и то, что получилось, использует как ЭЦП. Любой может это число зашифровать публичным ключом Алисы, и получить хеш. Совпадение хешей гарантирует авторство Алисы. (подробнее, и не настолько упрощённо, см. в энциклопедии, здесь я попытался упростить до предела понимание, вплоть до того, что некоторые детали не совсем соответствуют действительности. Я думаю, они не слишком важны на практике)

Практика

Здесь и далее  я буду использовать стандартную программу gpg, у неё конечно есть GUI (и не один), а также она работает в любых системах. И тем не менее, я настоятельно рекомендую хотя-бы один раз сделать это в консоли. Начнём мы конечно с создания пары своих ключей:


$ gpg --gen-key 
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Выберите тип ключа:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (только для подписи)
   (4) RSA (только для подписи)
Ваш выбор (?-подробнее)? 
ключи RSA могут иметь длину от 1024 до 4096 бит.
Какой размер ключа Вам необходим? (2048) 
Запрашиваемый размер ключа 2048 бит
Выберите срок действия ключа.
         0 = без ограничения срока действительности
        = срок действительности n дней
      w = срок действительности n недель
      m = срок действительности n месяцев
      y = срок действительности n лет
Ключ действителен до? (0) 
Ключ не имеет ограничения срока действительности
Все верно? (y/N) y

Для идентификации Вашего ключа необходим User ID
Программа создаст его из Вашего имени, комментария и адреса e-mail в виде:
    "Baba Yaga (pensioner) "

Ваше настоящее имя: emulek-test
Email-адрес: emulek.bx@gmail.com
Комментарий: тест
Используется таблица символов: `utf-8'.
Вы выбрали следующий User ID:
    "emulek-test (тест) "

Сменить (N)Имя, (C)Комментарий, (E)email-адрес или (O)Принять/(Q)Выход? O
Для защиты секретного ключа необходим пароль.

Вам не нужен пароль? Это ОЧЕНЬ ПЛОХАЯ идея!
Работа будет продолжена. Вы сможете сменить пароль в любое время,
запустив данную программу с ключом "--edit-key".

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

Недостаточно случайных чисел.  Выполняйте какие-либо действия для того,
чтобы ОС могла получить больше случайных данных! (Необходимо ещё 284 байт)
.+++++
.+++++
Необходимо сгенерировать много случайных чисел. Желательно, что бы Вы
выполняли некоторые другие действия (печать на клавиатуре, движения мыши,
обращения к дискам) в процессе генерации; это даст генератору
случайных чисел возможность получить лучшую энтропию.

Недостаточно случайных чисел.  Выполняйте какие-либо действия для того,
чтобы ОС могла получить больше случайных данных! (Необходимо ещё 23 байт)
.........+++++

Недостаточно случайных чисел.  Выполняйте какие-либо действия для того,
чтобы ОС могла получить больше случайных данных! (Необходимо ещё 53 байт)
.....+++++
gpg: ключ E79DF0AF помечен как абсолютно доверяемый.
открытый и закрытый ключи созданы и подписаны.

gpg: проверка таблицы доверий
gpg: 3 ограниченных необходимо, 1 выполненных необходимо, PGP модель доверия
gpg: глубина: 0  корректных:   3  подписанных:   1  доверия: 0-, 0q, 0n, 0m, 0f, 3u
gpg: глубина: 1  корректных:   1  подписанных:   0  доверия: 0-, 0q, 0n, 0m, 1f, 0u
pub   2048R/E79DF0AF 2013-07-09
Отпечаток ключа = 15A7 34D1 5C8A 0589 A8A0  F2DB 8BB8 B503 E79D F0AF
uid                  emulek-test (тест) 
sub   2048R/B60B9CA7 2013-07-09


Принцип защиты информации базируется на том, что злоумышленник никогда не узнает секретную часть ключа, потому важно, что-бы она НЕ покидала компьютер (бекапить её можно например зашифровав весь каталог ~/.gnupg, причём это можно сделать всего один раз. Этот ключ не поменяется, если вы его конечно сами не отзовёте), ну и кроме того, даже локально секретный ключ тоже шифруется паролем. Каждый раз при расшифровке и при подписывание НЕОБХОДИМО ручками этот пароль набирать. Если на другом компьютере вам понадобится ключ -- просто сделайте ещё один. Это ведь не сложно.

Следует помнить, что ВСЯ зашифрованная информация при потере секретного ключа превратится в груду бесполезного мусора.

Публичная часть ключа

В отличие от секретной части, публичную можно и нужно оставлять где угодно в широком доступе. Если злоумышленник подменит/спрячет ВСЕ публичные ключи Алисы, то Боб тоже лишится защищённого канала, если не успеет сохранить себе копию.


Только-что сделанный ключ можно преобразовать в файл такой командой:

gpg --armor --export E79DF0AF
 
Здесь E79DF0AF это идентификатор данного ключа(впрочем, можно использовать имя, мыло, или уникальные их части). Посмотреть список ключей(кольцо) можно так:

gpg --list-key
pub   2048R/E79DF0AF 2013-07-09
uid                  emulek-test (тест) 
sub   2048R/B60B9CA7 2013-07-09
 
(список секретных ключей можно смотреть с опцией --list-secret-keys). Также ключ можно и отправить на публичный сервер ключей командой

$ gpg --send-keys E79DF0AF
gpg: отправляю ключ E79DF0AF на hkp сервер pgp.mit.edu
 
Сервер ключей задан в ~/.gnupg/gpg.conf (можно задать и в команде ключом --keyserver. Принимать ключ с сервера нужно так же, но с опцией --recv-keys. За раз можно принять несколько ключей)

Ну а уж про использование ключей я расскажу в следующей части…

Часть вторая

Комментариев нет:

Отправить комментарий