Сервер в кармане, или просто о сложном!

главная - Статьи - Почта - Шифрование почты

Самоподписанный сертификат OpenSSL для S/MIME подходящий для iPhone

Теги: Windows Linux Шифрование Защита почты

В предыдущих статьях было описано как получить сертификат s/mime от Comodo и настроить Outlook на работу с ним. Но в этой схеме есть недостаток - сертификат, которым вы можете шифровать конфиденциальные данные, выпущен третьей стороной. Да, с точки зрения удобства, если требуется упростить обмен конфиденциальными данными, такой сертификат, подписанный известным центром сертификации, является достаточно простым методом. Но если есть желание увеличить степень контроля за перепиской или количество сертификатов планируется достаточно большим, а бюджет - не очень, то остается один вариант - выпускать сертификаты самому. Достаточно простой способ реализации этой затеи - генерация приватного и публичного ключей с помощью OpenSSL, который встроен в любую систему Linux по умолчанию (крайне редко можно встретить даже минимальный дистрибутив без openssl в базе). Дальше все просто - обмен публичными ключами, настройка почтовых клиентов.

Цель: обеспечение удобной защиты почтовой переписки (даже в случае взлома пароля почты) с обязательной возможностью работы с разных устройств (в том числе мобильных) и разных операционных систем для небольшой компании.

Требования:

  1. Полностью контролировать выпуск сертификатов OpenSSL для подписи и шифрования почты S/MIME.
  2. Выпущенные сертификаты должны быть совместимыми с большинством популярных почтовых программ, включая мобильные устройства.
  3. Все клиентские сертификаты должны быть подписаны одним общим ключом, который будет установлен на все устройства, вовлеченные в процесс обмена, чтобы наши самоподписанные сертификаты выглядели бы удостоверенными, а не "левыми", недоверенными и прочее. Т.е. на каждое устройство/компьютер будут установлены два ключа: один общий, (по сути, CA) и второй личный для каждого человека свой. Если у одного человека несколько устройств, то само собой личный сертификат будет одинаковый на всех его устройствах.

Почему я отметил "удобную защиту почты"? Всё просто - неудобное средство не будет использоваться во всех необходимых случаях. К сожалению, это факт.

Почему я выделил поддержку мобильных устройств? Потому что именно мобильность переписки является на текущий момент основным требованием, а как выяснилось, с ходу сгенерированные OpenSSL сертификаты не импортировались в iPhone. Или импортировались, но не могли быть использованы для подписи или шифрования переписки, в то время как Outlook или Thunderbird могли их использовать. Таким образом конечная цель - безопасная переписка по электронной почте - была невыполнима. Ненормально, когда человек в командировке не может быстро получить доступ к переписке и не может написать зашифрованное письмо.

Почему iPhone, а не Android? Всё просто - я и моё окружение используем iPhone исторически и менять (а надо ли?) Яблоко на Дроида никто бы не согласился. При этом ни на секунду не собираюсь утверждать, что одно лучше или хуже другого. Вообще не собираюсь :)

Так, с вводными данными закончили. Теперь вот что: я изначально не хотел настраивать файлы конфигурации openssl.cnf. Поэтому все дальнейшее никак не затронет дефолтного файла конфигурации openssl.cnf. Оставьте его в покое. Пока точно не будете знать, что вы делаете и зачем. Тогда можно и нормальный CA делать. А сейчас попробуем попроще.

