вторник, 8 октября 2013 г.

Шифруемся в Linux

Иногда в приступе паранойи целях разумного сокрытия данных возникает необходимость эти данные зашифровать. Представим простую ситуацию: в тылу вражеской сети два агента Кирилл и Таня нуждаются в обмене файлом со сверхсекретными данными, например, сообщением:
"Кодовое слово: рыба-меч!"
Передавать текстовый файл с кодовым словом в открытую по сети опасно, ибо в случае компрометации файла пароль станет известен врагу. Другого способа связи у агентов нет. Оба агента не понаслышке знают о симметричном и асимметричном шифровании, естественно и являются счастливыми пользователями Linux. Каковы сценарии развития событий?

Сценарий 1. Симметричное шифрование.

Агенты Кирилл и Таня достаточно самонадеянно решили использовать самое обычное симметричное шифрование. Логика проста: пока никто не догадывается, что они — секретные агенты, значит можно не мудрствуя лукаво зашифровать файлик с сообщением и спокойно перекинуть по сети без подозрений, что за ними кто-то следит. И что этот кто-то попытается файлик расшифровать. А даже если он и попытается, то секретного ключа на файлик он всё равно не знает, а, значит, ценная информация ему не достанется. Проще некуда!
Агенты решают воспользоваться утилитой GnuPG, благо в последних сборках почти всех линуксов она имеется. Неимевшуюся по какому-то недоразумению утилиту на компьютере одного из агентов быстро устранили, выполнив в терминале Ubuntu:
sudo apt-get install gnupg
Итак, файл с кодовым словом создан и называется message.txt. Агент Таня приступает к шифрованию данных. Перед ней стоит несложная задача: выбрать алгоритм для шифрования. Но какие алгоритмы можно использовать? Выход находится очень быстро:
gpg --version
Команда вывела все доступные алгоритмы шифрования:
Поддерживаются следующие алгоритмы:
С открытым ключом: RSA, RSA-E, RSA-S, ELG-E, DSA
Симметричные шифры: 3DES, CAST5, BLOWFISH, AES, 
AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192,
CAMELLIA256
Хэш-функции: MD5, SHA1, RIPEMD160, SHA256, SHA384,
SHA512, SHA224
Алгоритмы сжатия: Без сжатия, ZIP, ZLIB, BZIP2
Дело за малым — зашифровать сообщение. Таня, выбрав любимый алгоритм Blowfish, пишет в консоли:
gpg --symmetric --cipher-algo blowfish message.txt
,затем вводит секретный ключ, повторяет его и получает зашифрованный файл с именем message.txt.gpg.
Теперь, можно передать этот файлик Кириллу, а если вражеский агент и перехватит файл, то увидит в нём только нечитаемые каракули. Единственная проблема — секретный ключ Таня тоже должна каким-то образом передать, иначе участь агента Кирилла ничем не будет отличаться от участи коварного вражеского агента: и тот и другой будут видеть одинаковые каракули.
На этом моменте текста должно прийти осознание, что симметричные алгоритмы,в общем-то, плохо годятся в работе секретных агентов. Потому как имеются все шансы провалить операцию из-за передачи ключа, расшифровывающего данные. Не буду в теме данной сугубо практической заметки затрагивать такие темы как обмен Диффи-Хеллмана и прочие криптографические вещи — решение этой проблемы на самом деле существует. И одно из них — не использовать симметричное шифрование.
Впрочем, вражеский агент оказался недостаточно подкован технически и не сумел перехватить передававшийся по открытому каналу ключ, поэтому агент Кирилл, получив сообщение от Тани без труда смог расшифровать его, используя тот самый ключ (вводится после следующей команды):
gpg --decrypt-files message.txt.gpg
Мог быть и другой вариант расшифровки:
gpg --decrypt message.txt.gpg
в случае которого содержимое записалось бы не в файл, а вывелось в консоль.
Миссия выполнена!

Сценарий 2. Асимметричное шифрование.

На этот раз агентам выпала задачка посложнее: нужно выяснить, кто убийца. Находящийся на базе агент Таня внимательно следит за событиями. На месте преступления орудует агент Кирилл. Ему нужно абсолютно анонимно передать на базу агенту Тане сообщение:
Я всё узнал. Убийца — дворецкий!
Кирилл абсолютно точно знает, что его канал с Таней прослушивают. В случае симметричного шифрования, передача сообщения без компрометации невозможна. Нужно срочно переходить на асимметричное, покуда убийца не скрылся. Что делать? Итак, для начала Таня генерирует двойку ключей: закрытый и открытый.
gpg --gen-key
выбирает алгоритм (пусть это будет RSA and RSA):
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (только для подписи)
   (4) RSA (только для подписи)
выбирает длину ключа (пусть будет 2048) :
ключи RSA могут иметь длину от 1024 до 4096 бит.
Какой размер ключа Вам необходим? (2048)
выбирает срок его действительности (поскольку условия очень жёсткие, ставим 1 день):
Выберите срок действия ключа.
      0 = без ограничения срока действительности
      <n>  = срок действительности n дней
      <n>w = срок действительности n недель
      <n>m = срок действительности n месяцев
      <n>y = срок действительности n лет