Общая идея действий: каждому пользователю будет создан его личный сертификат (в примере это client.crt). Этим сертификатом пользователь будет шифровать и подписывать почтовые сообщения. У Пети есть сертификат client1.crt, у Васи - client2.crt. Мы хотим создать свой "круг доверия" - чтобы при получении письма от Пети Вася точно знал бы, что это email от Пети. Т.к. мы с вами - не удостоверяющий центр, то все сертификаты, которые мы создадим, не будут выглядеть как доверенные и файл cert1.crt может создать кто угодно, хоть бы ваш сосед, например. Как быть уверенным, что Вася получил письмо, зашифрованное именно ключом, выданным администратором Пете, а не подделаным кем-то? Нам для этого надо сделать свой аналог доверенного центра. Для этого мы создадим секретный ключ mail-ca.key (и соотв. ему сертификат mail-ca.crt), которым будем подписывать все выпущенные сертификаты пользователей. Пете мы выдадим client1.crt и mail-ca.crt, Васе - client2.crt и mail-ca.crt и т.д. Если Вася получит от Пети письмо, подписанное ключом client1.crt, то почтовая программа Васи при просмотре сертификата client1.crt увидит, что этот сертификат подписан тем же mail-ca, который уже установлен у Васи (mail-ca.crt). Таким образом, доверие к сертификату будет. Если же от Пети придет письмо, подписанное сертификатом, который не был подписан с помощью mail-ca, то очевидно, что что-то здесь не так и возможно Петя уже не тот добрый Петя, которого мы так хорошо знаем.

Все, поехали, а то болтовни больше кода команд, если честно. Имеем openssl и дефолтный конфиг.

Сменим рабочую директорию (на ту, где у нас openssl.cnf, пусть уж все будет в одном месте) и там и останемся до конца процесса:

# cd /etc/pki/tls

Наш маленький CA

Создаём приватный ключ и публичный сертификат нашего "удостоверяющего центра":

# openssl genrsa -aes256 -out mail-ca.key 8192
# chmod 0400 mail-ca.key

Приватный ключ (mal-ca.key) - самый важный файл из всего, что мы в этот раз создаем. Пароль secret1 естественно должен быть значительно сложнее, ведь если произойдет утечка приватного ключа то только пароль ключа будет защищать вас от поддельных сертификатов. Заранее подумайте, какие данные вы введете в сведения о сертификате, ведь этот сертификат будет потом установлен на всех клиентских устройствах в роли удостоверяющего центра. Если изменить сертификат одного клиента будет просто, то изменить этот сертификат будет совсем не просто.

Создаём публичный сертификат (mail-ca.crt), который будет установлен на всех клиентских устройствах (он будет подтверждать корректность сертификатов на устройствах пользователей):

# openssl req -new -x509 -sha512 -days 3650 -key mail-ca.key -out mail-ca.crt

Преобразуем сертификат в формат DER для дальнейшего импорта в разные почтовые программы:

# openssl x509 -outform der -in mail-ca.crt -out mail-ca.der

Ключ и сертификат клиента

Создаём секретный ключ клиента:

# openssl genrsa -aes256 -out client.key 8192
password: secret1

Создаём запрос клиентского сертификата:

# openssl req -new -key client.key -out client.csr

На этом шаге вы должны корректно указать данные владельца сертификата. В секциях Common Name и Email Address укажите ваш email (т.е. тот, для которого создается сертификат).

Создаем файл настроек для выпуска сертификата S/MIME: openssl-client-options.cnf:

basicConstraints = CA:FALSE
keyUsage = critical,digitalSignature, keyEncipherment
subjectAltName = email:copy
extendedKeyUsage=emailProtection

Создаем подписанный нашим новоявленным CA клиентский сертификат S/MIME:

# openssl x509 -sha512 -req -days 365 -in client.csr -CA mail-ca.crt -CAkey mail-ca.key -set_serial 1 -out client.crt -setalias "E-Mail Certificate" -trustout -extfile ./openssl-client-options.cnf

Преобразуем клиентский сертификат в формат DER для дальнейшего импорта в разные почтовые программы:

# openssl x509 -outform der -in client.crt -out client.der

Экспортируем клиентский сертификат в формат PKCS12 (включает приватный ключ):

# openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12

В общем, все уже ясно. Основная хитрость всего процесса - содержимое файла openssl-client-options.cnf. Именно в этих нескольких строчках заключаются весь цимус статьи. В сети есть похожие примеры (опции прописываюстя прямо в командной строке):

(выполнять не надо!) # openssl x509 -req -days 365 -in client.csr -CA mail-ca.crt -CAkey mail-ca.key -set_serial 1 -out client.crt -addtrust emailProtection -addreject clientAuth -addreject serverAuth -trustout

но выпускаемый сертификат в моем случае не получал опции emailProtection и др. (я пробовал разные варианты). А вот использование конфигурационного файла с опциями дало необходимый результат:

smime iPhone openssl

По аналогии выпускаем необходимое количество клиентских сертификатов (возможно, есть смысл не указывать опцию -set_serial, но мне этого не требовалось).

Дальше все как обычно - как зеницу ока храним приватный ключ mail-ca.key, пароли secret1 меняем на secret2 (чтобы никто не догадался), в зависимости от системы на клиенте устанавливаем подходящим файлом сертификаты mail-ca и client. Для Outlook 2007 и iPhone 4S для импорта приватного ключа (т.е. чтобы почтовая программа могла подписывать и шифровать письма) требуется файл в формате PKCS12. Если не установить mail-ca.crt в корневые доверенные центры сертификации, то сертификат пользователя client будет восприниматься как недоверенный.

Т.к. у всех участников процесса шифрования переписки будет установлен общий mail-ca.crt, то для них все клиентские сертификаты будут доверенными и не вызовут подозрения некрасивых подписей со стороны операционной системы. А если вдруг в пришедшем письме от Петра сертификат будет отображен как неподписанный нашим корневым центром сертификации (т.е. будет незаверенным ключом mail-ca.key), то это будет повод расследовать, не пытается ли кто-то третий выдать себя за участника обмена информацией:

OpenSSL S/MIME self signed certificate not trusted

Сроки валидности ключей и сертификатов (у меня для примера 10 лет или 3650 дней для приватного ключа CA и 1 год для клиентских сертификатов) выбирайте как себе удобно.

Дополнение

Основная проблема, с которой я столкнулся, была в том, чтобы точно понять, какие параметры сертификата мне необходимы. Я взял реальный сертификат, выданный Comodo (comodo.cer) и просмотрел его опции:

# openssl x509 -inform der -in comodo.cer -out comodo.pem
# openssl x509 -in comodo.pem -text -noout

Вот их часть:

 
        X509v3 extensions:
            X509v3 Authority Key Identifier:
                keyid:тут_буквы_и_цифири

            X509v3 Subject Key Identifier:
                тут_еще_буквы_и_цифири

				X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Extended Key Usage:
                E-mail Protection, 1.3.6.1.4.1.6449.1.3.5.2
            Netscape Cert Type:
                S/MIME

				X509v3 Certificate Policies:
                Policy: 1.3.6.1.4.1.6449.1.2.1.1.1
                  CPS: https://secure.comodo.net/CPS

Это помогло при выборе необходимых опций для файла настроек openssl-client-options.cnf. На эту тему смотрите man x509v3_config. Там есть много чего, но надо смотреть вдумчиво.

Чтобы передать сертификаты в iPhone я не нашел более удобного способа, как отправлять подписанное письмо (для обмена публичными ключами) и отправлять сертификат как вложение (для установки приватного ключа шифрования). На другие устройства проблем нет вообще никаких - флешка или карта памяти.

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

Кстати, не потеряйте ваши сертификаты и ключи!

Никто вас не заставляет использовать ваши самоподписанные сертификаты и для подписи, и для шифрования. Вы вполне можете выпустить бесплатные s/mime сертификаты у того же Comodo или StartSSL и использовать их для подписи, чтобы все получатели вашей корреспонденции видели сразу, что письмо в самом деле получено от вас. Т.е. подписанный настоящим CA сертификат для подписи и исключительно ваш сертификат для шифрования почты среди узкого круга лиц. И все это бесплатно.

Авторизуйтесь для добавления комментариев!


    забыли пароль?    новый пользователь?