Затем самое основное: идентифицируем созданный ключ. Для этого агент Таня вводила имя, e-mail и комментарий. Любое из этих полей впоследствии сможет идентифицировать ту пару ключей, которую она создала.
Отлично!Теперь Таня должна придумать секретный пароль для возможности шифрации/дешифрации. После его ввода, утилита принимается генерировать случайные числа для пары ключей. Для того, чтобы энтропия была наилучшей, Тане необходимо изобразить бурную деятельность: нажимать клавиши на клавиатуре, кликать мышкой — одним словом, подавать различные сигналы на устройства ввода, чтобы выборка случайных чисел для ключей носила "более случайный характер".
После того, как генератор случайных чисел закончит работу, в консоли появится что-то вроде:
pub   2048R/829B126C 2013-10-07 [годен до: 2013-10-08]
uid   Tanya (Секретно) <agent@agents.ru>
sub   2048R/69ABAE97 2013-10-07 [годен до: 2013-10-08]
Итак, подведём небольшой итог того, что получилось у Тани:
  • Открытый ключ — это тот самый ключ, который Таня может спокойно отправить агенту Кириллу для того, чтобы он зашифровал сообщение. В выводе выше он указан в строчке pub, имеет ID = 829B126C, который его однозначно идентифицирует среди всех остальных ключей.
  • Закрытый ключ — это тот "секретный ингредиент", который позволяет агентам спокойно передавать открытый ключ, поскольку только закрытый ключ может быть использован для дешифрации сообщения. В выводе выше его ID указан в строчке sub и равен 69ABAE97. Содержимое этого ключа никому нельзя передавать.
  • Секретный пароль — тот самый пароль, который вводила агент Таня при создании пары вышеупомянутых ключей. Пользоваться им будет только она, передавать его никуда не нужно.
Агент Таня хочет отправить ключ Кириллу, чтобы как можно скорее получить информацию о результатах расследования. Но как это сделать? Очень просто — содержимое открытого ключа нужно экспортировать в файл:
gpg --output key.txt --armor --export 69ABAE97
, где параметр --armor отвечает за то, чтобы файл был текстовым, а не бинарным, а параметр --export отвечает за идентификацию ключа (в данном случае указан его ID, однако можно использовать полное/частичное имя или комментарий).
Файл key.txt отправляется секретному агенту на задании. Что же он должен сделать? Конечно, импортировать пришедший ключ:
gpg --import key.txt
Теперь этот ключ зарегистрирован во внутренней базе данных GnuPG на компьютере у секретного агента Кирилла, но воспользоваться им пока нельзя — необходимо установить уровень доверия новому и неизвестному системе ранее ключу. Кирилл принимается его редактировать:
gpg --edit-key 69ABAE97
>>>trust
>>>5
>>>y
>>>quit
Ключевое слово trust открывает меню редактирования уровней доверия (всего 5), 5 — абсолютный уровень доверия. Окей, теперь ключ Тани зарегистрирован у Кирилла, ему присвоен абсолютный уровень доверия и теперь агент может приступить к шифрованию своего файла с сообщением:
gpg --recipient Tanya --encrypt message.txt --output
 breaking_news.txt
,где --recipient — это получатель, единственный владелец ключа, которым можно расшифровать сообщение. Тут небольшое пояснение: Tanya — это то самое имя, которое агент таня указывала при создании пары ключей. Теперь агент Кирилл с помощью этого имени фактически просто идентифицирует ключ, которым он зашифровывает сообщение (ключ с именем Tanya у Кирилла всего один, поэтому ему необязательно использовать его ID). Важный момент: сам Кирилл не сможет расшифровать собственное сообщение, поскольку закрытый ключ для расшифровки находится только у Тани.
Вдобавок к сообщению, Кирилл прикладывает MD5-хеш прикладываемого файла для того, чтобы Таня смогла проверить, правильно ли дешифрировался файл. Хеш получается очень просто:
md5sum message.txt
а файлик с полученной суммой упаковывается в архив вместе с зашифрованным файлом breaking_news.txt.gpg. Отличная работа! Теперь можно отправлять сообщение изнывающему от нетерпения агенту Тане.
Получив сообщение, агент Таня немедленно приступает к дешифрации, используя неявно закрытый ключ и вводя секретный пароль:
gpg --decrypt-files breaking_news.txt.gpg
Сравнив хеши, агент Таня удостоверяется в идентичности сообщения. Тайна разгадана. Убийца найден. На поиски дворецкого привлечены лучшие умы криминалистики и сыска. Однако, самое время замести следы. Смотрим ID закрытого ключа:
gpg --list-secret-keys
Экспортируем нужный закрытый ключ в файл и уносим куда подальше:
gpg --output myseckey.txt --armor --export-secret-key Tanya
Mission complete.
Читать дальше......