Відмінності між версіями «OpenSSL»

Матеріал з Wiki Welard
Перейти до навігації Перейти до пошуку
 
 
(Не показано одну проміжну версію цього користувача)
Рядок 1: Рядок 1:
−
[http://www.opennet.ru/base/sec/openssl.txt.html | Оригинал]
+
[http://www.opennet.ru/base/sec/openssl.txt.html | Оригинал] Статья впервые опубликована в журнале [http://www.samag.ru/ | Системный Администратор]  
−
Статья впервые опубликована в журнале [http://www.samag.ru/ | Системный Администратор]
 
  
−
== Использование OpenSSL (ssl security crypt cert mod_ssl apache imap postfix) ==
+
[http://wiki.oszone.net/index.php/OpenSSL_-_настройка_и_создание_сертификатов | OpenSSL - настройка и создание сертификатов]
 +
 
 +
== Использование OpenSSL (ssl security crypt cert mod_ssl apache imap postfix) ==
  
 
  OpenSSL - это система защиты и сертификации данных, название SSL переводится,
 
  OpenSSL - это система защиты и сертификации данных, название SSL переводится,
−
как система безопасных сокетов(secure socket layer). OpenSSL используется
 
−
практически всеми сетевыми серверами для защиты передаваемой информацией.
 
−
Существует программное API SSL(SSLEAY), позволяющее  создавать безопасные
 
−
сокеты с шифрацией передаваемых данных в собственных разработках. Но в данной статье
 
−
я бы хотел рассказать о самой системе OpenSSL, вызываемой через командную
 
−
строку.
 
  
−
Т.к. OpenSSL поддерживает очень много различных стандартов сертификации,
+
как система безопасных сокетов(secure socket layer). OpenSSL используется практически всеми сетевыми серверами для защиты передаваемой информацией. Существует программное API SSL(SSLEAY), позволяющее создавать безопасные сокеты с шифрацией передаваемых данных в собственных разработках. Но в данной статье я бы хотел рассказать о самой системе OpenSSL, вызываемой через командную строку.  
−
шифрования, хеширования, то использование данной команды достаточно сложно.
 
−
Внутри OpenSSL существуют отдельные компоненты, отвечающие за то или иное
 
−
действие, для получения списка доступных компонентов можно вызвать openssl с
 
−
параметрами list-standart-commands. Можно также получить список доступных
 
−
алгоритмов хеширования (list-message-digest-commands) и алгоритмов шифрования
 
−
(list-cipher-commands).  
 
  
−
OpenSSL может использоваться во множестве случаев и умеет выполнять следующие задачи:
+
Т.к. OpenSSL поддерживает очень много различных стандартов сертификации, шифрования, хеширования, то использование данной команды достаточно сложно. Внутри OpenSSL существуют отдельные компоненты, отвечающие за то или иное действие, для получения списка доступных компонентов можно вызвать openssl с параметрами list-standart-commands. Можно также получить список доступных алгоритмов хеширования (list-message-digest-commands) и алгоритмов шифрования (list-cipher-commands).
 +
 
 +
OpenSSL может использоваться во множестве случаев и умеет выполнять следующие задачи:  
 +
 
 +
*Создавать и управлять ключами RSA и DSA - команды rsa, dsa, dsaparam
 +
*Создавать сертификаты формата x509, запросы на сертификацию, восстановление -
  
−
* Создавать и управлять ключами RSA и DSA - команды rsa, dsa, dsaparam
 
−
* Создавать сертификаты формата x509, запросы на сертификацию, восстановление -
 
 
   команды x509, req, verify, ca, crl, pks12, pks7
 
   команды x509, req, verify, ca, crl, pks12, pks7
−
* Зашифровывать данные с помощью симметрического или асимметрического шифрования -  
+
 
 +
*Зашифровывать данные с помощью симметрического или асимметрического шифрования -
 +
 
 
   команды enc, rsautl
 
   команды enc, rsautl
−
* Высчитывать хеши различных типов - команда dgst
 
−
* Работа с S/MIME - команда s/mime
 
−
* Проверка работы серверов и клиентов ssl - команды s_client, s_server.
 
  
 +
*Высчитывать хеши различных типов - команда dgst
 +
*Работа с S/MIME - команда s/mime
 +
*Проверка работы серверов и клиентов ssl - команды s_client, s_server.
  
−
Cуществует также несколько вспомогательных утилит ssl:
+
<br> Cуществует также несколько вспомогательных утилит ssl:  
  
−
> openssl speed [список_алгоритмов_хеширования_или шифрования]:  
+
&gt; openssl speed [список_алгоритмов_хеширования_или шифрования]:  
  
 
   тестирование скорости различных алгоритмов, если запускать без
 
   тестирование скорости различных алгоритмов, если запускать без
Рядок 63: Рядок 57:
 
         cast cbc        10943.48k    12674.30k    12877.74k    12994.56k    13011.63k
 
         cast cbc        10943.48k    12674.30k    12877.74k    12994.56k    13011.63k
  
−
 
+
<br> Проверка алгоритмов асимметрического шифрования  
−
Проверка алгоритмов асимметрического шифрования
 
  
 
         |            Подписывание Проверка    За секунду подп. За секунду пров.   
 
         |            Подписывание Проверка    За секунду подп. За секунду пров.   
Рядок 76: Рядок 69:
 
         dsa 2048 bits  0.0309s  0.0377s    32.4            26.5
 
         dsa 2048 bits  0.0309s  0.0377s    32.4            26.5
  
−
 
+
<br> &gt; openssl rand [-out file] [-rand file] num:  
−
> openssl rand [-out file] [-rand file] num:  
 
  
 
   генерация num рандомных байт, можно использовать для проверки рандомизационной  
 
   генерация num рандомных байт, можно использовать для проверки рандомизационной  
Рядок 86: Рядок 78:
 
         #
 
         #
  
−
 
+
<br> &gt; openssl ciphers [-ssl2] [-ssl3] [-tls1] NAME:  
−
> openssl ciphers [-ssl2] [-ssl3] [-tls1] NAME:  
 
  
 
   вывод доступных алгоритмов для
 
   вывод доступных алгоритмов для
Рядок 93: Рядок 84:
 
   обеспечения уровня безопасности NAME, где NAME - это символическое название
 
   обеспечения уровня безопасности NAME, где NAME - это символическое название
 
   группы алгоритмов. Обычно используются значения  
 
   группы алгоритмов. Обычно используются значения  
−
   LOW - алгоритмы низкого уровня безопасности(<128 бит)
+
   LOW - алгоритмы низкого уровня безопасности(&lt;128 бит)
 
   MEDIUM - алгоритмы среднего уровня стойкости(128 бит)
 
   MEDIUM - алгоритмы среднего уровня стойкости(128 бит)
−
   HIGH - алгоритмы высокой стойкости(> 128 бит)
+
   HIGH - алгоритмы высокой стойкости(&gt; 128 бит)
 
   ALL - все алгоритмы
 
   ALL - все алгоритмы
 
   NULL - алгоритмы без шифрования.
 
   NULL - алгоритмы без шифрования.
 
   Обычно в настоящее время используются алгоритмы групп MEDIUM и HIGH, которые
 
   Обычно в настоящее время используются алгоритмы групп MEDIUM и HIGH, которые
 
   ещё долго не смогут быть взломаны прямым перебором. Можно также вывести список
 
   ещё долго не смогут быть взломаны прямым перебором. Можно также вывести список
−
   алгоритмов из нескольких групп, разделив их :(например, MEDIUM:HIGH)
+
   алгоритмов из нескольких групп, разделив их&nbsp;:(например, MEDIUM:HIGH)
  
−
 
+
<br> Теперь я бы хотел рассказать об основных утилитах openssl. Для начала я расскажу о методах генерации ключей, затем о командах шифрования, и, наконец, о сертификатах, s/mime. Итак, пару слов о генерации ключей. Для создания rsa ключей используется команда genrsa:  
−
Теперь я бы хотел рассказать об основных утилитах openssl. Для начала я расскажу
 
−
о методах генерации ключей, затем о командах шифрования, и, наконец, о
 
−
сертификатах, s/mime. Итак, пару слов о генерации
 
−
ключей. Для создания rsa ключей используется команда genrsa:
 
  
 
         openssl genrsa [-out file] [-des | -des3 | -idea] [-rand file] [bits]
 
         openssl genrsa [-out file] [-des | -des3 | -idea] [-rand file] [bits]
  
 +
<br> Команда genrsa создаёт секретный ключ длиной bits в формате PEM, шифрует его одним из алгоритмов des(56 бит), des3(3-й des 168 бит) или idea(128 бит). При выборе алгоритма шифрования будет запрошен пароль для шифрации создаваемого секретного ключа(если алгоритм не указан, то секретный ключ не шифруется, чего делать ни в коем случае нельзя для личных ключей, т.к. некоторые серверы требуют отсутствие шифрации для сектетного ключа сервера). Опция -out говорит программе, что вывод нужно осуществлять не в stdout, а в файл file(опция -out присутствует во множестве других компонентов openssl и используется аналогичным образом для указания выходного файла). Опция -rand указывает на файл[ы](разделённые&nbsp;:), из которых будут считываться данные для установки seed(зерна) генератора случайных чисел. В качестве таких файлов сразу же приходит на ум использовать что-то вроде /dev/random или /dev/urandom, но у меня с этим возникли проблемы - всё вешалось наглухо, поэтому я рекомендую в этом случае использовать какие-нибудь сложно угадываемые файлы, вроде /var/log/messages или /boot/vmlinuz, думаю, что угадать содержимое этих файлов не намного проще, чем содержимое /dev/random, но работает этот фокус в любом
  
−
Команда genrsa создаёт секретный ключ длиной bits в формате PEM, шифрует
 
−
его  одним из алгоритмов des(56 бит), des3(3-й des 168 бит) или
 
−
idea(128 бит). При выборе алгоритма шифрования будет запрошен пароль
 
−
для шифрации создаваемого секретного ключа(если алгоритм не указан, то
 
−
секретный ключ не шифруется, чего делать ни в коем случае нельзя для
 
−
личных ключей, т.к. некоторые серверы требуют отсутствие шифрации для
 
−
сектетного ключа сервера). Опция -out говорит программе, что вывод нужно
 
−
осуществлять не в stdout, а в файл file(опция -out присутствует во
 
−
множестве других компонентов openssl и используется аналогичным образом
 
−
для указания выходного файла). Опция -rand указывает на
 
−
файл[ы](разделённые :), из которых будут  считываться данные для
 
−
установки seed(зерна) генератора случайных чисел. В качестве таких
 
−
файлов сразу же приходит на ум использовать что-то вроде /dev/random
 
−
или /dev/urandom, но у меня с этим возникли проблемы - всё вешалось
 
−
наглухо, поэтому я рекомендую в этом случае использовать какие-нибудь
 
−
сложно угадываемые файлы, вроде /var/log/messages или /boot/vmlinuz,
 
−
думаю, что угадать содержимое этих файлов не намного проще, чем
 
−
содержимое /dev/random, но работает этот фокус в любом
 
 
*nixe(опция -rand также присутствует во всех компонентах генерации и управления
 
*nixe(опция -rand также присутствует во всех компонентах генерации и управления
−
ключами и сертификатами). Использовать /dev/random и /dev/urandom, конечно,
+
 
−
можно, но я для этого скопировал из /dev/random 32768 байт в файл .rnd таким
+
ключами и сертификатами). Использовать /dev/random и /dev/urandom, конечно, можно, но я для этого скопировал из /dev/random 32768 байт в файл .rnd таким образом:  
−
образом:
 
  
 
         dd if=/dev/[u]random of=.rnd count=64  
 
         dd if=/dev/[u]random of=.rnd count=64  
  
−
 
+
<br> Кроме этого, можно указывать в качестве -rand файла EGD сокет, который обеспечивает генерацию определённого количества случайных байт, EGD доступен на узле http://www.lothar.com/tech/crypto/. Установка генератора случайных чисел производится на основании хеша -rand файла, поэтому можно указывать файлы различной длины, т.к. хеш все равно имеет фиксированное число бит. Пример генерации 4096 битового секретного ключа RSA:  
−
Кроме этого, можно указывать в качестве -rand файла
 
−
EGD сокет, который обеспечивает генерацию определённого количества случайных
 
−
байт, EGD доступен на узле http://www.lothar.com/tech/crypto/. Установка
 
−
генератора случайных чисел производится на основании хеша -rand файла, поэтому
 
−
можно указывать файлы различной длины, т.к. хеш все равно имеет фиксированное
 
−
число бит. Пример генерации 4096 битового секретного ключа RSA:
 
  
 
         # openssl genrsa -out /etc/openssl/key.pem -des3 -rand /var/log/messages 4096
 
         # openssl genrsa -out /etc/openssl/key.pem -des3 -rand /var/log/messages 4096
Рядок 150: Рядок 113:
 
         Verify PEM passphrase:
 
         Verify PEM passphrase:
  
−
 
+
<br> После этого секретный ключ зашифровывается и записывается в файл(в текстовом виде). Вначале ключа указывается алгоритм шифрования. Для создания публичного ключа rsa на основе секретного используется команда openssl rsa. Даная команда имеет следующий формат:  
−
После этого секретный ключ зашифровывается и записывается в файл(в текстовом
 
−
виде). Вначале ключа указывается алгоритм шифрования. Для создания публичного
 
−
ключа rsa на основе секретного используется команда openssl rsa. Даная команда
 
−
имеет следующий формат:  
 
  
 
         openssl rsa -in filename [-out file] [-des | -des3 |-idea] [-check] [-pubout]
 
         openssl rsa -in filename [-out file] [-des | -des3 |-idea] [-check] [-pubout]
  
−
 
+
<br> Утилита openssl rsa способна изменять пароль и алгоритм шифрования cсекретного ключа, будучи вызвана с параметром -in и -out. Если применить параметр -pubout, то в указанный файл -out будет записан публичный ключ, вычисленный на основе -in секретного. Например, создание публичного ключа на основании секретного:  
−
Утилита openssl rsa способна изменять пароль и
 
−
алгоритм шифрования cсекретного ключа, будучи вызвана с параметром -in и -out.
 
−
Если применить параметр -pubout, то в указанный файл -out будет записан публичный
 
−
ключ, вычисленный на основе -in секретного. Например, создание публичного ключа
 
−
на основании секретного:
 
  
 
         openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/pubkey.pem -pubout
 
         openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/pubkey.pem -pubout
  
−
 
+
<br> Изменение пароля и алгоритма шифрования секретного ключа с des3 на idea:  
−
Изменение пароля и алгоритма шифрования секретного ключа с des3 на idea:
 
  
 
         openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/key1.pem -idea
 
         openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/key1.pem -idea
  
−
 
+
<br> Для создания ключей DSA используется утилита openssl gendsa, аналогичная genrsa, но есть два отличия: во-первых, для ключей DSA нельзя прямо указывать длину в битах и, во-вторых, ключи DSA могут генерироваться согласно некоторым параметрам, записанным в файл paramfile утилитой openssl dsaparam. dsaparam имеет следующий формат:  
−
Для создания ключей DSA используется утилита openssl gendsa, аналогичная genrsa,
 
−
но есть два отличия: во-первых, для ключей DSA нельзя прямо указывать длину в битах и,
 
−
во-вторых, ключи DSA могут генерироваться согласно некоторым параметрам,
 
−
записанным в файл paramfile утилитой openssl dsaparam. dsaparam имеет следующий
 
−
формат:
 
  
 
         openssl dsaparam [-rand file{s}] [-C] [-genkey] [-out file]  numbits
 
         openssl dsaparam [-rand file{s}] [-C] [-genkey] [-out file]  numbits
  
−
 
+
<br> где numbits - длина желаемого ключа, -С заставляет dsaparam вывести на stdout код на СИ для программной генерации DSA на основе необходимых параметров, а опция -genkey говорит, что в выходной файл, наряду с параметрами, дополнительно записывается созданный секретный ключ DSA, но нельзя его сразу же зашифровать, поэтому удобнее воспользоваться утилитой openssl gendsa, которая имеет схожий синтаксис с командой genrsa, но вместо числа бит указывается файл параметров, созданный dsaparam:  
−
где numbits - длина желаемого ключа, -С заставляет dsaparam вывести на
 
−
stdout код на СИ для программной генерации DSA на основе необходимых параметров,
 
−
а опция -genkey говорит, что в выходной файл, наряду с параметрами,  
 
−
дополнительно записывается созданный секретный ключ DSA, но нельзя его сразу же
 
−
зашифровать, поэтому удобнее воспользоваться утилитой openssl gendsa, которая
 
−
имеет схожий синтаксис с командой genrsa, но вместо числа бит указывается файл
 
−
параметров, созданный dsaparam:
 
  
 
         # openssl gendsa -out /etc/openssl/dsakey.pem -rand /boot/vmlinuz -idea paramfile
 
         # openssl gendsa -out /etc/openssl/dsakey.pem -rand /boot/vmlinuz -idea paramfile
Рядок 194: Рядок 135:
 
         Verify PEM passphrase:
 
         Verify PEM passphrase:
  
−
 
+
<br> Для управления ключами dsa используется программа openssl dsa, которая абсолютно аналогична(в параметрах) утилите openssl rsa. Поэтому я просто приведу пример генерации публичного ключа DSA:  
−
Для управления ключами dsa используется программа openssl dsa, которая абсолютно
 
−
аналогична(в параметрах) утилите openssl rsa. Поэтому я просто приведу пример
 
−
генерации публичного ключа DSA:
 
  
 
         # openssl dsa -in /etc/openssl/dsakey.pem -out /etc/openssl/pubdsakey.pem -pubout
 
         # openssl dsa -in /etc/openssl/dsakey.pem -out /etc/openssl/pubdsakey.pem -pubout
  
 +
<br> Теперь настало время рассказать о компонентах openssl, выполняющих шифрование и хеширование данных. Для выполнения симметрического шифрования используется утилита openssl enc -cipher, или её сокращённая запись openssl cipher, где cipher - это одно из символических имён симметрических шифров. Наиболее популярными являются следующие: base-64(преобразование в текстовый вид), bf(blowfish - 128 бит), des(56 бит), des3(168 бит), rc4(128 бит), rc5(128 бит), rc2 и idea(128 бит). Для указания входного и выходного файлов используется опции
  
−
Теперь настало время рассказать о компонентах openssl, выполняющих шифрование и
 
−
хеширование данных. Для выполнения симметрического шифрования используется
 
−
утилита openssl enc -cipher, или её сокращённая запись openssl cipher, где
 
−
cipher - это одно из символических имён симметрических шифров. Наиболее
 
−
популярными являются следующие: base-64(преобразование в текстовый вид),
 
−
bf(blowfish - 128 бит), des(56 бит), des3(168 бит), rc4(128 бит), rc5(128 бит),
 
−
rc2 и idea(128 бит). Для указания входного и выходного файлов используется опции
 
 
  -in и -out соответственно. Пароль для шифрования вводится с клавиатуры (можно указать
 
  -in и -out соответственно. Пароль для шифрования вводится с клавиатуры (можно указать
−
в командной строке параметром -k, но это очень плохо по соображениям
 
−
безопасности, т.к. большинство шелов умеют сохранять историю командной строки,
 
−
IMHO намного лучше ввести пароль непосредственно перед шифрованием, хотя эта опция
 
−
полезна для скриптов, так что забывать о ней нельзя :). Учтите, что
 
−
пароль не спрашивается при обработке файла base64, т.к. шифрования не
 
−
происходит. Для расшифровки зашифрованных данных примените openssl cipher с
 
−
опцией -d(алгоритм шифрования и дешифрования должен совпадать!), а для
 
−
одновременной обработки данных base64 можно воспользоваться опцией -a.
 
  
−
Шифрование по умолчанию происходит с подмешиванием(подсолением :), т.е. для выбора
+
в командной строке параметром -k, но это очень плохо по соображениям безопасности, т.к. большинство шелов умеют сохранять историю командной строки, IMHO намного лучше ввести пароль непосредственно перед шифрованием, хотя эта опция полезна для скриптов, так что забывать о ней нельзя&nbsp;:). Учтите, что пароль не спрашивается при обработке файла base64, т.к. шифрования не происходит. Для расшифровки зашифрованных данных примените openssl cipher с опцией -d(алгоритм шифрования и дешифрования должен совпадать!), а для одновременной обработки данных base64 можно воспользоваться опцией -a.
−
алгоритма подмешивания используется случайная соль(salt), в этом случае, если вы
+
 
−
шифруете один и тот же файл в разное время одним и тем же алгоритмом и паролем,
+
Шифрование по умолчанию происходит с подмешиванием(подсолением&nbsp;:), т.е. для выбора алгоритма подмешивания используется случайная соль(salt), в этом случае, если вы шифруете один и тот же файл в разное время одним и тем же алгоритмом и паролем, то результаты скорее всего будут разными(это затрудняет атаку по словарю). Также по умолчанию используется cbc режим алгоритмов, когда ключ меняется в течение всего сеанса работы согласно передаваемым данным, этот приём очень сильно затрудняет брутфорс, т.к. атакующему сложно поймать нужный момент времени.  
−
то результаты скорее всего будут разными(это затрудняет атаку по словарю). Также
 
−
по умолчанию используется cbc режим алгоритмов, когда ключ меняется в течение
 
−
всего сеанса работы согласно передаваемым данным, этот приём очень сильно затрудняет  
 
−
брутфорс, т.к. атакующему сложно поймать нужный момент времени.
 
  
−
Приведу несколько примеров:
+
Приведу несколько примеров:  
  
−
зашифруем файл, используя алгоритм des3
+
зашифруем файл, используя алгоритм des3  
  
 
         # openssl des3 -in file -out file.des3
 
         # openssl des3 -in file -out file.des3
  
−
 
+
<br> расшифруем полученный файл  
−
расшифруем полученный файл
 
  
 
         # openssl des3 -d -in file.des3 -out file
 
         # openssl des3 -d -in file.des3 -out file
  
−
 
+
<br> зашифруем файл, используя алгоритм blowfish(bf), и закодируем base64  
−
зашифруем файл, используя алгоритм blowfish(bf), и закодируем base64
 
  
 
         # openssl bf -a -in file -out file.bf64
 
         # openssl bf -a -in file -out file.bf64
  
−
 
+
<br> теперь расшифруем его и обработаем сразу же base64  
−
теперь расшифруем его и обработаем сразу же base64
 
  
 
         # openssl bf -a -d -in file.bf64 -out file
 
         # openssl bf -a -d -in file.bf64 -out file
  
 +
<br> Для вычисления хешей(их ещё называют отпечатками или контрольными суммами) используется команда openssl dgst -hashalg или краткая форма openssl hashalg(первая команда может также выполнять манипуляции с ЭЦП, но об этом далее). Обычное использование данной команды таково openssl hashalg [-c] file[s]. Вычисляется хеш сообщения фиксированной длины в виде одной строки или, если указана опция -c, строки, разделённой на пары HEX чисел двоеточием. Из алгоритмов хеширования могут применяться следующие: md2(128 бит), md4(128 бит), md5(128 бит), mdc2(128 бит), sha(160 бит), sha1(160 бит), ripemd160(160 бит).
  
−
Для вычисления хешей(их ещё называют отпечатками или контрольными суммами)
+
Опять же приведу пару примеров:  
−
используется команда openssl dgst -hashalg или краткая
 
−
форма openssl hashalg(первая команда может также выполнять манипуляции с ЭЦП, но
 
−
об этом далее). Обычное использование данной команды таково openssl hashalg [-c]
 
−
file[s]. Вычисляется хеш сообщения фиксированной длины в виде одной строки или,
 
−
если указана опция -c, строки, разделённой на пары HEX чисел двоеточием. Из
 
−
алгоритмов хеширования могут применяться следующие: md2(128 бит), md4(128 бит),
 
−
md5(128 бит), mdc2(128 бит), sha(160 бит), sha1(160 бит), ripemd160(160 бит).
 
  
−
Опять же приведу пару примеров:
+
вычислим md5 хеш файла:  
−
 
 
−
вычислим md5 хеш файла:
 
  
 
         # openssl md5 -c file
 
         # openssl md5 -c file
 
         MD5(file)= 81:fd:20:ff:db:06:d5:2d:c3:55:b5:7d:3f:37:ac:94
 
         MD5(file)= 81:fd:20:ff:db:06:d5:2d:c3:55:b5:7d:3f:37:ac:94
  
−
 
+
<br> а теперь SHA1 хеш этого же файла:  
−
а теперь SHA1 хеш этого же файла:
 
  
 
         # openssl sha1 file
 
         # openssl sha1 file
 
         SHA1(file)= 13f2b3abd8a7add2f3025d89593a0327a8eb83af
 
         SHA1(file)= 13f2b3abd8a7add2f3025d89593a0327a8eb83af
  
−
 
+
<br> Как я уже говорил, утилита openssl dgst может использоваться для подписывания сообщения секретным ключом и проверки ЭЦП публичным ключом. Для этого используется следующий синтаксис:  
−
Как я уже говорил, утилита openssl dgst может использоваться для подписывания
 
−
сообщения секретным ключом и проверки ЭЦП публичным ключом. Для этого
 
−
используется следующий синтаксис:
 
  
 
         openssl dgst -sign private_key -out signature -hashalg  file[s]
 
         openssl dgst -sign private_key -out signature -hashalg  file[s]
  
−
 
+
<br> Подписывание file с помощью секретного ключа private_key, используя алгоритм хеширования hasalg(обычно применяются sha1 или md5).  
−
Подписывание file с помощью секретного ключа private_key, используя алгоритм
 
−
хеширования hasalg(обычно применяются sha1 или md5).
 
  
 
         openssl dgst -signature signature -verify public_key file[s]
 
         openssl dgst -signature signature -verify public_key file[s]
  
 +
<br> Проверка подписи в file, используя публичный ключ public_key и ЭЦП signature. Данная программа выводит "Verification OK" при правильной подписи или "Verification Failure"
  
−
Проверка подписи в file, используя публичный ключ public_key и ЭЦП signature.
+
в любом другом случае. Учтите, что ЭЦП в таком случае хранится отдельно от файла, который ею подписан(причём в каком-то кривом формате).  
−
Данная программа выводит "Verification OK" при правильной подписи или
 
−
"Verification Failure"
 
−
 
 
−
в любом другом случае. Учтите, что ЭЦП в таком случае хранится отдельно от
 
−
файла, который ею подписан(причём в каком-то кривом формате).
 
  
−
Для шифрации и дешифрации RSA алгоритмом используется программа rsautl. Данная
+
Для шифрации и дешифрации RSA алгоритмом используется программа rsautl. Данная утилита имеет также возможность подписывать и проверять подпись сообщений(однако работать всё равно приходится с хешем сообщения, т.к. подписывать можно только небольшой объём данных, по этой причине лучше применять openssl dgst). Для шифрации/дешифрации используется следующий синтаксис:  
−
утилита имеет также возможность подписывать и проверять подпись сообщений(однако
 
−
работать всё равно приходится с хешем сообщения, т.к. подписывать можно только  
 
−
небольшой объём данных, по этой причине лучше применять openssl dgst). Для
 
−
шифрации/дешифрации используется следующий синтаксис:
 
  
 
         openssl rsautl -in file -out file.cr -keyin pubkey.pem -pubin -encrypt
 
         openssl rsautl -in file -out file.cr -keyin pubkey.pem -pubin -encrypt
  
−
 
+
<br> Шифрация file с использованием публичного ключа pubkey.pem  
−
Шифрация file с использованием публичного ключа pubkey.pem
 
  
 
         openssl rsautl -in file.cr -out file -keyin secretkey.pem -decrypt
 
         openssl rsautl -in file.cr -out file -keyin secretkey.pem -decrypt
  
 +
<br> Дешифрация file.cr с использованием секретного ключа secretkey.pem
  
−
Дешифрация file.cr с использованием секретного ключа secretkey.pem
+
Теперь настало время рассказать об одном из главных применений openssl - управление сертификатами. Openssl имеет возможность генерировать сертификаты, управлять ЭЦП и шифрацией с помощью сертификатов. Однако применение утилит управления сертификатами - достаточно сложная задача. Поэтому для начала я дам общие представления о сертификатах. Сертификат содержит публичный ключ, подписанный одним из корневых доверенных центров сертификации(или комплементарным секретным ключом), данные об организации, выдавшей сертификат и в некоторых случаях зашифрованный секретный ключ, а также отпечаток(хеш) публичного ключа. Сертификаты имеют время действия, по окончанию которого они автоматически считаются недействительными, иерархия сертификатов обычно строится на основании сети доверия (бывают довольно длинные цепочки сертификатов, ведущие к доверенному ключу из root CA). Таким образом, сертификат - это полный комплекс системы асимметрического шифрования, предоставляющий гораздо больше возможностей, чем сами по себе ключи(а также являющийся более защищённой системой). Основным привлекательным моментом сертификата является возможность записи в него информации об организации, этот ключ выдавшей. Таким образом явно напрашивается применение собственной системы сертификации в данной организации.  
−
 
 
−
Теперь настало время рассказать об одном из главных применений openssl -
 
−
управление сертификатами. Openssl имеет возможность генерировать сертификаты,
 
−
управлять ЭЦП и шифрацией с помощью сертификатов. Однако применение утилит
 
−
управления сертификатами - достаточно сложная задача. Поэтому для начала я дам
 
−
общие представления о сертификатах. Сертификат содержит публичный ключ,
 
−
подписанный одним из корневых доверенных центров сертификации(или
 
−
комплементарным секретным ключом), данные об организации, выдавшей сертификат и
 
−
в некоторых случаях зашифрованный секретный ключ, а также отпечаток(хеш)
 
−
публичного ключа. Сертификаты имеют время действия, по окончанию которого они  
 
−
автоматически считаются недействительными, иерархия сертификатов обычно строится
 
−
на основании сети доверия (бывают довольно длинные цепочки сертификатов,  
 
−
ведущие к доверенному ключу из root CA). Таким образом, сертификат -  
 
−
это полный комплекс системы асимметрического шифрования, предоставляющий гораздо
 
−
больше возможностей, чем сами по себе ключи(а также являющийся более защищённой
 
−
системой). Основным привлекательным моментом сертификата является возможность
 
−
записи в него информации об организации, этот ключ выдавшей. Таким образом явно
 
−
напрашивается применение собственной системы сертификации в данной организации.
 
−
 
 
−
Можно, например, выдавать сотрудникам их персональные сертификаты, подписанные
 
−
сертификатом организации(его можно сгенерировать самому или получить от
 
−
сторонней компании). Причём эти сертификаты впоследствие можно использовать для
 
−
удостоверения личности сотрудника, например, при почтовой переписке или
 
−
аутентификации на http сервере(apache+ssl). Единственное условие, которое должно
 
−
выполняться,- это наличие на машине клиента сертификата организации в списке
 
−
корневых доверенных ключей. Общее содержание сертификатов определено стандартом
 
−
x509, в то время как форматы записей сертификатов могут внести некоторую
 
−
путаницу. Openssl по умолчанию использует формат PKCS#10, Microsoft использует
 
−
по умолчанию формат PKCS#12(в руководстве по openssl этот формат
 
−
охарактеризован, как один большой баг :), формат PKCS#7 используется для
 
−
запросов на сертификацию к CA(центр сертификации )и не может содержать
 
−
секретного ключа, также для этой цели может использоваться DER закодированный
 
−
сертификат(DER кодирование подобно кодированию base64, но имеет специальное
 
−
назначение для использования в криптографических системах) также без секретного
 
−
ключа. Учтите, что при использовании DER формата убираются маркеры начала и
 
−
конца сертификата, а его содержимое кодируется base64, поэтому в файле DER можно
 
−
хранить только один сертификат, с другой стороны DER сертификаты поддерживаются
 
−
M$(стандартное расширение .cer), поэтому иногда бывает нужно преобразовать
 
−
сертификаты из одного формата в другой(я здесь имею ввиду PEM или DER):
 
  
−
        PEM-->DER openssl x509 -inform PEM -in cert.pem -outform DER -out cert.cer
+
Можно, например, выдавать сотрудникам их персональные сертификаты, подписанные сертификатом организации(его можно сгенерировать самому или получить от сторонней компании). Причём эти сертификаты впоследствие можно использовать для удостоверения личности сотрудника, например, при почтовой переписке или аутентификации на http сервере(apache+ssl). Единственное условие, которое должно выполняться,- это наличие на машине клиента сертификата организации в списке корневых доверенных ключей. Общее содержание сертификатов определено стандартом x509, в то время как форматы записей сертификатов могут внести некоторую путаницу. Openssl по умолчанию использует формат PKCS#10, Microsoft использует по умолчанию формат PKCS#12(в руководстве по openssl этот формат охарактеризован, как один большой баг&nbsp;:), формат PKCS#7 используется для запросов на сертификацию к CA(центр сертификации )и не может содержать секретного ключа, также для этой цели может использоваться DER закодированный сертификат(DER кодирование подобно кодированию base64, но имеет специальное назначение для использования в криптографических системах) также без секретного ключа. Учтите, что при использовании DER формата убираются маркеры начала и конца сертификата, а его содержимое кодируется base64, поэтому в файле DER можно хранить только один сертификат, с другой стороны DER сертификаты поддерживаются M$(стандартное расширение .cer), поэтому иногда бывает нужно преобразовать сертификаты из одного формата в другой(я здесь имею ввиду PEM или DER):
−
        DER-->PEM openssl x509 -inform DER -in cert.cer -outform PEM -out cert.pem
 
  
 +
        PEM--&gt;DER openssl x509 -inform PEM -in cert.pem -outform DER -out cert.cer
 +
        DER--&gt;PEM openssl x509 -inform DER -in cert.cer -outform PEM -out cert.pem
  
−
Таким же образом можно конвертировать и ключи асимметрического
+
<br> Таким же образом можно конвертировать и ключи асимметрического шифрования(используя утилиты rsa или dsa).  
−
шифрования(используя утилиты rsa или dsa).
 
  
−
Думаю, что не сильно запутал вас всеми этими стандартами. Если объяснять
+
Думаю, что не сильно запутал вас всеми этими стандартами. Если объяснять на пальцах, то всё выглядит следующим образом: клиент создаёт сертификат и отправляет свой публичный сертификат(PKCS#7) в центр сертификации. В центре сертификации обрабатывается запрос клиента(запрос на сертификацию), и сертификат клиента подписывается секретным ключом центра сертификации. Клиент, имея публичный ключ центра сертификации, проверяет подлинность подписи и может далее использовать свой сертификат. Для организации можно предложить следующее решение: на сервере создаётся сертификат организации; генерируется запрос на сертификацию и отправляется к некоему доверенному центру сертификации(который будет известен всем клиентам и персоналу данной организации); получается сертификат организации, который можно использовать при создании сертификатов клиентов. Последние создаются так: клиент посылает запрос на выдачу сертификата; сервер создаёт сертификат клиента и подписывает его сертификатом организации; клиент получает сертификат клиента и сертификат организации; после проверки достоверности ключа организации(предполагается, что клиент доверяет CA, которым был подписан сертификат организации) проверяется достоверность сертификата клиента. После такой операции клиент будет точно уверен, что получил сертификат от данной организации, и может его использовать для работы с ней. По такой схеме построены все центры выдачи сертификатов(правда зачастую сертификат организации бывает подписан самим собой, что требует от клиента добавить сертификат организации к доверенным, а в первой схеме сертификат организации принадлежит к группе промежуточных центров сертификации, и этот случай предпочтительнее с точки зрения безопасности и удобства клиента, но требует больше работы от администратора). Да, хорошенькое объяснение на пальцах! Но что тут поделать: сертификаты - это довольно запутанная вещь. Сейчас я объясню, как создавать сертификаты с помощью openssl, и приведу пример только что описанного безобразия...  
−
на пальцах, то всё выглядит следующим образом: клиент создаёт сертификат и
 
−
отправляет свой публичный сертификат(PKCS#7) в центр сертификации. В центре
 
−
сертификации обрабатывается запрос клиента(запрос на сертификацию), и сертификат
 
−
клиента подписывается секретным ключом центра сертификации. Клиент, имея
 
−
публичный ключ центра сертификации, проверяет подлинность подписи и может далее
 
−
использовать свой сертификат. Для организации можно предложить следующее
 
−
решение: на сервере создаётся сертификат организации; генерируется запрос на
 
−
сертификацию и отправляется к некоему доверенному центру сертификации(который
 
−
будет известен всем клиентам и персоналу данной организации); получается
 
−
сертификат организации, который можно использовать при создании сертификатов
 
−
клиентов. Последние создаются так: клиент посылает запрос на выдачу сертификата;
 
−
сервер создаёт сертификат клиента и подписывает его сертификатом организации;
 
−
клиент получает сертификат клиента и сертификат организации; после проверки
 
−
достоверности ключа организации(предполагается, что клиент доверяет CA, которым
 
−
был подписан сертификат организации) проверяется достоверность сертификата
 
−
клиента. После такой операции клиент будет точно уверен, что получил сертификат
 
−
от данной организации, и может его использовать для работы с ней. По такой схеме
 
−
построены все центры выдачи сертификатов(правда зачастую сертификат организации
 
−
бывает подписан самим собой, что требует от клиента добавить сертификат
 
−
организации к доверенным, а в первой схеме сертификат организации принадлежит к
 
−
группе промежуточных центров сертификации, и этот случай предпочтительнее с
 
−
точки зрения безопасности и удобства клиента, но требует больше работы от
 
−
администратора). Да, хорошенькое объяснение на пальцах! Но что тут поделать:
 
−
сертификаты - это довольно запутанная вещь. Сейчас я объясню, как создавать
 
−
сертификаты с помощью openssl, и приведу пример только что описанного
 
−
безобразия...
 
  
−
Для создания сертификата используется инструмент openssl req. Он имеет довольно
+
Для создания сертификата используется инструмент openssl req. Он имеет довольно много параметров, поэтому, чтобы не парить мозги, я просто приведу пару примеров его использования. Для начала требуется конфигурационный файл, который имеет следующий формат(все строки, начинающиеся с # - это мои комментарии, в конечном файле их может и не быть):  
−
много параметров, поэтому, чтобы не парить мозги, я просто приведу пару примеров
 
−
его использования. Для начала требуется конфигурационный файл, который имеет
 
−
следующий формат(все строки, начинающиеся с # - это мои комментарии, в конечном
 
−
файле их может и не быть):
 
  
 
         [ req ]
 
         [ req ]
Рядок 416: Рядок 242:
 
   
 
   
 
   
 
   
−
Если не указывать prompt no, то значения для параметров будут считаны в
 
−
интерактивном режиме(то бишь с клавиатуры), а значения параметров будут являться
 
−
подсказками при вводе данных. При интерактивном режиме можно указывать значения
 
−
по умолчанию, а также минимальное и максимальное значения для параметров(для
 
−
строковых параметров устанавливается ограничение на длину). В таком случае общий
 
−
формат параметра таков:
 
  
−
имя = подсказка
+
Если не указывать prompt no, то значения для параметров будут считаны в интерактивном режиме(то бишь с клавиатуры), а значения параметров будут являться подсказками при вводе данных. При интерактивном режиме можно указывать значения по умолчанию, а также минимальное и максимальное значения для параметров(для строковых параметров устанавливается ограничение на длину). В таком случае общий формат параметра таков:
−
имя_default = значение_по_умолчанию
 
−
имя_max = максимум
 
−
имя_min = минимум
 
  
−
Пример интерактивного файла конфигурации:
+
имя = подсказка имя_default = значение_по_умолчанию имя_max = максимум имя_min = минимум
 +
 
 +
Пример интерактивного файла конфигурации:  
  
 
         [ req ]
 
         [ req ]
Рядок 451: Рядок 270:
 
         emailAddress_max       = 40
 
         emailAddress_max       = 40
  
−
 
+
<br> Спешу обрадовать некоторых ленивых товарищей: если вы намереваетесь создавать просто сертификат сервера(например, для LDAP сервера), то указывать конфиг необязательно, будет использоваться конфиг по умолчанию /usr/lib/ssl/openssl.cnf, который содержит всё необходимое. Ну а теперь традиционно приведу примеры использования openssl req(я не собираюсь подробно описывать данную команду, т.к. думаю, что для большинства случаев хватит примеров, а для особых случаев можно почитать man req).  
−
Спешу обрадовать некоторых ленивых товарищей: если вы намереваетесь создавать
 
−
просто сертификат сервера(например, для LDAP сервера), то указывать конфиг
 
−
необязательно, будет использоваться конфиг по умолчанию /usr/lib/ssl/openssl.cnf,  
 
−
который содержит всё необходимое. Ну а теперь традиционно приведу примеры
 
−
использования openssl req(я не собираюсь подробно описывать данную команду, т.к.
 
−
думаю, что для большинства случаев хватит примеров, а для особых случаев можно
 
−
почитать man req).
 
  
 
         openssl req -new -newkey rsa:2048 -keyout rsa_key.pem -config cfg -out certreq.pem
 
         openssl req -new -newkey rsa:2048 -keyout rsa_key.pem -config cfg -out certreq.pem
  
 +
<br> Создание запроса на сертификацию(-new) на основе создаваемого секретного ключа rsa(-newkey rsa:2048), который записывается в файл -keyout(и шифруется тройным DES). Запрос на сертификацию создаётся на основе конфигурационного файла-config.
  
−
Создание запроса на сертификацию(-new) на основе создаваемого секретного ключа
+
openssl req -x509 -new -key private_key.pem -config cfg -out selfcert.pem -days 365 Создание(-new) self-signed сертификата(-x509) для использования в качестве сертификата сервера или сертификата CA. Сертификат создаётся с использованием секретного ключа -key и конфигурационного файла -config. Создаваемый сертификат будет действителен в течение 365 дней(-days), опция -days не применима к запросам на сертификацию.  
−
rsa(-newkey rsa:2048), который записывается в файл -keyout(и шифруется тройным
 
−
DES). Запрос на сертификацию создаётся на основе конфигурационного файла-config.
 
  
−
openssl req -x509 -new -key private_key.pem -config cfg -out selfcert.pem -days 365
+
Для управления сертификатами x509 используется утилита openssl x509. С её помощью можно подписать сертификат или запрос на сертификацию сертификатом CA. Также можно просмотреть содержимое сертификата в читаемой форме(DN, публичный ключ, время действия, отпечаток и.т.д.). Приведу примеры вышеописанных действий:
−
Создание(-new) self-signed сертификата(-x509) для использования в качестве
 
−
сертификата сервера или сертификата CA. Сертификат создаётся с использованием
 
−
секретного ключа -key и конфигурационного файла -config. Создаваемый сертификат
 
−
будет действителен в течение 365 дней(-days), опция -days не применима к
 
−
запросам на сертификацию.
 
  
−
Для управления сертификатами x509 используется утилита openssl x509. С её
+
openssl x509 -in cert.pem -noout -text Просмотреть информацию о сертификате в "нормальной" форме. Вот что примерно будет выведено, также можно использовать дополнительные опции: -fingerprint (необходимо сочетать с одной из опций -sha1, -md5 или -mdc2), -modulus (вывод публичного ключа), -serial, -subject, -issuer(организация, выдавшая сертификат), -email, -startdate, -enddate:  
−
помощью можно подписать сертификат или запрос на сертификацию сертификатом CA.
 
−
Также можно просмотреть содержимое сертификата в читаемой форме(DN, публичный
 
−
ключ, время действия, отпечаток и.т.д.). Приведу примеры вышеописанных действий:
 
−
 
 
−
openssl x509 -in cert.pem -noout -text
 
−
Просмотреть информацию о сертификате в "нормальной" форме. Вот что примерно
 
−
будет выведено, также можно использовать дополнительные опции: -fingerprint
 
−
(необходимо сочетать с одной из опций -sha1, -md5 или -mdc2), -modulus
 
−
(вывод публичного ключа), -serial, -subject, -issuer(организация, выдавшая  
 
−
сертификат), -email, -startdate, -enddate:
 
  
 
         Certificate:
 
         Certificate:
Рядок 495: Рядок 291:
 
                 Validity
 
                 Validity
 
                     Not Before: Nov  9 08:51:03 2002 GMT
 
                     Not Before: Nov  9 08:51:03 2002 GMT
−
                     Not After : Nov  9 08:51:03 2003 GMT
+
                     Not After&nbsp;: Nov  9 08:51:03 2003 GMT
 
                 Subject: C=RU, ST=region, L=city, O=organization, OU=Sysopka,
 
                 Subject: C=RU, ST=region, L=city, O=organization, OU=Sysopka,
 
         CN=CEBKA/[email protected]  
 
         CN=CEBKA/[email protected]  
Рядок 526: Рядок 322:
 
             -CAcreateserial -out clientcert.pem
 
             -CAcreateserial -out clientcert.pem
  
−
 
+
<br> Подписать запрос на сертификацию(-req) файла -in, используя доверенный CA сертификат -CA и его секретный ключ -CAkey. В конечный сертификат клиента(-out), записываются дополнительные параметры сертификата 3-й версии из файла /usr/lib/ssl/openssl.cnf(конфигурационный файл по умолчанию). Но об этом я расскажу после на конкретном примере. Такое поведение x509 позволяет организовать свой центр сертификации, подписывающий запросы клиентов на сертификацию.  
−
Подписать запрос на сертификацию(-req) файла -in, используя доверенный CA
 
−
сертификат -CA и его секретный ключ -CAkey. В конечный сертификат клиента(-out),
 
−
записываются дополнительные параметры сертификата 3-й версии из файла
 
−
/usr/lib/ssl/openssl.cnf(конфигурационный файл по умолчанию). Но об этом я
 
−
расскажу после на конкретном примере. Такое поведение x509 позволяет
 
−
организовать свой центр сертификации, подписывающий запросы клиентов на
 
−
сертификацию.  
 
  
 
         openssl x509 -in CAcert.pem -addtrust sslclient -alias "myorganization CA" \
 
         openssl x509 -in CAcert.pem -addtrust sslclient -alias "myorganization CA" \
 
             -out CAtrust.pem
 
             -out CAtrust.pem
  
 +
<br> Преобразование сертификата -in в доверенный сертификат для использования в SSL клиентах(sslserver - использование в качестве сертификата сервера, emailProtection - использование в качестве сертификата S/MIME).
  
−
Преобразование сертификата -in в доверенный сертификат для использования в SSL
+
Я ещё раз хотел бы вернуться к проблеме построения CA. Для использования внутри организации можно использовать self-signed сертификат, но для использования CA вне организации приходится использовать сертификаты, выданные или подписанные сторонней организацией. Во втором случае возникает проблема выбора такой сторонней организации(она легко разрешается для дочерних компаний), которая требует юридического анализа(в разных странах существуют свои законы криптографии и поэтому дать какой-либо конкретный совет я не могу). Если вам довелось работать в российской правительственной компании, то считайте, что вам не повезло - использовать openssl для работы с правительственными организациями нельзя. Наши уважаемые гос. деятели добавили геморроя админам, разрешив использовать только алгоритмы ГОСТ(симметрические, асимметрические, хеширования - меня просто выворачивает от самого этого слова ГОСТ&nbsp;;), поэтому использовать вам придётся только специальные программы, реализующие эти алгоритмы. Я же приведу здесь пример построение собственного CA с self-signed сертификатом:
−
клиентах(sslserver - использование в качестве сертификата сервера,
 
−
emailProtection - использование в качестве сертификата S/MIME).
 
  
−
Я ещё раз хотел бы вернуться к проблеме построения CA. Для использования внутри
+
1) Генерируем секретный ключ:  
−
организации можно использовать self-signed сертификат, но для использования CA
 
−
вне организации приходится использовать сертификаты, выданные или подписанные
 
−
сторонней организацией. Во втором случае возникает проблема выбора такой
 
−
сторонней организации(она легко разрешается для дочерних компаний), которая
 
−
требует юридического анализа(в разных странах существуют свои законы
 
−
криптографии и поэтому дать какой-либо конкретный совет я не могу). Если вам
 
−
довелось работать в российской правительственной компании, то считайте, что вам
 
−
не повезло - использовать openssl для работы с правительственными организациями
 
−
нельзя. Наши уважаемые гос. деятели добавили геморроя админам, разрешив
 
−
использовать только алгоритмы ГОСТ(симметрические, асимметрические, хеширования
 
−
- меня просто выворачивает от самого этого слова ГОСТ ;), поэтому использовать
 
−
вам придётся только специальные программы, реализующие эти алгоритмы. Я же
 
−
приведу здесь пример построение собственного CA с self-signed сертификатом:
 
−
 
 
−
1) Генерируем секретный ключ:
 
  
 
         openssl genrsa -out CAkey.pem -rand randfile -des3 4096
 
         openssl genrsa -out CAkey.pem -rand randfile -des3 4096
  
−
 
+
<br> 2) Создаём self-signed сертификат:  
−
2) Создаём self-signed сертификат:
 
  
 
         openssl req -new -x509 -key CAkey.pem -out CAcert.pem -days 365 -config cfg
 
         openssl req -new -x509 -key CAkey.pem -out CAcert.pem -days 365 -config cfg
  
 +
<br> Содержимое конфигурационного файла зависит от организации, можно даже воспользоваться утилитой /usr/lib/ssl/misc/CA.pl -newcert, которая создаст ключ и сертификат в одном файле в интерактивном режиме(хотя мне этот вариант не очень понравился, лучше один раз написать нормальный конфиг) - о дополнительных требованиях к конфигурации CA сертификата см. ниже.
  
−
Содержимое конфигурационного файла зависит от организации, можно даже
+
3) Приведу пример скрипта, генерирующего клиентские сертификаты:
−
воспользоваться утилитой /usr/lib/ssl/misc/CA.pl -newcert, которая создаст ключ
 
−
и сертификат в одном файле в интерактивном режиме(хотя мне этот вариант не очень
 
−
понравился, лучше один раз написать нормальный конфиг) - о дополнительных
 
−
требованиях к конфигурации CA сертификата см. ниже.
 
  
−
3) Приведу пример скрипта, генерирующего клиентские сертификаты:
+
<br>
  
 +
#!/bin/bash
 +
 +
dd if=/dev/random of=/tmp/.rnd count=64
 +
RAND="/var/log/messages:/boot/vmlinuz:/tmp/.rnd"
 +
REQ="openssl req"
 +
X509="openssl x509"
 +
RSA="openssl rsa"
 +
GENRSA="openssl genrsa"
 +
O="company"
 +
C="RU"
 +
ST="region"
 +
L="city"
 +
PURPOSES="digitalSignature, keyEncipherment"
 +
CERTTYPE="client, email, objsign"
 +
CA="/etc/openssl/CAcert.pem"
 +
CAkey="/etc/openssl/CAkey.pem"
 +
OUTDIR="/etc/openssl/clientcert/"
 +
CN="client"
 +
BITS=2048
 +
DAYS=365
  
−
#!/bin/bash
+
#Создаём секретный ключ во временной папке БЕЗ шифрования
 +
TMP="/tmp/ssl-$$"
 +
mkdir $TMP
 +
 +
if [&nbsp;! -d $OUTDIR ];then
 +
        mkdir $OUTDIR
 +
fi
  
−
dd if=/dev/random of=/tmp/.rnd count=64
+
pushd $TMP &gt; /dev/null
−
RAND="/var/log/messages:/boot/vmlinuz:/tmp/.rnd"
+
$GENRSA -rand $RAND -out tmp.key $BITS
−
REQ="openssl req"
 
−
X509="openssl x509"
 
−
RSA="openssl rsa"
 
−
GENRSA="openssl genrsa"
 
−
O="company"
 
−
C="RU"
 
−
ST="region"
 
−
L="city"
 
−
PURPOSES="digitalSignature, keyEncipherment"
 
−
CERTTYPE="client, email, objsign"
 
−
CA="/etc/openssl/CAcert.pem"
 
−
CAkey="/etc/openssl/CAkey.pem"
 
−
OUTDIR="/etc/openssl/clientcert/"
 
−
CN="client"
 
−
BITS=2048
 
−
DAYS=365
 
  
−
#Создаём секретный ключ во временной папке БЕЗ шифрования
+
# Создаём конфиг для клиента
−
TMP="/tmp/ssl-$$"
+
cat &gt; cfg &lt;&lt;EOT
−
mkdir $TMP
+
[ req ]
 +
default_bits                    = $BITS
 +
distinguished_name              = req_DN
 +
extensions = v3_req
 +
[ req_DN ]
 +
countryName                    = "1. Country Name            (2 letter code)"
 +
countryName_default            = "$C"
 +
countryName_min                = 2
 +
countryName_max                = 2
 +
stateOrProvinceName            = "2. State or Province Name  (full name)    "
 +
stateOrProvinceName_default    = "$ST"
 +
localityName                    = "3. Locality Name            (eg, city)    "
 +
localityName_default            = "$L"
 +
0.organizationName              = "4. Organization Name        (eg, company)  "
 +
0.organizationName_default      = "$O"
 +
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
 +
organizationalUnitName_default  = "$OU"
 +
commonName                      = "6. Common Name              (eg, CA name)  "
 +
commonName_max                  = 64
 +
commonName_default              = "$CN"
 +
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
 +
emailAddress_max                = 40
 +
emailAddress_default            = ""
 +
[ v3_req ]
 +
basicConstraints = CA:FALSE
 +
keyUsage = $PURPOSES
 +
nsCertType = $CERTTYPE
 +
EOT
 +
# Создаём запрос на сертификацию
 +
$REQ -new -key tmp.key -config cfg -rand $RAND -out $CN.pem
  
−
if [ ! -d $OUTDIR ];then
+
  # Этот файл лучше удалить побыстрее: мало ли чего...
−
        mkdir $OUTDIR
+
rm -fr /tmp/.rnd
−
fi
+
−
 
+
if [ $? -ne 0 ]; then
−
pushd $TMP > /dev/null
+
        echo "Failed to make a certificate due to error: $?"
−
$GENRSA -rand $RAND -out tmp.key $BITS
+
        popd &gt; /dev/null
−
 
+
        rm -fr $TMP
−
# Создаём конфиг для клиента
+
        exit $?
−
cat > cfg <<EOT
+
fi
−
[ req ]
+
# Подписываем сертификат сертификатом сервера
−
default_bits                    = $BITS
+
−
distinguished_name              = req_DN
+
$X509 -req -in $CN.pem -CA $CA -CAkey $CAkey -CAsetserial \
−
extensions = v3_req
 
−
[ req_DN ]
 
−
countryName                    = "1. Country Name            (2 letter code)"
 
−
countryName_default            = "$C"
 
−
countryName_min                = 2
 
−
countryName_max                = 2
 
−
stateOrProvinceName            = "2. State or Province Name  (full name)    "
 
−
stateOrProvinceName_default    = "$ST"
 
−
localityName                    = "3. Locality Name            (eg, city)    "
 
−
localityName_default            = "$L"
 
−
0.organizationName              = "4. Organization Name        (eg, company)  "
 
−
0.organizationName_default      = "$O"
 
−
organizationalUnitName          = "5. Organizational Unit Name (eg, section) "
 
−
organizationalUnitName_default  = "$OU"
 
−
commonName                      = "6. Common Name              (eg, CA name)  "
 
−
commonName_max                  = 64
 
−
commonName_default              = "$CN"
 
−
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
 
−
emailAddress_max                = 40
 
−
emailAddress_default            = ""
 
−
[ v3_req ]
 
−
basicConstraints = CA:FALSE
 
−
keyUsage = $PURPOSES
 
−
nsCertType = $CERTTYPE
 
−
EOT
 
−
# Создаём запрос на сертификацию
 
−
$REQ -new -key tmp.key -config cfg -rand $RAND -out $CN.pem
 
−
 
 
−
# Этот файл лучше удалить побыстрее: мало ли чего...
 
−
rm -fr /tmp/.rnd
 
−
 
 
−
if [ $? -ne 0 ]; then
 
−
        echo "Failed to make a certificate due to error: $?"
 
−
        popd > /dev/null
 
−
        rm -fr $TMP
 
−
        exit $?
 
−
fi
 
−
# Подписываем сертификат сертификатом сервера
 
−
 
 
−
$X509 -req -in $CN.pem -CA $CA -CAkey $CAkey -CAsetserial \
 
 
       -extensions -config cfg -days $DAYS -out $OUTDIR$CN.pem  
 
       -extensions -config cfg -days $DAYS -out $OUTDIR$CN.pem  
 +
 +
chmod 0400 $OUTDIR$CN.pem
 +
chown root:root $OUTDIR$CN.pem
 +
# Шифруем секретный ключ
 +
$RSA -in tmp.key -des3 -out $OUTDIR$CN-key.pem
 +
 +
chmod 0400 $OUTDIR$CN-key.pem
 +
chown root:root $OUTDIR$CN-key.pem
 +
# Выполняем заключительные действия
 +
popd &gt; /dev/null
 +
 +
rm -fr $TMP
  
−
chmod 0400 $OUTDIR$CN.pem
+
echo -e "Generation complete, go to $OUTDIR and give to client $CN his certificate and \
−
chown root:root $OUTDIR$CN.pem
+
\n private key(for windows users you should use openssl pkcs12 utility)"
−
# Шифруем секретный ключ
 
−
$RSA -in tmp.key -des3 -out $OUTDIR$CN-key.pem
 
  
−
chmod 0400 $OUTDIR$CN-key.pem
+
<br>  
−
chown root:root $OUTDIR$CN-key.pem
 
−
# Выполняем заключительные действия
 
−
popd > /dev/null
 
  
−
rm -fr $TMP
+
<br> Дополнительные свойства, описанные в скрипте (v3_req) означают, что клиент может использовать сертификат для подписывания и шифрации, но его сертификат не является CA сертификатом. Для CA сертификата значение basicConstraits должно быть равно CA:TRUE(об этом забывать нельзя!). Поле nsCertType определяет дополнительные назначения данного ключа(для использования в качестве клиента, подписывания, использования в почтовых сообщениях). Для CA сертификатов обычно применяют следующие значения nsCertType: sslCA, emailCA. Для ssl ключей серверов(например, апача) используется значение nsCertType = server.
  
−
echo -e "Generation complete, go to $OUTDIR and give to client $CN his certificate and \
+
Полученный таким образом сертификат клиента будет содержать информацию о поставщике сертификата (то есть о вашем сертификате организации). Клиенту необходимо будет передать его сертификат, его секретный ключ(зашифрованный!) и ваш сертификат организации. Для клиентов Micro$oft необходимо ещё и перевести сертификаты в формат PKCS#12. Для этого воспользуемся командой openssl pkcs12:  
−
\n private key(for windows users you should use openssl pkcs12 utility)"
 
−
 
 
−
 
 
−
 
 
−
 
 
−
Дополнительные свойства, описанные в скрипте (v3_req) означают, что клиент может
 
−
использовать сертификат для подписывания и шифрации, но его сертификат не
 
−
является CA сертификатом. Для CA сертификата значение basicConstraits должно быть равно
 
−
CA:TRUE(об этом забывать нельзя!). Поле nsCertType определяет дополнительные
 
−
назначения данного ключа(для использования в качестве клиента, подписывания, использования в
 
−
почтовых сообщениях). Для CA сертификатов обычно применяют следующие значения nsCertType: sslCA,
 
−
emailCA. Для ssl ключей серверов(например, апача) используется значение nsCertType = server.
 
−
 
 
−
Полученный таким образом сертификат клиента будет содержать информацию о поставщике сертификата
 
−
(то есть о вашем сертификате организации). Клиенту необходимо будет передать
 
−
его сертификат, его секретный ключ(зашифрованный!) и ваш сертификат организации.
 
−
Для клиентов Micro$oft необходимо ещё и перевести сертификаты в формат PKCS#12.
 
−
Для этого воспользуемся командой openssl pkcs12:
 
  
 
         openssl pkcs12 -export -in client.pem -inkey client-key.pem -out client.p12 \
 
         openssl pkcs12 -export -in client.pem -inkey client-key.pem -out client.p12 \
 
               -name "Client certificate from our organization"
 
               -name "Client certificate from our organization"
  
−
 
+
<br> Для обратного преобразования используется синтаксис:  
−
Для обратного преобразования используется синтаксис:
 
  
 
         openssl pkcs12 -in client.p12 -out client.pem
 
         openssl pkcs12 -in client.p12 -out client.pem
  
 +
<br> В выходной файл записываются сертификат клиента, ca сертификат, секретный ключ клиента(его можно зашифровать опцией -des3, -idea и.т.д.). Такое поведение позволяет использовать для вывода только формат pem(маркеры здесь обязательны!). Для экспорта сертификата организации можно воспользоваться командой pkcs12( конечно же без параметра inkey&nbsp;;), можно также обработать сертификат организации base64 и сохранить в файле .cer(openssl x509 -in CA.pem -outform DER -out CA.cer).
  
−
В выходной файл записываются сертификат клиента, ca сертификат, секретный ключ
+
В openssl существует компонент управления s/mime сообщениями, называющийся openssl smime. Данная утилита позволяет зашифровывать, расшифровывать, управлять ЭЦП и MIME заголовками писем. Приведу опять же несколько примеров её использования:  
−
клиента(его можно зашифровать опцией -des3, -idea и.т.д.). Такое поведение
 
−
позволяет использовать для вывода только формат pem(маркеры здесь обязательны!).
 
−
Для экспорта сертификата организации можно воспользоваться командой pkcs12(
 
−
конечно же без параметра inkey ;), можно также обработать сертификат организации
 
−
base64 и сохранить в файле .cer(openssl x509 -in CA.pem -outform DER -out CA.cer).
 
−
 
 
−
В openssl существует компонент управления s/mime сообщениями, называющийся
 
−
openssl smime. Данная утилита позволяет зашифровывать, расшифровывать, управлять
 
−
ЭЦП и MIME заголовками писем. Приведу опять же несколько примеров её
 
−
использования:
 
  
 
         openssl smime -sign -in mail.txt -text -from [email protected] -to \
 
         openssl smime -sign -in mail.txt -text -from [email protected] -to \
Рядок 713: Рядок 460:
 
               private_key.pem | sendmail [email protected]
 
               private_key.pem | sendmail [email protected]
  
−
 
+
<br> Подписывает сообщение -in(в текстовом виде) и подписывает(-sign) его с помощью сертификата(-signer) и секретного ключа(-inkey). Вывод идёт непосредственно к sendmail, для этого определены MIME заголовки from, to и subject.  
−
Подписывает сообщение -in(в текстовом виде) и подписывает(-sign) его с помощью
 
−
сертификата(-signer) и секретного ключа(-inkey). Вывод идёт непосредственно к
 
−
sendmail, для этого определены MIME заголовки from, to и subject.
 
  
 
         openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt
 
         openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt
  
−
 
+
<br> Проверяет подпись в файле -in, записывает сообщение в файл -out, а полученный сертификат - в файл -signer(для проверки s/mime сообщения не требуется ничего, кроме него самого, т.к. ЭЦП s/mime содержит публичный ключ!).  
−
Проверяет подпись в файле -in, записывает сообщение в файл -out, а полученный
 
−
сертификат - в файл -signer(для проверки s/mime сообщения не требуется ничего,
 
−
кроме него самого, т.к. ЭЦП s/mime содержит публичный ключ!).
 
  
 
         openssl smime -encrypt -in mail.txt -from [email protected] -to [email protected] \
 
         openssl smime -encrypt -in mail.txt -from [email protected] -to [email protected] \
Рядок 729: Рядок 470:
 
               [email protected]
 
               [email protected]
  
−
 
+
<br> Шифрация файла -in с помощью сертификата получателя user.pem, используя алгоритм des3. Вывод программы посылается непосредственно в sendmail.  
−
Шифрация файла -in с помощью сертификата получателя user.pem, используя алгоритм
 
−
des3. Вывод программы посылается непосредственно в sendmail.
 
  
 
         openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey private_key.pem \
 
         openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey private_key.pem \
 
               -out mail.txt
 
               -out mail.txt
  
 +
<br> Расшифровка файла -in с помощью секретного ключа -inkey и сертификата -recip(ваш собственный сертификат).
  
−
Расшифровка файла -in с помощью секретного ключа -inkey и сертификата
+
Есть альтернатива не указывать smime заголовки from, to и subject. Можно просто указать необходимый файл -out и добавить заголовки с помощью программы sendmail вручную. Кроме этого, есть ещё одна деталь использования smime: некоторые почтовые клиенты используют в качестве подписи вложение в формате PKCS#7(чаще всего закодированное base64). В таком случае необходимо применять smime следующим образом:  
−
-recip(ваш собственный сертификат).
 
−
 
 
−
Есть альтернатива не указывать smime заголовки from, to и subject. Можно просто
 
−
указать необходимый файл -out и добавить заголовки с помощью программы sendmail
 
−
вручную. Кроме этого, есть ещё одна деталь использования smime: некоторые
 
−
почтовые клиенты используют в качестве подписи вложение в формате PKCS#7(чаще
 
−
всего закодированное base64). В таком случае необходимо применять smime
 
−
следующим образом:
 
  
 
         openssl smime -verify -inform [PEM | DER] -in signature.pem[der] -content \
 
         openssl smime -verify -inform [PEM | DER] -in signature.pem[der] -content \
 
               mail.txt
 
               mail.txt
  
 +
<br> PEM используется для стандартного формата PKCS#7, а DER заставляет произвести дополнительную обработку base64. Учтите, что в данном случае файл -in представляет собой только подпись(аттачмент), а -content - непосредственно текст письма. Можно также заставить smime подписывать сообщения подобным образом, если указать опцию -pk7out (PEM формат). Для преобразования PKCS#7 структуры из формата PEM в формат DER можно воспользоваться утилитой openssl base64(обратное преобразование достигается за счёт использования опции -d).
  
−
PEM используется для стандартного формата PKCS#7, а DER заставляет произвести
+
Итак, думаю, что для большинства операций с использованием SSL этого будет достаточно.  
−
дополнительную обработку base64. Учтите, что в данном случае файл -in
 
−
представляет собой только подпись(аттачмент), а -content - непосредственно текст
 
−
письма.  Можно также заставить smime подписывать сообщения подобным образом,
 
−
если указать опцию -pk7out (PEM формат). Для преобразования PKCS#7 структуры из
 
−
формата PEM в формат DER можно воспользоваться утилитой openssl base64(обратное
 
−
преобразование достигается за счёт использования опции -d).
 
  
−
Итак, думаю, что для большинства операций с использованием SSL этого будет
+
Openssl применяется во множестве сетевых серверов. В данной статье я бы хотел рассказать о работе с ssl апача, постфикса и курьера. Соответственно происходит шифрация трафика http, smtp и imap(pop3) протоколов. При использовании шифрации ssl обычно меняется порт, чтобы клиент мог корректно определить использование безопасного соединения. Для начала я расскажу об использовании ssl в апаче.  
−
достаточно.
 
  
−
Openssl применяется во множестве сетевых серверов. В данной статье я бы хотел
+
Апач может работать с ssl через модуль mod_ssl, который может быть скачан с www.apache-ssl.org. Для компиляции апача с данным модулем выполняем следующее:  
−
рассказать о работе с ssl апача, постфикса и курьера. Соответственно
 
−
происходит шифрация трафика http, smtp и imap(pop3) протоколов. При использовании
 
−
шифрации ssl обычно меняется порт, чтобы клиент мог корректно определить
 
−
использование безопасного соединения. Для начала я расскажу об использовании ssl
 
−
в апаче.
 
−
 
 
−
Апач может работать с ssl через модуль mod_ssl, который может быть скачан с
 
−
www.apache-ssl.org. Для компиляции апача с данным модулем выполняем следующее:  
 
  
 
         $ cd /usr/src/apache_1.3.x/src
 
         $ cd /usr/src/apache_1.3.x/src
 
         $ SSL_BASE=/usr/src/mod_ssl/ ./configure --... --enable-module=ssl
 
         $ SSL_BASE=/usr/src/mod_ssl/ ./configure --... --enable-module=ssl
  
 +
<br> После успешной компиляции необходимо получить сертификат организации. Тут есть два пути: первый - это создать self-signed сертификат, второй - получить сертификат от trusted root CA. Скорее всего, второй вариант будет небесплатный, например, на www.thawte.com предлагают продать сертификат www сервера за 160$ сроком действия на год. С другой стороны такой способ обеспечивает полную безопасность клиента, т.к. он будет знать, что сертификат действителен. Обычно у браузеров есть набор trusted root CA, и, когда браузер получает сертификат, подписанный одним из trusted ca, то он может корректно проверить подпись и решить на её основании о действительности сертификата www сервера. Если же браузер получает self-signed сертификат, то он спрашивает у пользователя, можно ли доверять этому сертификату, т.к. в этом случае клиент не может точно определить, откуда к нему пришёл этот сертификат и не может проверить его подпись, т.к. она не входит в его trusted root ca. В качестве альтернативного варианта, если вы работаете с несколькими крупными клиентами, можно посоветовать принести каждому клиенту свой сертификат(например, на дискетке или компакте&nbsp;:) и вручную добавить его в trusted root CA клиента. Для работы через ssl в локальной сети обычно используются self-signed сертификаты, что естественно. Сертификат сервера обычно подписывается сертификатом организации.
  
−
После успешной компиляции необходимо получить сертификат организации. Тут есть два
+
Итак, сгенерируем секретный ключ RSA и self-signed сертификат организации:  
−
пути: первый - это создать self-signed сертификат, второй - получить сертификат
 
−
от trusted root CA. Скорее всего, второй вариант будет небесплатный, например, на
 
−
www.thawte.com предлагают продать сертификат www сервера за 160$ сроком действия
 
−
на год. С другой стороны такой способ обеспечивает полную безопасность клиента,
 
−
т.к. он будет знать, что сертификат действителен. Обычно у браузеров есть набор
 
−
trusted root CA, и, когда браузер получает сертификат, подписанный одним из
 
−
trusted ca, то он может корректно проверить подпись и решить на её основании о
 
−
действительности сертификата www сервера. Если же браузер получает self-signed
 
−
сертификат, то он спрашивает у пользователя, можно ли доверять этому
 
−
сертификату, т.к. в этом случае клиент не может точно определить, откуда к нему
 
−
пришёл этот сертификат и не может проверить его подпись, т.к. она не входит в
 
−
его trusted root ca.  В качестве альтернативного варианта, если вы работаете с
 
−
несколькими крупными клиентами, можно посоветовать принести каждому клиенту свой
 
−
сертификат(например, на дискетке или компакте :) и вручную добавить его в
 
−
trusted root CA клиента. Для работы через ssl в локальной сети обычно
 
−
используются self-signed сертификаты, что естественно. Сертификат сервера обычно
 
−
подписывается сертификатом организации.
 
−
 
 
−
Итак, сгенерируем секретный ключ RSA и self-signed сертификат организации:
 
  
 
         dd if=/dev/urandom of=/etc/openssl/.rnd -count 64
 
         dd if=/dev/urandom of=/etc/openssl/.rnd -count 64
Рядок 804: Рядок 504:
 
             -extfile /etc/openssl/org.cnf -out /etc/openssl/org.crt -days 365
 
             -extfile /etc/openssl/org.cnf -out /etc/openssl/org.crt -days 365
  
−
 
+
<br> Пример конфига сертификата организации(CA сертификат, поэтому определяем некоторые расширения, которые указываем программе x509):  
−
Пример конфига сертификата организации(CA сертификат, поэтому определяем
 
−
некоторые расширения, которые указываем программе x509):
 
  
 
         [ req ]
 
         [ req ]
Рядок 838: Рядок 536:
 
         nsCertType      = sslCA
 
         nsCertType      = sslCA
  
−
 
+
<br> Теперь создаём сертификат сервера:  
−
Теперь создаём сертификат сервера:
 
  
 
         dd if=/dev/urandom of=/etc/openssl/.rnd count=64
 
         dd if=/dev/urandom of=/etc/openssl/.rnd count=64
Рядок 846: Рядок 543:
 
             -out /etc/openssl/httpd.csr
 
             -out /etc/openssl/httpd.csr
  
−
 
+
<br> И подписываем его сертификатом организации:  
−
И подписываем его сертификатом организации:
 
  
 
         openssl x509 -req -signkey /etc/openssl/org.key -CA /etc/openssl/org.crt  \
 
         openssl x509 -req -signkey /etc/openssl/org.key -CA /etc/openssl/org.crt  \
Рядок 853: Рядок 549:
 
             -days 365
 
             -days 365
  
−
 
+
<br> Опять же здесь нужны расширения для серверного сертификата, ещё учтите, что лучше задавать CN серверного сертификата как имя сервера:  
−
Опять же здесь нужны расширения для серверного сертификата, ещё учтите, что
 
−
лучше задавать CN серверного сертификата как имя сервера:
 
  
 
         extensions = v3_req
 
         extensions = v3_req
Рядок 863: Рядок 557:
 
         nsCertType      = server
 
         nsCertType      = server
  
 +
<br> И ещё одна тонкость: при создании секретного ключа сервера его лучше не шифровать. Хотя если это неообходимо в соображениях безопасности, то можно и зашифровать, но при этом апач при запуске будет спрашивать пароль секретного ключа сервера(на экране при этом ничего отображаться не будет, поэтому если вы долго ждёте запуска апача при включенном ssl и зашифрованном ключе, попробуйте ввести пароль).
  
−
И ещё одна тонкость: при создании секретного ключа сервера его лучше не
+
После генерации сертификата начинаем настройку апача. Имеет смысл при использовании ssl создать отдельный файл конфигурации, который будет описывать параметры ssl. Также обычно создаётся виртуальный сервер ssl, который висит на 443 порту(https), в отличие от стандартных виртуальных серверов ssl сервер должен однозначно соответствовать паре ip адрес&nbsp;: порт(т.е. на один ipшник и порт можно повесить только один ssl виртуальный сервер). Для начала включим ssl модуль в апаче. После этого все настройки ssl полезно окружить условием &lt;IfModule mod_ssl.c&gt;&lt;/IfModule&gt;:  
−
шифровать. Хотя если это неообходимо в соображениях безопасности, то можно и
 
−
зашифровать, но при этом апач при запуске будет спрашивать пароль секретного
 
−
ключа сервера(на экране при этом ничего отображаться не будет, поэтому если вы
 
−
долго ждёте запуска апача при включенном ssl и зашифрованном ключе, попробуйте
 
−
ввести пароль).
 
−
 
 
−
После генерации сертификата начинаем настройку апача. Имеет смысл при
 
−
использовании ssl создать отдельный файл конфигурации, который будет описывать
 
−
параметры ssl. Также обычно создаётся виртуальный сервер ssl, который висит на
 
−
443 порту(https), в отличие от стандартных виртуальных серверов ssl сервер
 
−
должен однозначно соответствовать паре ip адрес : порт(т.е. на один ipшник и
 
−
порт можно повесить только один ssl виртуальный сервер). Для начала включим ssl
 
−
модуль в апаче. После этого все настройки ssl полезно окружить условием <IfModule
 
−
mod_ssl.c></IfModule>:
 
  
−
httpd.conf
+
httpd.conf  
  
 
         # Загружаем модуль ssl(он может находиться в modules или extramodules). Учтите,
 
         # Загружаем модуль ssl(он может находиться в modules или extramodules). Учтите,
Рядок 924: Рядок 605:
 
         SSLLogLevel info
 
         SSLLogLevel info
  
 +
<br> После настройки самого апача обычно приступают к настройке виртуального ssl сервера. Обычно основной сервер оставляют висеть на 80 порту, а на главной странице размещают ссылку на переход в безопасный режим(или ставят редирект, но это уж дело вкуса или политики безопасности).
  
−
После настройки самого апача обычно приступают к настройке виртуального ssl
+
vhosts.conf
−
сервера. Обычно основной сервер оставляют висеть на 80 порту, а на главной
 
−
странице размещают ссылку на переход в безопасный режим(или ставят редирект, но
 
−
это уж дело вкуса или политики безопасности).  
 
  
−
vhosts.conf
+
         &lt;IfModule mod_ssl.c&gt;
−
 
 
−
         <IfModule mod_ssl.c>
 
 
         # Определяем виртуальный сервер, висящий на том же ip адресе, что и основной, но слушающий
 
         # Определяем виртуальный сервер, висящий на том же ip адресе, что и основной, но слушающий
 
         # на 443 порту
 
         # на 443 порту
−
         <VirtualHost _default_:443>
+
         &lt;VirtualHost _default_:443&gt;
  
 
         #  Основные настройки виртуального сервера
 
         #  Основные настройки виртуального сервера
Рядок 948: Рядок 625:
  
 
         # Список доступных алгоритмов шифрования. Формат списка такой же, как и у
 
         # Список доступных алгоритмов шифрования. Формат списка такой же, как и у
−
         # команды openssl ciphers(MEDIUM, HIGH, NULL, элементы разделяются :, исключение
+
         # команды openssl ciphers(MEDIUM, HIGH, NULL, элементы разделяются&nbsp;:, исключение
−
         # элемента осуществляется знаком !).
+
         # элемента осуществляется знаком&nbsp;!).
 
         SSLCipherSuite HIGH:MEDIUM
 
         SSLCipherSuite HIGH:MEDIUM
  
Рядок 981: Рядок 658:
 
         # Аутентификация клиента на основании его сертификата, выданного CA(см. опцию
 
         # Аутентификация клиента на основании его сертификата, выданного CA(см. опцию
 
         # SSLCACertificate). В глобальной конфигурации я установил эту опцию в none, но
 
         # SSLCACertificate). В глобальной конфигурации я установил эту опцию в none, но
−
         # эта опция может быть переопределена в конкретной <Directory> или <Location>, как и сделано в
+
         # эта опция может быть переопределена в конкретной &lt;Directory&gt; или &lt;Location&gt;, как и сделано в
 
         # данном примере
 
         # данном примере
 
         SSLVerifyClient none
 
         SSLVerifyClient none
Рядок 987: Рядок 664:
 
         # сотрудникам определённых отделов. Клиент должен будет послать свой сертификат,
 
         # сотрудникам определённых отделов. Клиент должен будет послать свой сертификат,
 
         # который подписан одним из ca сертификатов.  
 
         # который подписан одним из ca сертификатов.  
−
         <Location /secure>
+
         &lt;Location /secure&gt;
 
         # Требуем от клиента посылки своего сертификата для выполнения аутентификации
 
         # Требуем от клиента посылки своего сертификата для выполнения аутентификации
 
         SSLVerifyClient require
 
         SSLVerifyClient require
Рядок 998: Рядок 675:
 
         # данной команды с первого взгляда может показаться несколько сложным, но он
 
         # данной команды с первого взгляда может показаться несколько сложным, но он
 
         # использует регулярные выражения, подобные перловским, и логические
 
         # использует регулярные выражения, подобные перловским, и логические
−
         # операторы(and, or, !). В качестве переменных могут использоваться как
+
         # операторы(and, or,&nbsp;!). В качестве переменных могут использоваться как
 
         # стандартные переменные, вроде REMOTE_ADDR, TIME, так и переменные ssl. Среди
 
         # стандартные переменные, вроде REMOTE_ADDR, TIME, так и переменные ssl. Среди
 
         # последних imho наиболее полезны следующие: SSL_CIPHER,
 
         # последних imho наиболее полезны следующие: SSL_CIPHER,
 
         # SSL_CLIENT_S_DN_(параметры DN клиента, вроде O, OU, С и.т.д.),
 
         # SSL_CLIENT_S_DN_(параметры DN клиента, вроде O, OU, С и.т.д.),
 
         # SSL_CLIENT_I_DN_(параметры DN поставщика сертификата).
 
         # SSL_CLIENT_I_DN_(параметры DN поставщика сертификата).
−
         SSLRequire %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
+
         SSLRequire &nbsp;%{SSL_CIPHER}&nbsp;!~ m/^(EXP|NULL)-/ \
−
                     and %{SSL_CLIENT_S_DN_O} eq "organization" \
+
                     and&nbsp;%{SSL_CLIENT_S_DN_O} eq "organization" \
−
                     and %{SSL_CLIENT_S_DN_OU} in {"Sysopka", "CA", "BigBosses"}
+
                     and&nbsp;%{SSL_CLIENT_S_DN_OU} in {"Sysopka", "CA", "BigBosses"}
−
         </Location>
+
         &lt;/Location&gt;
  
−
         # Определяем опции ssl(они могут быть переопределены в <Directory>):
+
         # Определяем опции ssl(они могут быть переопределены в &lt;Directory&gt;):
 
         #  FakeBasicAuth:
 
         #  FakeBasicAuth:
 
         #  Данная опция говорит апачу, что можно использовать аутентификацию на основе
 
         #  Данная опция говорит апачу, что можно использовать аутентификацию на основе
Рядок 1028: Рядок 705:
 
         #  доступа клиента, если его сертификат не соответствует RequireSSL
 
         #  доступа клиента, если его сертификат не соответствует RequireSSL
 
         #  OptRenegotiate:
 
         #  OptRenegotiate:
−
         #  Данная опция применяется только в параметрах <Directory> и заставляет ssl
+
         #  Данная опция применяется только в параметрах &lt;Directory&gt; и заставляет ssl
 
         #  заново инициализировать соединение с клиентом
 
         #  заново инициализировать соединение с клиентом
 
         #SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
 
         #SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
Рядок 1051: Рядок 728:
 
         # шифрования.
 
         # шифрования.
 
         CustomLog logs/ssl_request_log \
 
         CustomLog logs/ssl_request_log \
−
                   "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
                   "%t&nbsp;%h&nbsp;%{SSL_PROTOCOL}x&nbsp;%{SSL_CIPHER}x \"%r\"&nbsp;%b"
  
 
         # Перезапускаем апач, если ssl оказался не включенным
 
         # Перезапускаем апач, если ssl оказался не включенным
 
         RewriteEngine on
 
         RewriteEngine on
−
         RewriteCond %{HTTPS} !=on
+
         RewriteCond&nbsp;%{HTTPS}&nbsp;!=on
 
         RewriteOptions inherit
 
         RewriteOptions inherit
  
−
         </VirtualHost>
+
         &lt;/VirtualHost&gt;
  
−
         </IfModule>
+
         &lt;/IfModule&gt;
  
−
 
+
<br> Для проверки работы сервера ssl обычно применяется утилита openssl s_client, которая эмулирует поведение ssl клиента(фактически, ssl telnet): openssl s_client -connect ww.test.ru:443 [-cert file] [-debug] [-ciphers list] Клиент может передать серверу сертификат(аутнентификация по сертификату), указав опцию -cert, опция -debug включает в вывод дополнительную отладочную информацию, включая hex дампы каждого пакета. Для проверки апача можно также применить свой любимый браузер(мой любимый - lynx):  
−
Для проверки работы сервера ssl обычно применяется утилита openssl s_client,
 
−
которая эмулирует поведение ssl клиента(фактически, ssl telnet):  
 
−
openssl s_client -connect ww.test.ru:443 [-cert file] [-debug] [-ciphers list]
 
−
Клиент может передать серверу сертификат(аутнентификация по сертификату),
 
−
указав опцию -cert, опция -debug включает в вывод дополнительную отладочную
 
−
информацию, включая hex дампы каждого пакета. Для проверки апача можно также
 
−
применить свой любимый браузер(мой любимый - lynx):
 
  
 
         lynx https://www.test.ru
 
         lynx https://www.test.ru
  
−
 
+
<br> При этом в лог записывается примерно следующее(если сервер настроен парвильно):  
−
При этом в лог записывается примерно следующее(если сервер настроен парвильно):
 
  
 
         [10/Nov/2002 17:41:34 04803] [info]  Connection to child 0 established (server localhost.localdomain:443, client 127.0.0.1)
 
         [10/Nov/2002 17:41:34 04803] [info]  Connection to child 0 established (server localhost.localdomain:443, client 127.0.0.1)
Рядок 1082: Рядок 751:
 
         [10/Nov/2002 17:41:35 04803] [info]  Connection to child 0 closed with standard shutdown (server localhost.localdomain:443, client 127.0.0.1)  
 
         [10/Nov/2002 17:41:35 04803] [info]  Connection to child 0 closed with standard shutdown (server localhost.localdomain:443, client 127.0.0.1)  
  
 +
<br> Итак, могу привести парочку примеров применения ssl соединений: во-первых - это любые процедуры конфиденциальной регистрации, во-вторых, возможность организации защищённого веб-интерфейса для почты, в-третьих, работа с клиентами данной фирмы, в-четвёртых, для защиты некоторых мест от посторонних взглядов(это несоизмеримо безопаснее, чем парольная аутентификация!) и подмены ipшника, в-пятых, для организации собственного CA. Вообще агентства по выдаче персональных сертификатов работают по следующей схеме: пользователь заходит на сайт и просит сертификата, после чего устанавливается безопасное соединение, и клиент заполняет форму регистрации(включая пароль секретного ключа), после этого создаётся запрос на сертификацию(на сервере), и на основе сертификата организации создаётся сертификат клиента. После этого обычно сертификат клиента перегоняется в pkcs#12 формат и записывается на диск. Пользователю же по мылу отправляется ссылка на полученный сертификат. Этот несчастный клиент проходит по ссылке, вводит своё имя и пароль(в безопасном режиме - https) и перенаправляется к своему сертификату. Браузер, получив сертификат, проверяет его подпись и после запроса помещает в хранилище личных сертификатов. Я здесь не буду приводить готового решения, т.к. это дело очень творческое(да и влом мне&nbsp;:) и создать вышеописанное не представляет труда, только надо немного поработать(написать скриптик, оформить всё это безобразие, организовать мыльную связь и.т.д.).
  
−
Итак, могу привести парочку примеров применения ssl соединений: во-первых - это
+
А теперь расскажу об одном непременном атрибуте каждого СА: создания списка недействительных сертификатов(чтобы не переполнять текст, буду далее применять обозначение CRL). По истечении определённого срока сертификат становится недействительным. Если это сертфика сотрудника, то после его увольнения сертификат также необходимо считать недействительным(а если уволили вас?&nbsp;;). Если секретный ключ сертификата стал достоянием общественности, то и его вносят в CRL. Для управления CRL можно использовать утилиту openssl ca. Для начала создаём crl:  
−
любые процедуры конфиденциальной регистрации, во-вторых, возможность организации
 
−
защищённого веб-интерфейса для почты, в-третьих, работа с клиентами данной
 
−
фирмы, в-четвёртых, для защиты некоторых мест от посторонних взглядов(это
 
−
несоизмеримо безопаснее, чем парольная аутентификация!) и подмены ipшника,
 
−
в-пятых, для организации собственного CA. Вообще агентства по выдаче
 
−
персональных сертификатов работают по следующей схеме: пользователь заходит на
 
−
сайт и просит сертификата, после чего устанавливается безопасное соединение, и
 
−
клиент заполняет форму регистрации(включая пароль секретного ключа), после этого
 
−
создаётся запрос на сертификацию(на сервере), и на основе сертификата организации
 
−
создаётся сертификат клиента. После этого обычно сертификат клиента перегоняется
 
−
в pkcs#12 формат и записывается на диск. Пользователю же по мылу отправляется
 
−
ссылка на полученный сертификат. Этот несчастный клиент проходит по ссылке,
 
−
вводит своё имя и пароль(в безопасном режиме - https) и перенаправляется к
 
−
своему сертификату. Браузер, получив сертификат, проверяет его подпись и после
 
−
запроса помещает в хранилище личных сертификатов. Я здесь не буду приводить
 
−
готового решения, т.к. это дело очень творческое(да и влом мне :) и создать
 
−
вышеописанное не представляет труда, только надо немного поработать(написать
 
−
скриптик, оформить всё это безобразие, организовать мыльную связь и.т.д.).
 
−
 
 
−
А теперь расскажу об одном непременном атрибуте каждого СА: создания списка
 
−
недействительных сертификатов(чтобы не переполнять текст, буду далее применять
 
−
обозначение CRL). По истечении определённого срока сертификат становится
 
−
недействительным. Если это сертфика сотрудника, то после его увольнения
 
−
сертификат также необходимо считать недействительным(а если уволили вас? ;).
 
−
Если секретный ключ сертификата стал достоянием общественности, то и его вносят
 
−
в CRL. Для управления CRL можно использовать утилиту openssl ca. Для начала
 
−
создаём crl:
 
  
 
         openssl ca -gencrl -out crl.pem
 
         openssl ca -gencrl -out crl.pem
  
 +
<br> Затем просто отменяем нужные(точнее говря не нужные) сертификаты командой openssl ca -revoke bad_cert.pem
  
−
Затем просто отменяем нужные(точнее говря не нужные) сертификаты командой
+
После каждого применения revoke необходимо обновлять CRL командой openssl -gencrl. Для применения внутри СА необходимо дать клиентам возможность отменять их сертификаты, для этого необходимо предоставить им доступ к CRL. Если же вы используете аутентификацию через сертификаты, то пользователям необходимо понять, как опасно потерять секретный ключ. Ещё способ давать пароль для секретного ключа с помощью /dev/random, закодированного base64 и сообщать пароль клиенту только лично(можно также поиграться со временем действия сертификата клиента, но зачастую это может сильно увеличить геморройность работы, если вам необходимо раздавать сертификаты лично).  
−
openssl ca -revoke bad_cert.pem
 
  
−
После каждого применения revoke необходимо обновлять CRL командой openssl
+
Теперь настало время обратиться к защите почтовых серверов. Одним из наиболее удобных вариантов является использование courier в качестве pop3 и imap серверов, а в качестве MTA использовать postfix. Итак, начнём с курьера.  
−
-gencrl. Для применения внутри СА необходимо дать клиентам возможность отменять
 
−
их сертификаты, для этого необходимо предоставить им доступ к CRL. Если же вы
 
−
используете аутентификацию через сертификаты, то пользователям необходимо
 
−
понять, как опасно потерять секретный ключ. Ещё способ давать пароль для
 
−
секретного ключа с помощью /dev/random, закодированного base64 и сообщать пароль
 
−
клиенту только лично(можно также поиграться со временем действия сертификата
 
−
клиента, но зачастую это может сильно увеличить геморройность работы, если вам
 
−
необходимо раздавать сертификаты лично).
 
  
−
Теперь настало время обратиться к защите почтовых серверов. Одним из наиболее
+
Курьер поставляется с грамотным конфигом, поэтому у меня всё заработало сразу же безо всяких проблем с настройкой. Единственное, что необходимо учесть, так это что сертфикат почтового сервера должен быть подписан CA сертификатом(по умолчанию при сборке курьера генерится self-signed сертификат, но я бы рекомендовал создать сертификат, как это было сделано в апаче или воспоьзовавшись моим скриптиком CA, только необходимо изменить настройки extensions). Кроме этого, сертификат организации, которым был подписан ключ сервера, должен находится среди доверенных сертификатов почтового клиента. Я всё же расскажу о некоторых полезных опциях конфигурации couriera(imapd и pop3d):
−
удобных вариантов является использование courier в качестве pop3 и imap
 
−
серверов, а в качестве MTA использовать postfix. Итак, начнём с курьера.
 
  
−
Курьер поставляется с грамотным конфигом, поэтому у меня всё заработало сразу же
+
imapd-ssl  
−
безо всяких проблем с настройкой. Единственное, что необходимо учесть, так это
 
−
что сертфикат почтового сервера должен быть подписан CA сертификатом(по
 
−
умолчанию при сборке курьера генерится self-signed сертификат, но я бы
 
−
рекомендовал создать сертификат, как это было сделано в апаче или
 
−
воспоьзовавшись моим скриптиком CA, только необходимо изменить настройки
 
−
extensions). Кроме этого, сертификат организации, которым был подписан ключ
 
−
сервера, должен находится среди доверенных сертификатов почтового клиента. Я всё
 
−
же расскажу о некоторых полезных опциях конфигурации couriera(imapd и pop3d):
 
−
 
 
−
imapd-ssl
 
  
 
         # Запускаем работу механизма ssl для imap сервера. В файлах esmtpd-ssl,
 
         # Запускаем работу механизма ssl для imap сервера. В файлах esmtpd-ssl,
Рядок 1218: Рядок 841:
 
         TLS_VERIFYPEER=NONE  
 
         TLS_VERIFYPEER=NONE  
  
 +
<br> Думаю, что дальнейшая настройка курьера не должна вызвать проблем(IMHO courier - один из самых простых в настройке почтовых служб, т.к. все переменные внутри его конфигов фактически имеют тот же синтаксис, что и переменные в shell).
  
−
Думаю, что дальнейшая настройка курьера не должна вызвать проблем(IMHO courier -
+
Другой популярный мыльный сервер - postfix - также легко поддаётся бронированию с помощбю ssl. Сразу же приведу пример настройки smtpd postfixa, который использует при передаче почты механизм ssl:  
−
один из самых простых в настройке почтовых служб, т.к. все переменные внутри его
 
−
конфигов фактически имеют тот же синтаксис, что и переменные в shell).
 
−
 
 
−
Другой популярный мыльный сервер - postfix - также легко поддаётся бронированию
 
−
с помощбю ssl. Сразу же приведу пример настройки smtpd postfixa, который
 
−
использует при передаче почты механизм ssl:
 
  
 
main.cf:  
 
main.cf:  
Рядок 1284: Рядок 902:
 
         tls_random_source = dev:/dev/urandom
 
         tls_random_source = dev:/dev/urandom
  
−
 
+
<br> Также необходимо создать запись в master.cf, чтобы указать postfix слушать smtps порт(кроме этого заставляем на порту smtps использовать полную шифрацию передаваемого трафика)  
−
Также необходимо создать запись в master.cf, чтобы указать postfix слушать smtps
 
−
порт(кроме этого заставляем на порту smtps использовать полную шифрацию
 
−
передаваемого трафика)
 
  
 
         # tls_random_source = egd:/var/run/egd-pool
 
         # tls_random_source = egd:/var/run/egd-pool
Рядок 1297: Рядок 912:
 
         smtps    inet  n      -      y      -      -      smtpd -o smtpd_enforce_tls=yes
 
         smtps    inet  n      -      y      -      -      smtpd -o smtpd_enforce_tls=yes
  
 +
<br> Вместо имени сервиса можно указать номер порта(обычно 465).
  
−
Вместо имени сервиса можно указать номер порта(обычно 465).
+
Sendmail также обладает возможностью использования ssl, но я не являюсь специалистом по sendmail(наверное, виной тому паталогическая лень и наличие более простых в освоении инструментов).  
−
 
 
−
Sendmail также обладает возможностью использования ssl, но я не являюсь
 
−
специалистом по sendmail(наверное, виной тому паталогическая лень и наличие
 
−
более простых в освоении инструментов).
 
  
−
SSL, похоже, будет всё больше и больше использоваться в сети, защищая стандартные
+
SSL, похоже, будет всё больше и больше использоваться в сети, защищая стандартные протоколы. Поэтому каждый администратор должен знать принципы работы с ssl. И если я помог кому-то в освоении данной темы, то могу считать свою задачу выполненной!  
−
протоколы. Поэтому каждый администратор должен знать принципы работы с ssl. И
 
−
если я помог кому-то в освоении данной темы, то могу считать свою задачу
 
−
выполненной!  
 
  
−
Приведу некоторые ссылки:
+
Приведу некоторые ссылки:  
  
 
  http://www.openssl.org -- основной сайт с документацией и исходниками openssl
 
  http://www.openssl.org -- основной сайт с документацией и исходниками openssl
Рядок 1317: Рядок 926:
 
  http://www.thawte.com -- одна из коммерческих фирм, предоставляющих сертификаты
 
  http://www.thawte.com -- одна из коммерческих фирм, предоставляющих сертификаты
  
−
И ещё информация для тех, кто решил работать с ssl: не так давно в механизме
+
И ещё информация для тех, кто решил работать с ssl: не так давно в механизме openssl были обнаружены уязвимости, поэтому не поленитесь сходить на http://www.openssl.org за последними патчами.
−
openssl были обнаружены уязвимости, поэтому не поленитесь сходить на
 
−
http://www.openssl.org за последними патчами.
 

Поточна версія на 11:20, 21 квітня 2009

| Оригинал Статья впервые опубликована в журнале | Системный Администратор

| OpenSSL - настройка и создание сертификатов

Использование OpenSSL (ssl security crypt cert mod_ssl apache imap postfix)

OpenSSL - это система защиты и сертификации данных, название SSL переводится,

как система безопасных сокетов(secure socket layer). OpenSSL используется практически всеми сетевыми серверами для защиты передаваемой информацией. Существует программное API SSL(SSLEAY), позволяющее создавать безопасные сокеты с шифрацией передаваемых данных в собственных разработках. Но в данной статье я бы хотел рассказать о самой системе OpenSSL, вызываемой через командную строку.

Т.к. OpenSSL поддерживает очень много различных стандартов сертификации, шифрования, хеширования, то использование данной команды достаточно сложно. Внутри OpenSSL существуют отдельные компоненты, отвечающие за то или иное действие, для получения списка доступных компонентов можно вызвать openssl с параметрами list-standart-commands. Можно также получить список доступных алгоритмов хеширования (list-message-digest-commands) и алгоритмов шифрования (list-cipher-commands).

OpenSSL может использоваться во множестве случаев и умеет выполнять следующие задачи:

  • Создавать и управлять ключами RSA и DSA - команды rsa, dsa, dsaparam
  • Создавать сертификаты формата x509, запросы на сертификацию, восстановление -
 команды x509, req, verify, ca, crl, pks12, pks7
  • Зашифровывать данные с помощью симметрического или асимметрического шифрования -
 команды enc, rsautl
  • Высчитывать хеши различных типов - команда dgst
  • Работа с S/MIME - команда s/mime
  • Проверка работы серверов и клиентов ssl - команды s_client, s_server.


Cуществует также несколько вспомогательных утилит ssl:

> openssl speed [список_алгоритмов_хеширования_или шифрования]:

 тестирование скорости различных алгоритмов, если запускать без
 параметров, то тестируются все алгоритмы; алгоритмы внутри списка
 разделяются пробелом, например openssl speed md5 rsa idea blowfish
 des 3des sha1. В конце работы выводится общая скорость работы
 различных алгоритмов(в 1000-х байт в секунду), для обработки
 различной длины блоков. Вот результат работы тестов скорости на моём
 домашнем компе (Celeron 366), на других машинах значения будут
 другими:
       Aлгоритм           8 байт       64 байт     256 байт     1024 байта   8192 байт
       md2                291.38k      817.15k     1109.67k     1218.56k     1256.11k
       mdc2               868.57k      911.02k      914.01k      915.11k      917.50k
       md4               4417.91k    24808.28k    51404.97k    70189.40k    78168.06k
       md5               3905.61k    21142.91k    41515.69k    55489.54k    59091.63k
       hmac(md5)         1536.42k    10381.81k    27585.13k    46119.35k    57671.68k
       sha1              2458.59k    11965.97k    21560.58k    26889.22k    29143.66k
       rmd160            2032.99k     9523.48k    16568.15k    20547.81k    22220.11k
       rc4              28775.08k    39239.02k    41210.52k    41862.98k    41454.25k
       des cbc           7586.90k     8411.44k     8580.28k     8627.29k     8612.52k
       des ede3          2866.13k     3031.96k     3050.92k     3074.74k     3058.35k
       idea cbc          4948.09k     5743.19k     5760.09k     5744.67k     5723.48k
       rc2 cbc           2982.04k     3220.39k     3256.32k     3263.49k     3268.61k
       rc5-32/12 cbc    19108.39k    24151.19k    24906.75k    25154.90k    25212.25k
       blowfish cbc     11018.91k    12881.27k    12925.01k    12972.37k    13047.13k
       cast cbc         10943.48k    12674.30k    12877.74k    12994.56k    13011.63k


Проверка алгоритмов асимметрического шифрования

       |            Подписывание Проверка    За секунду подп. За секунду пров.   
       rsa  512 bits   0.0036s   0.0003s    281.4           3221.7
       rsa 1024 bits   0.0184s   0.0009s     54.3           1072.9
       rsa 2048 bits   0.1105s   0.0032s      9.0            315.6
       rsa 4096 bits   0.7414s   0.0112s      1.3             89.4
               
       dsa  512 bits   0.0032s   0.0038s    311.3           261.3
       dsa 1024 bits   0.0093s   0.0116s    107.5            86.4
       dsa 2048 bits   0.0309s   0.0377s     32.4            26.5


> openssl rand [-out file] [-rand file] num:

 генерация num рандомных байт, можно использовать для проверки рандомизационной 
 последовательности rand:
       # openssl rand -rand .rnd 5 
       Wеб~
       #


> openssl ciphers [-ssl2] [-ssl3] [-tls1] NAME:

 вывод доступных алгоритмов для
 обеспечения уровня безопасности NAME, где NAME - это символическое название
 группы алгоритмов. Обычно используются значения 
 LOW - алгоритмы низкого уровня безопасности(<128 бит)
 MEDIUM - алгоритмы среднего уровня стойкости(128 бит)
 HIGH - алгоритмы высокой стойкости(> 128 бит)
 ALL - все алгоритмы
 NULL - алгоритмы без шифрования.
 Обычно в настоящее время используются алгоритмы групп MEDIUM и HIGH, которые
 ещё долго не смогут быть взломаны прямым перебором. Можно также вывести список
 алгоритмов из нескольких групп, разделив их :(например, MEDIUM:HIGH)


Теперь я бы хотел рассказать об основных утилитах openssl. Для начала я расскажу о методах генерации ключей, затем о командах шифрования, и, наконец, о сертификатах, s/mime. Итак, пару слов о генерации ключей. Для создания rsa ключей используется команда genrsa:

       openssl genrsa [-out file] [-des | -des3 | -idea] [-rand file] [bits]


Команда genrsa создаёт секретный ключ длиной bits в формате PEM, шифрует его одним из алгоритмов des(56 бит), des3(3-й des 168 бит) или idea(128 бит). При выборе алгоритма шифрования будет запрошен пароль для шифрации создаваемого секретного ключа(если алгоритм не указан, то секретный ключ не шифруется, чего делать ни в коем случае нельзя для личных ключей, т.к. некоторые серверы требуют отсутствие шифрации для сектетного ключа сервера). Опция -out говорит программе, что вывод нужно осуществлять не в stdout, а в файл file(опция -out присутствует во множестве других компонентов openssl и используется аналогичным образом для указания выходного файла). Опция -rand указывает на файл[ы](разделённые :), из которых будут считываться данные для установки seed(зерна) генератора случайных чисел. В качестве таких файлов сразу же приходит на ум использовать что-то вроде /dev/random или /dev/urandom, но у меня с этим возникли проблемы - всё вешалось наглухо, поэтому я рекомендую в этом случае использовать какие-нибудь сложно угадываемые файлы, вроде /var/log/messages или /boot/vmlinuz, думаю, что угадать содержимое этих файлов не намного проще, чем содержимое /dev/random, но работает этот фокус в любом

  • nixe(опция -rand также присутствует во всех компонентах генерации и управления

ключами и сертификатами). Использовать /dev/random и /dev/urandom, конечно, можно, но я для этого скопировал из /dev/random 32768 байт в файл .rnd таким образом:

       dd if=/dev/[u]random of=.rnd count=64 


Кроме этого, можно указывать в качестве -rand файла EGD сокет, который обеспечивает генерацию определённого количества случайных байт, EGD доступен на узле http://www.lothar.com/tech/crypto/. Установка генератора случайных чисел производится на основании хеша -rand файла, поэтому можно указывать файлы различной длины, т.к. хеш все равно имеет фиксированное число бит. Пример генерации 4096 битового секретного ключа RSA:

       # openssl genrsa -out /etc/openssl/key.pem -des3 -rand /var/log/messages 4096
       Generating RSA private key 
       .....++*...++++++++*
       Enter PEM passphrase: 
       Verify PEM passphrase:


После этого секретный ключ зашифровывается и записывается в файл(в текстовом виде). Вначале ключа указывается алгоритм шифрования. Для создания публичного ключа rsa на основе секретного используется команда openssl rsa. Даная команда имеет следующий формат:

       openssl rsa -in filename [-out file] [-des | -des3 |-idea] [-check] [-pubout]


Утилита openssl rsa способна изменять пароль и алгоритм шифрования cсекретного ключа, будучи вызвана с параметром -in и -out. Если применить параметр -pubout, то в указанный файл -out будет записан публичный ключ, вычисленный на основе -in секретного. Например, создание публичного ключа на основании секретного:

       openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/pubkey.pem -pubout


Изменение пароля и алгоритма шифрования секретного ключа с des3 на idea:

       openssl rsa -in /etc/openssl/key.pem -out /etc/openssl/key1.pem -idea


Для создания ключей DSA используется утилита openssl gendsa, аналогичная genrsa, но есть два отличия: во-первых, для ключей DSA нельзя прямо указывать длину в битах и, во-вторых, ключи DSA могут генерироваться согласно некоторым параметрам, записанным в файл paramfile утилитой openssl dsaparam. dsaparam имеет следующий формат:

       openssl dsaparam [-rand file{s}] [-C] [-genkey] [-out file]  numbits


где numbits - длина желаемого ключа, -С заставляет dsaparam вывести на stdout код на СИ для программной генерации DSA на основе необходимых параметров, а опция -genkey говорит, что в выходной файл, наряду с параметрами, дополнительно записывается созданный секретный ключ DSA, но нельзя его сразу же зашифровать, поэтому удобнее воспользоваться утилитой openssl gendsa, которая имеет схожий синтаксис с командой genrsa, но вместо числа бит указывается файл параметров, созданный dsaparam:

       # openssl gendsa -out /etc/openssl/dsakey.pem -rand /boot/vmlinuz -idea paramfile
       Enter PEM passphrase:
       Verify PEM passphrase:


Для управления ключами dsa используется программа openssl dsa, которая абсолютно аналогична(в параметрах) утилите openssl rsa. Поэтому я просто приведу пример генерации публичного ключа DSA:

       # openssl dsa -in /etc/openssl/dsakey.pem -out /etc/openssl/pubdsakey.pem -pubout


Теперь настало время рассказать о компонентах openssl, выполняющих шифрование и хеширование данных. Для выполнения симметрического шифрования используется утилита openssl enc -cipher, или её сокращённая запись openssl cipher, где cipher - это одно из символических имён симметрических шифров. Наиболее популярными являются следующие: base-64(преобразование в текстовый вид), bf(blowfish - 128 бит), des(56 бит), des3(168 бит), rc4(128 бит), rc5(128 бит), rc2 и idea(128 бит). Для указания входного и выходного файлов используется опции

-in и -out соответственно. Пароль для шифрования вводится с клавиатуры (можно указать

в командной строке параметром -k, но это очень плохо по соображениям безопасности, т.к. большинство шелов умеют сохранять историю командной строки, IMHO намного лучше ввести пароль непосредственно перед шифрованием, хотя эта опция полезна для скриптов, так что забывать о ней нельзя :). Учтите, что пароль не спрашивается при обработке файла base64, т.к. шифрования не происходит. Для расшифровки зашифрованных данных примените openssl cipher с опцией -d(алгоритм шифрования и дешифрования должен совпадать!), а для одновременной обработки данных base64 можно воспользоваться опцией -a.

Шифрование по умолчанию происходит с подмешиванием(подсолением :), т.е. для выбора алгоритма подмешивания используется случайная соль(salt), в этом случае, если вы шифруете один и тот же файл в разное время одним и тем же алгоритмом и паролем, то результаты скорее всего будут разными(это затрудняет атаку по словарю). Также по умолчанию используется cbc режим алгоритмов, когда ключ меняется в течение всего сеанса работы согласно передаваемым данным, этот приём очень сильно затрудняет брутфорс, т.к. атакующему сложно поймать нужный момент времени.

Приведу несколько примеров:

зашифруем файл, используя алгоритм des3

       # openssl des3 -in file -out file.des3


расшифруем полученный файл

       # openssl des3 -d -in file.des3 -out file


зашифруем файл, используя алгоритм blowfish(bf), и закодируем base64

       # openssl bf -a -in file -out file.bf64


теперь расшифруем его и обработаем сразу же base64

       # openssl bf -a -d -in file.bf64 -out file


Для вычисления хешей(их ещё называют отпечатками или контрольными суммами) используется команда openssl dgst -hashalg или краткая форма openssl hashalg(первая команда может также выполнять манипуляции с ЭЦП, но об этом далее). Обычное использование данной команды таково openssl hashalg [-c] file[s]. Вычисляется хеш сообщения фиксированной длины в виде одной строки или, если указана опция -c, строки, разделённой на пары HEX чисел двоеточием. Из алгоритмов хеширования могут применяться следующие: md2(128 бит), md4(128 бит), md5(128 бит), mdc2(128 бит), sha(160 бит), sha1(160 бит), ripemd160(160 бит).

Опять же приведу пару примеров:

вычислим md5 хеш файла:

       # openssl md5 -c file
       MD5(file)= 81:fd:20:ff:db:06:d5:2d:c3:55:b5:7d:3f:37:ac:94


а теперь SHA1 хеш этого же файла:

       # openssl sha1 file
       SHA1(file)= 13f2b3abd8a7add2f3025d89593a0327a8eb83af


Как я уже говорил, утилита openssl dgst может использоваться для подписывания сообщения секретным ключом и проверки ЭЦП публичным ключом. Для этого используется следующий синтаксис:

       openssl dgst -sign private_key -out signature -hashalg  file[s]


Подписывание file с помощью секретного ключа private_key, используя алгоритм хеширования hasalg(обычно применяются sha1 или md5).

       openssl dgst -signature signature -verify public_key file[s]


Проверка подписи в file, используя публичный ключ public_key и ЭЦП signature. Данная программа выводит "Verification OK" при правильной подписи или "Verification Failure"

в любом другом случае. Учтите, что ЭЦП в таком случае хранится отдельно от файла, который ею подписан(причём в каком-то кривом формате).

Для шифрации и дешифрации RSA алгоритмом используется программа rsautl. Данная утилита имеет также возможность подписывать и проверять подпись сообщений(однако работать всё равно приходится с хешем сообщения, т.к. подписывать можно только небольшой объём данных, по этой причине лучше применять openssl dgst). Для шифрации/дешифрации используется следующий синтаксис:

       openssl rsautl -in file -out file.cr -keyin pubkey.pem -pubin -encrypt


Шифрация file с использованием публичного ключа pubkey.pem

       openssl rsautl -in file.cr -out file -keyin secretkey.pem -decrypt


Дешифрация file.cr с использованием секретного ключа secretkey.pem

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

Можно, например, выдавать сотрудникам их персональные сертификаты, подписанные сертификатом организации(его можно сгенерировать самому или получить от сторонней компании). Причём эти сертификаты впоследствие можно использовать для удостоверения личности сотрудника, например, при почтовой переписке или аутентификации на http сервере(apache+ssl). Единственное условие, которое должно выполняться,- это наличие на машине клиента сертификата организации в списке корневых доверенных ключей. Общее содержание сертификатов определено стандартом x509, в то время как форматы записей сертификатов могут внести некоторую путаницу. Openssl по умолчанию использует формат PKCS#10, Microsoft использует по умолчанию формат PKCS#12(в руководстве по openssl этот формат охарактеризован, как один большой баг :), формат PKCS#7 используется для запросов на сертификацию к CA(центр сертификации )и не может содержать секретного ключа, также для этой цели может использоваться DER закодированный сертификат(DER кодирование подобно кодированию base64, но имеет специальное назначение для использования в криптографических системах) также без секретного ключа. Учтите, что при использовании DER формата убираются маркеры начала и конца сертификата, а его содержимое кодируется base64, поэтому в файле DER можно хранить только один сертификат, с другой стороны DER сертификаты поддерживаются M$(стандартное расширение .cer), поэтому иногда бывает нужно преобразовать сертификаты из одного формата в другой(я здесь имею ввиду PEM или DER):

       PEM-->DER openssl x509 -inform PEM -in cert.pem -outform DER -out cert.cer
       DER-->PEM openssl x509 -inform DER -in cert.cer -outform PEM -out cert.pem


Таким же образом можно конвертировать и ключи асимметрического шифрования(используя утилиты rsa или dsa).

Думаю, что не сильно запутал вас всеми этими стандартами. Если объяснять на пальцах, то всё выглядит следующим образом: клиент создаёт сертификат и отправляет свой публичный сертификат(PKCS#7) в центр сертификации. В центре сертификации обрабатывается запрос клиента(запрос на сертификацию), и сертификат клиента подписывается секретным ключом центра сертификации. Клиент, имея публичный ключ центра сертификации, проверяет подлинность подписи и может далее использовать свой сертификат. Для организации можно предложить следующее решение: на сервере создаётся сертификат организации; генерируется запрос на сертификацию и отправляется к некоему доверенному центру сертификации(который будет известен всем клиентам и персоналу данной организации); получается сертификат организации, который можно использовать при создании сертификатов клиентов. Последние создаются так: клиент посылает запрос на выдачу сертификата; сервер создаёт сертификат клиента и подписывает его сертификатом организации; клиент получает сертификат клиента и сертификат организации; после проверки достоверности ключа организации(предполагается, что клиент доверяет CA, которым был подписан сертификат организации) проверяется достоверность сертификата клиента. После такой операции клиент будет точно уверен, что получил сертификат от данной организации, и может его использовать для работы с ней. По такой схеме построены все центры выдачи сертификатов(правда зачастую сертификат организации бывает подписан самим собой, что требует от клиента добавить сертификат организации к доверенным, а в первой схеме сертификат организации принадлежит к группе промежуточных центров сертификации, и этот случай предпочтительнее с точки зрения безопасности и удобства клиента, но требует больше работы от администратора). Да, хорошенькое объяснение на пальцах! Но что тут поделать: сертификаты - это довольно запутанная вещь. Сейчас я объясню, как создавать сертификаты с помощью openssl, и приведу пример только что описанного безобразия...

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

       [ req ]
       # Секция основных опций 
       default_bits	       = 2048
       # Число бит
       default_keyfile	       = keyfile.pem
       # Имя ключа, используемого для сертификата
       distinguished_name     = req_distinguished_name
       # DN организации, выдавшей сертификат
       prompt		       = no
       # Брать параметры из конфига неинтерактивный режим
       [ req_distinguished_name ]
       # DN организации 
       CN=RU
       # Страна
       ST=Ivanovskaya
       # Область
       L=Gadukino
       # Город
       O=Krutie parni
       # Название организации
       OU=Sysopka
       # Название отделения
       CN=Your personal certificate
       # Имя для сертификата(персоны, получающей сертификат)
       [email protected]
       # Мыло организации


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

имя = подсказка имя_default = значение_по_умолчанию имя_max = максимум имя_min = минимум

Пример интерактивного файла конфигурации:

       [ req ]
       default_bits	       = 1024
       default_keyfile	       = privkey.pem
       distinguished_name     = req_distinguished_name
       [ req_distinguished_name ]
       countryName		       = Country Name (2 letter code)
       countryName_default	       = RU
       countryName_min		       = 2
       countryName_max		       = 2
       localityName		       = Locality Name (eg, city)
       organizationName               = Organization Name(eg, org)
       organizationalUnitName	       = Organizational Unit Name (eg, section)
       commonName		       = Common Name (eg, YOUR name)
       commonName_max		       = 64
       emailAddress		       = Email Address
       emailAddress_max	       = 40


Спешу обрадовать некоторых ленивых товарищей: если вы намереваетесь создавать просто сертификат сервера(например, для LDAP сервера), то указывать конфиг необязательно, будет использоваться конфиг по умолчанию /usr/lib/ssl/openssl.cnf, который содержит всё необходимое. Ну а теперь традиционно приведу примеры использования openssl req(я не собираюсь подробно описывать данную команду, т.к. думаю, что для большинства случаев хватит примеров, а для особых случаев можно почитать man req).

       openssl req -new -newkey rsa:2048 -keyout rsa_key.pem -config cfg -out certreq.pem


Создание запроса на сертификацию(-new) на основе создаваемого секретного ключа rsa(-newkey rsa:2048), который записывается в файл -keyout(и шифруется тройным DES). Запрос на сертификацию создаётся на основе конфигурационного файла-config.

openssl req -x509 -new -key private_key.pem -config cfg -out selfcert.pem -days 365 Создание(-new) self-signed сертификата(-x509) для использования в качестве сертификата сервера или сертификата CA. Сертификат создаётся с использованием секретного ключа -key и конфигурационного файла -config. Создаваемый сертификат будет действителен в течение 365 дней(-days), опция -days не применима к запросам на сертификацию.

Для управления сертификатами x509 используется утилита openssl x509. С её помощью можно подписать сертификат или запрос на сертификацию сертификатом CA. Также можно просмотреть содержимое сертификата в читаемой форме(DN, публичный ключ, время действия, отпечаток и.т.д.). Приведу примеры вышеописанных действий:

openssl x509 -in cert.pem -noout -text Просмотреть информацию о сертификате в "нормальной" форме. Вот что примерно будет выведено, также можно использовать дополнительные опции: -fingerprint (необходимо сочетать с одной из опций -sha1, -md5 или -mdc2), -modulus (вывод публичного ключа), -serial, -subject, -issuer(организация, выдавшая сертификат), -email, -startdate, -enddate:

       Certificate:
           Data:
               Version: 3 (0x2)
               Serial Number: 0 (0x0)
               Signature Algorithm: md5WithRSAEncryption
               Issuer: C=RU, ST=region, L=city, O=organization, OU=Sysopka,
        CN=CEBKA/[email protected]
               Validity
                   Not Before: Nov  9 08:51:03 2002 GMT
                   Not After : Nov  9 08:51:03 2003 GMT
               Subject: C=RU, ST=region, L=city, O=organization, OU=Sysopka,
        CN=CEBKA/[email protected] 
               Subject Public Key Info:
                   Public Key Algorithm: rsaEncryption
                   RSA Public Key: (1024 bit)
                       Modulus (1024 bit):
                           00:c6:6b:3b:8e:f8:33:05:a0:dc:e1:38:8f:6a:68:
                           42:1c:21:33:aa:90:b6:8c:93:14:11:9b:69:94:8a:
                           3a:0e:42:29:b0:45:14:1b:f0:37:2c:f3:05:db:13:
                           06:a9:cd:eb:99:31:51:25:86:c8:69:e0:5e:8d:28:
                           04:8d:1f:08:37:d7:72:39:fe:05:57:61:68:95:bf:
                           5c:ae:13:f2:05:a1:29:c3:bf:3b:32:ca:1a:ff:22:
                           53:f9:32:92:78:fe:44:c3:e1:ca:42:5c:5f:d1:49:
                           da:1c:9f:34:06:04:ee:46:74:8d:11:68:ef:37:e2:
                           74:1e:d9:46:04:b8:7e:d5:c5
                       Exponent: 65537 (0x10001)
               Signature Algorithm: md5WithRSAEncryption
               3b:42:85:45:08:95:f3:f1:fc:8a:23:88:58:0e:be:e5:9b:56:
               1e:c1:ff:39:28:4f:84:19:f8:3e:38:ef:98:34:d6:ee:e0:0a:
               de:36:3a:5c:15:88:d7:2a:a4:0a:d5:dc:3e:b2:72:4c:82:57:
               b8:fe:52:f6:e2:06:01:38:eb:00:0b:f2:a9:87:be:65:83:19:
               13:50:ae:6c:f2:0a:07:14:e6:8c:60:cd:c5:a3:d1:e1:ea:da:
               24:c2:6a:06:d5:dc:1c:71:c9:64:fa:9e:c9:ca:97:e2:06:84:
               de:4c:69:b8:9a:af:66:14:8d:46:9a:00:53:13:c9:ab:10:b8:
               09:c2
       openssl x509 -req -in clientreq.pem -extfile /usr/lib/ssl/openssl.cnf \
            -extensions /usr/lib/ssl/openssl.cnf -CA CAcert.pem -CAkey serverkey.pem    \
            -CAcreateserial -out clientcert.pem


Подписать запрос на сертификацию(-req) файла -in, используя доверенный CA сертификат -CA и его секретный ключ -CAkey. В конечный сертификат клиента(-out), записываются дополнительные параметры сертификата 3-й версии из файла /usr/lib/ssl/openssl.cnf(конфигурационный файл по умолчанию). Но об этом я расскажу после на конкретном примере. Такое поведение x509 позволяет организовать свой центр сертификации, подписывающий запросы клиентов на сертификацию.

       openssl x509 -in CAcert.pem -addtrust sslclient -alias "myorganization CA" \
            -out CAtrust.pem


Преобразование сертификата -in в доверенный сертификат для использования в SSL клиентах(sslserver - использование в качестве сертификата сервера, emailProtection - использование в качестве сертификата S/MIME).

Я ещё раз хотел бы вернуться к проблеме построения CA. Для использования внутри организации можно использовать self-signed сертификат, но для использования CA вне организации приходится использовать сертификаты, выданные или подписанные сторонней организацией. Во втором случае возникает проблема выбора такой сторонней организации(она легко разрешается для дочерних компаний), которая требует юридического анализа(в разных странах существуют свои законы криптографии и поэтому дать какой-либо конкретный совет я не могу). Если вам довелось работать в российской правительственной компании, то считайте, что вам не повезло - использовать openssl для работы с правительственными организациями нельзя. Наши уважаемые гос. деятели добавили геморроя админам, разрешив использовать только алгоритмы ГОСТ(симметрические, асимметрические, хеширования - меня просто выворачивает от самого этого слова ГОСТ ;), поэтому использовать вам придётся только специальные программы, реализующие эти алгоритмы. Я же приведу здесь пример построение собственного CA с self-signed сертификатом:

1) Генерируем секретный ключ:

       openssl genrsa -out CAkey.pem -rand randfile -des3 4096


2) Создаём self-signed сертификат:

       openssl req -new -x509 -key CAkey.pem -out CAcert.pem -days 365 -config cfg


Содержимое конфигурационного файла зависит от организации, можно даже воспользоваться утилитой /usr/lib/ssl/misc/CA.pl -newcert, которая создаст ключ и сертификат в одном файле в интерактивном режиме(хотя мне этот вариант не очень понравился, лучше один раз написать нормальный конфиг) - о дополнительных требованиях к конфигурации CA сертификата см. ниже.

3) Приведу пример скрипта, генерирующего клиентские сертификаты:


#!/bin/bash

dd if=/dev/random of=/tmp/.rnd count=64
RAND="/var/log/messages:/boot/vmlinuz:/tmp/.rnd"
REQ="openssl req"
X509="openssl x509"
RSA="openssl rsa"
GENRSA="openssl genrsa"
O="company"
C="RU"
ST="region"
L="city"
PURPOSES="digitalSignature, keyEncipherment"
CERTTYPE="client, email, objsign"
CA="/etc/openssl/CAcert.pem"
CAkey="/etc/openssl/CAkey.pem"
OUTDIR="/etc/openssl/clientcert/"
CN="client"
BITS=2048
DAYS=365
#Создаём секретный ключ во временной папке БЕЗ шифрования
TMP="/tmp/ssl-$$"
mkdir $TMP

if [ ! -d $OUTDIR ];then
        mkdir $OUTDIR
fi
pushd $TMP > /dev/null
$GENRSA -rand $RAND -out tmp.key $BITS
# Создаём конфиг для клиента
cat > cfg <<EOT
[ req ]
default_bits                    = $BITS
distinguished_name              = req_DN
extensions			= v3_req
[ req_DN ]
countryName                     = "1. Country Name             (2 letter code)"
countryName_default             = "$C"
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = "2. State or Province Name   (full name)    "
stateOrProvinceName_default     = "$ST"
localityName                    = "3. Locality Name            (eg, city)     "
localityName_default            = "$L"
0.organizationName              = "4. Organization Name        (eg, company)  "
0.organizationName_default      = "$O"
organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
organizationalUnitName_default  = "$OU"
commonName                      = "6. Common Name              (eg, CA name)  "
commonName_max                  = 64
commonName_default              = "$CN"
emailAddress                    = "7. Email Address            (eg, name@FQDN)"
emailAddress_max                = 40
emailAddress_default            = ""
[ v3_req ]
basicConstraints	= CA:FALSE
keyUsage		= $PURPOSES
nsCertType 		= $CERTTYPE
EOT
# Создаём запрос на сертификацию
$REQ -new -key tmp.key -config cfg -rand $RAND -out $CN.pem 
# Этот файл лучше удалить побыстрее: мало ли чего...
rm -fr /tmp/.rnd

if [ $? -ne 0 ]; then
        echo "Failed to make a certificate due to error: $?"
        popd > /dev/null
        rm -fr $TMP
        exit $?
fi
# Подписываем сертификат сертификатом сервера

$X509 -req -in $CN.pem -CA $CA -CAkey $CAkey -CAsetserial \
     -extensions -config cfg -days $DAYS -out $OUTDIR$CN.pem 

chmod 0400 $OUTDIR$CN.pem
chown root:root $OUTDIR$CN.pem
# Шифруем секретный ключ
$RSA -in tmp.key -des3 -out $OUTDIR$CN-key.pem

chmod 0400 $OUTDIR$CN-key.pem
chown root:root $OUTDIR$CN-key.pem
# Выполняем заключительные действия
popd > /dev/null

rm -fr $TMP
echo -e "Generation complete, go to $OUTDIR and give to client $CN his certificate and \
\n private key(for windows users you should use openssl pkcs12 utility)"



Дополнительные свойства, описанные в скрипте (v3_req) означают, что клиент может использовать сертификат для подписывания и шифрации, но его сертификат не является CA сертификатом. Для CA сертификата значение basicConstraits должно быть равно CA:TRUE(об этом забывать нельзя!). Поле nsCertType определяет дополнительные назначения данного ключа(для использования в качестве клиента, подписывания, использования в почтовых сообщениях). Для CA сертификатов обычно применяют следующие значения nsCertType: sslCA, emailCA. Для ssl ключей серверов(например, апача) используется значение nsCertType = server.

Полученный таким образом сертификат клиента будет содержать информацию о поставщике сертификата (то есть о вашем сертификате организации). Клиенту необходимо будет передать его сертификат, его секретный ключ(зашифрованный!) и ваш сертификат организации. Для клиентов Micro$oft необходимо ещё и перевести сертификаты в формат PKCS#12. Для этого воспользуемся командой openssl pkcs12:

       openssl pkcs12 -export -in client.pem -inkey client-key.pem -out client.p12 \
              -name "Client certificate from our organization"


Для обратного преобразования используется синтаксис:

       openssl pkcs12 -in client.p12 -out client.pem


В выходной файл записываются сертификат клиента, ca сертификат, секретный ключ клиента(его можно зашифровать опцией -des3, -idea и.т.д.). Такое поведение позволяет использовать для вывода только формат pem(маркеры здесь обязательны!). Для экспорта сертификата организации можно воспользоваться командой pkcs12( конечно же без параметра inkey ;), можно также обработать сертификат организации base64 и сохранить в файле .cer(openssl x509 -in CA.pem -outform DER -out CA.cer).

В openssl существует компонент управления s/mime сообщениями, называющийся openssl smime. Данная утилита позволяет зашифровывать, расшифровывать, управлять ЭЦП и MIME заголовками писем. Приведу опять же несколько примеров её использования:

       openssl smime -sign -in mail.txt -text -from [email protected] -to \
             [email protected] -subject "Signed message" -signer mycert.pem -inkey \
             private_key.pem | sendmail [email protected]


Подписывает сообщение -in(в текстовом виде) и подписывает(-sign) его с помощью сертификата(-signer) и секретного ключа(-inkey). Вывод идёт непосредственно к sendmail, для этого определены MIME заголовки from, to и subject.

       openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt


Проверяет подпись в файле -in, записывает сообщение в файл -out, а полученный сертификат - в файл -signer(для проверки s/mime сообщения не требуется ничего, кроме него самого, т.к. ЭЦП s/mime содержит публичный ключ!).

       openssl smime -encrypt -in mail.txt -from [email protected] -to [email protected] \
             -subject "Encrypted message" -des3 user.pem | sendmail     \
             [email protected]


Шифрация файла -in с помощью сертификата получателя user.pem, используя алгоритм des3. Вывод программы посылается непосредственно в sendmail.

       openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey private_key.pem \
             -out mail.txt


Расшифровка файла -in с помощью секретного ключа -inkey и сертификата -recip(ваш собственный сертификат).

Есть альтернатива не указывать smime заголовки from, to и subject. Можно просто указать необходимый файл -out и добавить заголовки с помощью программы sendmail вручную. Кроме этого, есть ещё одна деталь использования smime: некоторые почтовые клиенты используют в качестве подписи вложение в формате PKCS#7(чаще всего закодированное base64). В таком случае необходимо применять smime следующим образом:

       openssl smime -verify -inform [PEM | DER] -in signature.pem[der] -content \
             mail.txt


PEM используется для стандартного формата PKCS#7, а DER заставляет произвести дополнительную обработку base64. Учтите, что в данном случае файл -in представляет собой только подпись(аттачмент), а -content - непосредственно текст письма. Можно также заставить smime подписывать сообщения подобным образом, если указать опцию -pk7out (PEM формат). Для преобразования PKCS#7 структуры из формата PEM в формат DER можно воспользоваться утилитой openssl base64(обратное преобразование достигается за счёт использования опции -d).

Итак, думаю, что для большинства операций с использованием SSL этого будет достаточно.

Openssl применяется во множестве сетевых серверов. В данной статье я бы хотел рассказать о работе с ssl апача, постфикса и курьера. Соответственно происходит шифрация трафика http, smtp и imap(pop3) протоколов. При использовании шифрации ssl обычно меняется порт, чтобы клиент мог корректно определить использование безопасного соединения. Для начала я расскажу об использовании ssl в апаче.

Апач может работать с ssl через модуль mod_ssl, который может быть скачан с www.apache-ssl.org. Для компиляции апача с данным модулем выполняем следующее:

       $ cd /usr/src/apache_1.3.x/src
       $ SSL_BASE=/usr/src/mod_ssl/ ./configure --... --enable-module=ssl


После успешной компиляции необходимо получить сертификат организации. Тут есть два пути: первый - это создать self-signed сертификат, второй - получить сертификат от trusted root CA. Скорее всего, второй вариант будет небесплатный, например, на www.thawte.com предлагают продать сертификат www сервера за 160$ сроком действия на год. С другой стороны такой способ обеспечивает полную безопасность клиента, т.к. он будет знать, что сертификат действителен. Обычно у браузеров есть набор trusted root CA, и, когда браузер получает сертификат, подписанный одним из trusted ca, то он может корректно проверить подпись и решить на её основании о действительности сертификата www сервера. Если же браузер получает self-signed сертификат, то он спрашивает у пользователя, можно ли доверять этому сертификату, т.к. в этом случае клиент не может точно определить, откуда к нему пришёл этот сертификат и не может проверить его подпись, т.к. она не входит в его trusted root ca. В качестве альтернативного варианта, если вы работаете с несколькими крупными клиентами, можно посоветовать принести каждому клиенту свой сертификат(например, на дискетке или компакте :) и вручную добавить его в trusted root CA клиента. Для работы через ssl в локальной сети обычно используются self-signed сертификаты, что естественно. Сертификат сервера обычно подписывается сертификатом организации.

Итак, сгенерируем секретный ключ RSA и self-signed сертификат организации:

       dd if=/dev/urandom of=/etc/openssl/.rnd -count 64
       openssl genrsa -rand /etc/openssl/.rnd -des3 -out /etc/openssl/org.key
       openssl req -new -key /etc/openssl/org.key -config    \
           /etc/openssl/org.cnf -out /etc/openssl/org.csr
       openssl x509 -req -signkey /etc/openssl/org.key -in /etc/openssl/org.csr \
            -extfile /etc/openssl/org.cnf -out /etc/openssl/org.crt -days 365


Пример конфига сертификата организации(CA сертификат, поэтому определяем некоторые расширения, которые указываем программе x509):

       [ req ]
       default_bits                    = 1024
       distinguished_name              = req_DN
       RANDFILE                        = ca.rnd
       extensions			= v3_req
       [ req_DN ]
       countryName                     = "1. Country Name             (2 letter code)"
       countryName_default             = RU
       countryName_min                 = 2
       countryName_max                 = 2
       stateOrProvinceName             = "2. State or Province Name   (full name)    "
       stateOrProvinceName_default     = region
       localityName                    = "3. Locality Name            (eg, city)     "
       localityName_default            = city
       0.organizationName              = "4. Organization Name        (eg, company)  "
       0.organizationName_default      = organization
       organizationalUnitName          = "5. Organizational Unit Name (eg, section)  "
       organizationalUnitName_default  = Certificate Authority
       commonName                      = "6. Common Name              (eg, CA name)  "
       commonName_max                  = 64
       commonName_default              = ""
       emailAddress                    = "7. Email Address  (eg,[email protected])"
       emailAddress_max                = 40
       emailAddress_default            = ""
       [ v3_req ]
       subjectAltName   = email:copy
       basicConstraints = CA:true
       nsComment        = "CA certificate of our organization"
       nsCertType       = sslCA


Теперь создаём сертификат сервера:

       dd if=/dev/urandom of=/etc/openssl/.rnd count=64
       openssl genrsa -rand /etc/openssl/.rnd -out /etc/openssl/httpd.key
       openssl req -new -key /etc/openssl/httpd.key -config /etc/openssl/httpd.cnf \
           -out /etc/openssl/httpd.csr


И подписываем его сертификатом организации:

       openssl x509 -req -signkey /etc/openssl/org.key -CA /etc/openssl/org.crt  \
            -extfile /etc/openssl/httpd.conf -out /etc/openssl/httpd.crt \
            -days 365


Опять же здесь нужны расширения для серверного сертификата, ещё учтите, что лучше задавать CN серверного сертификата как имя сервера:

       extensions	 = v3_req
       [ v3_req ]
       basicConstraints = CA:false
       nsComment        = "Apache server certificate"
       nsCertType       = server


И ещё одна тонкость: при создании секретного ключа сервера его лучше не шифровать. Хотя если это неообходимо в соображениях безопасности, то можно и зашифровать, но при этом апач при запуске будет спрашивать пароль секретного ключа сервера(на экране при этом ничего отображаться не будет, поэтому если вы долго ждёте запуска апача при включенном ssl и зашифрованном ключе, попробуйте ввести пароль).

После генерации сертификата начинаем настройку апача. Имеет смысл при использовании ssl создать отдельный файл конфигурации, который будет описывать параметры ssl. Также обычно создаётся виртуальный сервер ssl, который висит на 443 порту(https), в отличие от стандартных виртуальных серверов ssl сервер должен однозначно соответствовать паре ip адрес : порт(т.е. на один ipшник и порт можно повесить только один ssl виртуальный сервер). Для начала включим ssl модуль в апаче. После этого все настройки ssl полезно окружить условием <IfModule mod_ssl.c></IfModule>:

httpd.conf

       # Загружаем модуль ssl(он может находиться в modules или extramodules). Учтите,
       # если вы используете модуль mod_php, то его необходимо добавить ПОСЛЕ модуля
       # ssl, иначе последствия могут быть печальны(core dumpted)
       LoadModule ssl_module modules/libssl.so 
       AddModule mod_ssl.c
       # Добавляем некоторые MIME типы
       AddType application/x-x509-ca-cert .crt
       AddType application/x-pkcs7-crl    .crl
       AddType application/x-pkcs12-cert  .p12
       # Слушаем на порту 443(https)
       Listen 443
       # Определяем спсоб запроса пароля к секретному ключу сервера, как built-in, или
       # можно определить путь ко внешнему скрипту, но в большинстве случаев достаточно
       # built-in метода.
       SSLPassPhraseDialog builtin
       # Определяем кеширование данных ssl в файле данных(none для отключения
       # кеширования) и таймаут обновления данных в кеше. Можно использовать при
       # указании файла кеша специальный формат shm(shm:/path/file [size]), который
       # обеспечивает высокую производительность и работает через механизм shared
       # memory.
       SSLSessionCache         dbm:logs/ssl_scache
       #SSLSessionCache        none
       SSLSessionCacheTimeout  300
       # Настраиваем генератор случайных чисел, указываем метод для рандомизации.
       # Указывается два источника рандомизации: начальный(startup) и
       # инициализирующийся при присоединении клиента(connect). Возможные значения для
       # этого параметра: builtin - встроенный источник рандомизации, file:имя_файла -
       # читаются данные из файла, file:имя_файла число_байт - читается только определённое
       # число байт из файла(полезно для /dev/random и /dev/urandom)
       SSLRandomSeed startup file:/dev/random  512
       SSLRandomSeed connect file:/dev/random  512
       #SSLRandomSeed startup builtin
       #SSLRandomSeed connect builtin
       #SSLRandomSeed startup file:/dev/urandom 512
       #SSLRandomSeed connect file:/dev/urandom 512
       # Настраиваем логи ssl. Указываем файл и уровень записи в лог, возможные
       # значения уровня по возрастающему числу регистрируемых данных: none, error,
       # warn, info, trace, debug.
       SSLLog      logs/ssl_engine_log
       SSLLogLevel info


После настройки самого апача обычно приступают к настройке виртуального ssl сервера. Обычно основной сервер оставляют висеть на 80 порту, а на главной странице размещают ссылку на переход в безопасный режим(или ставят редирект, но это уж дело вкуса или политики безопасности).

vhosts.conf

       <IfModule mod_ssl.c>
       # Определяем виртуальный сервер, висящий на том же ip адресе, что и основной, но слушающий
       # на 443 порту
       <VirtualHost _default_:443>
       #  Основные настройки виртуального сервера
       DocumentRoot /var/www/html
       ServerName www.test.ru
       ServerAdmin [email protected]
       ErrorLog logs/ssl-error_log
       TransferLog logs/ssl-access_log
       # Следующая директива включает ssl для данного виртуального сервера
       SSLEngine on
       # Список доступных алгоритмов шифрования. Формат списка такой же, как и у
       # команды openssl ciphers(MEDIUM, HIGH, NULL, элементы разделяются :, исключение
       # элемента осуществляется знаком !).
       SSLCipherSuite HIGH:MEDIUM
       # Сертификат сервера. Данный сертификат должен быть в формате pem.
       SSLCertificateFile /etc/openssl/httpd.crt
       # Секретный ключ сервера, которым он будет расшифровывать данные клиента. Если
       # ключ зашифрован, то при запуске апача будет спрашиваться пароль, как
       # определено в опции SSLPassPhraseDialog.
       SSLCertificateKeyFile /etc/openssl/httpd.key
       # Следующие директивы описывают CA сертификаты. Если указан параметр
       # SSLCACertificatePath, то CA сертификаты загружаются из указанного каталога(в
       # этом каталоге должны также размещаться символические ссылки с именем
       # hash-value.N, при добавлении нового файла сертификата в данный каталог
       # необходимо воспользоваться специальным makefile, идущим вместе с модулем).
       # Если указан параметр SSLCACertificateFile, то все СА сертификаты хранятся в
       # одном pem файле(сертификаты просто записываются один за другим в данный файл
       # без всяких разделитетлей, т.к. любой сертификат имеет маркер начала и конца)
       #SSLCACertificatePath @@ServerRoot@@/conf/ssl/ssl.crt
       SSLCACertificateFile /etc/openssl/org.crt
       # Список сертификатов, которые считаются недействительными(certificate
       # revocation list - CRL) по неким причинам: по происшествии срока действия, по
       # потере секретного ключа и.т.д. Это понятие требует некоторого объяснения,
       # поэтому после данного примера я расскажу(несколько запоздало) о создании
       # такого списка. Синтаксис этих паарметров аналогичен предыдущим
       #SSLCARevocationPath @@ServerRoot@@/conf/ssl/ssl.crl
       SSLCARevocationFile /etc/openssl/ssl.crl
       # Аутентификация клиента на основании его сертификата, выданного CA(см. опцию
       # SSLCACertificate). В глобальной конфигурации я установил эту опцию в none, но
       # эта опция может быть переопределена в конкретной <Directory> или <Location>, как и сделано в
       # данном примере
       SSLVerifyClient none
       # Теперь определим некий раздел, доступ в который предоставим только
       # сотрудникам определённых отделов. Клиент должен будет послать свой сертификат,
       # который подписан одним из ca сертификатов. 
       <Location /secure>
       # Требуем от клиента посылки своего сертификата для выполнения аутентификации
       SSLVerifyClient require
       # Число шагов от сертификата клиента до CA сертификата в иерархии сертификатов
       SSLVerifyDepth  5
       # Проверка сертификата клиента. Для начала необходимо, чтобы сертификат клиента
       # был подписан одним из ca сертификатов, тогда сервер может быть уверен, что
       # сертификат клиента является действительным, кроме этого, полученный сертификат
       # не должен находиться в списке недействительных(crl) сертификатов. Синтаксис
       # данной команды с первого взгляда может показаться несколько сложным, но он
       # использует регулярные выражения, подобные перловским, и логические
       # операторы(and, or, !). В качестве переменных могут использоваться как
       # стандартные переменные, вроде REMOTE_ADDR, TIME, так и переменные ssl. Среди
       # последних imho наиболее полезны следующие: SSL_CIPHER,
       # SSL_CLIENT_S_DN_(параметры DN клиента, вроде O, OU, С и.т.д.),
       # SSL_CLIENT_I_DN_(параметры DN поставщика сертификата).
       SSLRequire  %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
                   and %{SSL_CLIENT_S_DN_O} eq "organization" \
                   and %{SSL_CLIENT_S_DN_OU} in {"Sysopka", "CA", "BigBosses"}
       </Location>
       # Определяем опции ssl(они могут быть переопределены в <Directory>):
       #   FakeBasicAuth:
       #   Данная опция говорит апачу, что можно использовать аутентификацию на основе
       #   сертификата, но настройки фильтрации сертификата лежат в файле .htpasswd,
       #   который выглядит примерно следующим образом:
       #   /C=RU/L=city/O=organization/OU=sysopka/CN=admin:xxj31ZMTZzkVA
       #   /C=RU/L=city/O=organization/OU=bosses/CN=my_boss:xxj31ZMTZzkVA
       #   /C=US/L=New York/O=Microsoft/OU=head/CN=Billy:xxj31ZMTZzkVA
       #   Где символы "xxj31ZMTZzkVA" - это des вариант слова password(необходимое
       #   условие), на некоторых системах нужно здесь поставить md5 хеш этого слова 
       #   $1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/.
       #   ExportCertData:
       #   Данный параметр устанавливает, что CGI скриптам будут передаваться
       #   переменные SSL_SERVER_CERT(всегда), SSL_CLIENT_CERT(если клиент послал свой
       #   сертификат), которые содержат сертификаты сервера и клиента соответственно в
       #   формате pem.
       #   StrictRequire:
       #   Эта опция применяется совместно с опцией satisfy и обеспечивает запрет
       #   доступа клиента, если его сертификат не соответствует RequireSSL
       #   OptRenegotiate:
       #   Данная опция применяется только в параметрах <Directory> и заставляет ssl
       #   заново инициализировать соединение с клиентом
       #SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire
       # Переменные, устанавливаемые для некоторых браузеров. Вообще-то все браузеры
       # должны получить перед завершением ssl сеанса сообщение от сервера, что
       # соответствует стандарту, но некоторые(особенно здесь красуется ослик) очень
       # некорректно(мягко говоря) завершают работу с ssl, поэтому приходится
       # устанавливать переменную ssl-unclean-shutdown, которая говорит о том, что при
       # завершении соединения сервер не должен ни посылать сообщение, ни принимать
       # подтверждение от браузера(что тоже может делаться некоторыми браузерами).
       # Кроме этого, ослик ещё в случае ssl соединения плохо работает с keepalive
       # сообщениями(вызывая разрыв ssl соединения), поэтому приходится устанавливать
       # ещё переменную nokeepalive. У осла также есть ещё пару недостатков: он не
       # работает с адресом вроде https://192.168.1.1 и некоторые его версии не
       # поддерживают работу с sslv3. А вообще при выборе алгоритмов шифрования -
       # SSLCipherSuite - просмотрите список алгоритмов, поддерживаемых клиентским
       # браузером и исходя из этого выбирайте нужное(+) и отсекайте ненужное(-)
       SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
       # Устанавливаем специальный лог, включаем определение протокола и алгоритма
       # шифрования.
       CustomLog logs/ssl_request_log \
                 "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
       # Перезапускаем апач, если ssl оказался не включенным
       RewriteEngine on
       RewriteCond %{HTTPS} !=on
       RewriteOptions inherit
       </VirtualHost>
       </IfModule>


Для проверки работы сервера ssl обычно применяется утилита openssl s_client, которая эмулирует поведение ssl клиента(фактически, ssl telnet): openssl s_client -connect ww.test.ru:443 [-cert file] [-debug] [-ciphers list] Клиент может передать серверу сертификат(аутнентификация по сертификату), указав опцию -cert, опция -debug включает в вывод дополнительную отладочную информацию, включая hex дампы каждого пакета. Для проверки апача можно также применить свой любимый браузер(мой любимый - lynx):

       lynx https://www.test.ru


При этом в лог записывается примерно следующее(если сервер настроен парвильно):

       [10/Nov/2002 17:41:34 04803] [info]  Connection to child 0 established (server localhost.localdomain:443, client 127.0.0.1)
       [10/Nov/2002 17:41:34 04803] [info]  Seeding PRNG with 23177 bytes of entropy
       [10/Nov/2002 17:41:35 04803] [info]  Connection: Client IP: 127.0.0.1, Protocol: TLSv1, Cipher: EDH-RSA-DES-CBC3-SHA (168/168 bits)
       [10/Nov/2002 17:41:35 04803] [info]  Initial (No.1) HTTPS request received for child 0 (server localhost.localdomain:443)
       [10/Nov/2002 17:41:35 04803] [info]  Connection to child 0 closed with standard shutdown (server localhost.localdomain:443, client 127.0.0.1) 


Итак, могу привести парочку примеров применения ssl соединений: во-первых - это любые процедуры конфиденциальной регистрации, во-вторых, возможность организации защищённого веб-интерфейса для почты, в-третьих, работа с клиентами данной фирмы, в-четвёртых, для защиты некоторых мест от посторонних взглядов(это несоизмеримо безопаснее, чем парольная аутентификация!) и подмены ipшника, в-пятых, для организации собственного CA. Вообще агентства по выдаче персональных сертификатов работают по следующей схеме: пользователь заходит на сайт и просит сертификата, после чего устанавливается безопасное соединение, и клиент заполняет форму регистрации(включая пароль секретного ключа), после этого создаётся запрос на сертификацию(на сервере), и на основе сертификата организации создаётся сертификат клиента. После этого обычно сертификат клиента перегоняется в pkcs#12 формат и записывается на диск. Пользователю же по мылу отправляется ссылка на полученный сертификат. Этот несчастный клиент проходит по ссылке, вводит своё имя и пароль(в безопасном режиме - https) и перенаправляется к своему сертификату. Браузер, получив сертификат, проверяет его подпись и после запроса помещает в хранилище личных сертификатов. Я здесь не буду приводить готового решения, т.к. это дело очень творческое(да и влом мне :) и создать вышеописанное не представляет труда, только надо немного поработать(написать скриптик, оформить всё это безобразие, организовать мыльную связь и.т.д.).

А теперь расскажу об одном непременном атрибуте каждого СА: создания списка недействительных сертификатов(чтобы не переполнять текст, буду далее применять обозначение CRL). По истечении определённого срока сертификат становится недействительным. Если это сертфика сотрудника, то после его увольнения сертификат также необходимо считать недействительным(а если уволили вас? ;). Если секретный ключ сертификата стал достоянием общественности, то и его вносят в CRL. Для управления CRL можно использовать утилиту openssl ca. Для начала создаём crl:

       openssl ca -gencrl -out crl.pem


Затем просто отменяем нужные(точнее говря не нужные) сертификаты командой openssl ca -revoke bad_cert.pem

После каждого применения revoke необходимо обновлять CRL командой openssl -gencrl. Для применения внутри СА необходимо дать клиентам возможность отменять их сертификаты, для этого необходимо предоставить им доступ к CRL. Если же вы используете аутентификацию через сертификаты, то пользователям необходимо понять, как опасно потерять секретный ключ. Ещё способ давать пароль для секретного ключа с помощью /dev/random, закодированного base64 и сообщать пароль клиенту только лично(можно также поиграться со временем действия сертификата клиента, но зачастую это может сильно увеличить геморройность работы, если вам необходимо раздавать сертификаты лично).

Теперь настало время обратиться к защите почтовых серверов. Одним из наиболее удобных вариантов является использование courier в качестве pop3 и imap серверов, а в качестве MTA использовать postfix. Итак, начнём с курьера.

Курьер поставляется с грамотным конфигом, поэтому у меня всё заработало сразу же безо всяких проблем с настройкой. Единственное, что необходимо учесть, так это что сертфикат почтового сервера должен быть подписан CA сертификатом(по умолчанию при сборке курьера генерится self-signed сертификат, но я бы рекомендовал создать сертификат, как это было сделано в апаче или воспоьзовавшись моим скриптиком CA, только необходимо изменить настройки extensions). Кроме этого, сертификат организации, которым был подписан ключ сервера, должен находится среди доверенных сертификатов почтового клиента. Я всё же расскажу о некоторых полезных опциях конфигурации couriera(imapd и pop3d):

imapd-ssl

       # Запускаем работу механизма ssl для imap сервера. В файлах esmtpd-ssl,
       # pop3d-ssl можно также устанавливать эту опцию для конкретного сервера(например
       # ESMTPDSSLSTART...)
       IMAPDSSLSTART=YES
       # Порт для безопасного соединения(по умолчанию порт не определён, но обычно
       # используются следующие значения: IMAPS - 993, POPS - 995 и SMTPS - 465). Адрес
       # задается как ipшник
       SSLPORT=993 
       SSLADDRESS=0
       # PID файл для ssl сервера
       SSLPIDFILE=/var/run/courier/imapd[pop3d, esmtpd]-ssl.pid 
       # Использование улучшенного протокола tls, по умолчанию выключено, но у меня
       # всё работало нормально с включением расширений tls. TLS используется, если 
       # необходимо использовать особый ssl порт, т.е. позволяет использовать
       # особый порт для работы ssl.
       IMAPDSTARTTLS=YES
       # Заставляет работать механизм tls в любых случаях(по умолчанию).
       IMAP_TLS_REQUIRED=0
       ###############################################################################
       # Далее идут дополнительные настройки работы ssl. Обычно они используются при #
       # включенной опции STARTTLS.						      #
       ###############################################################################
       # Вспомогательная программа, использующаяся при работе с ssl. На этапе
       # компиляции она создаёт простой сертификат(который, впрочем, у меня не работал,
       # поэтому я сразу же создал нужны мне правильный сертификат), а затем по идее
       # должна использоваться для аутентификации клиентов, но, как я понял, работать
       # подобным образом это ещё не работает(не забывайте, что курьер - это довольно
       # молодой продукт), но всё же укажем эту опцию на всякий случай...
       COURIERTLS=/usr/bin/couriertls
       # Определение версии используемого протокола ssl:
       # SSL2 - SSLv2
       # SSL3 - SSLv3
       # TLS1 - TLS1
       TLS_PROTOCOL=SSL3
       # Данная опция рассматривается, как механизм работы ssl, если определён параметр
       # STARTTLS=YES
       TLS_STARTTLS_PROTOCOL=TLS1
       # Список алгоритмов шифрации. Можно не трогать данный параметр и оставить его по
       # умолчанию - и так сработает
       # TLS_CIPHER_LIST="ALL:!ADH:RC4+RSA:+SSLv2:@STRENGTH"
       # Сертификат сервера(pem формат). Внутри данного файла должны содержаться
       # сертификат и НЕЗАШИФРОВАННЫЙ секретный ключ, поэтому доступ к данному файлу на
       # чтение должен быть предоставлен только пользователю courier.
       TLS_CERTFILE=/etc/openssl/imapd.pem
       # Следующий параметр определяет путь к каталогу(или файлу), содержащему
       # "доверенные" сертификаты(если я правильно понял, то это СА сетрификаты, но
       # здесь я могу ошибаться). Сервер использует данные сертификаты, если
       # опция TLS_VERIFYPEER установлена в PEER или REQUIREPEER. Честно говоря, с этим
       # я разобрался не до конца, да и сами разработчики курьера не очень-то советуют
       # использовать данную опцию по причине 
       #TLS_TRUSTCERTS=/etc/openssl/ca.pem
       # А вот это та самая опция аутентификации через сертификаты, она может принимать
       # следующие значения:
       #
       # NONE - не проверяем сертификат клиента вовсе
       #
       # PEER - проверяем сертификат клиента, если последний передал его серверу
       #
       # REQUIREPEER - проверяем сертификат клиента и запрещаем вход, если клиент не
       # предоставил сертификата(или сертификат неверный)
       TLS_VERIFYPEER=NONE 


Думаю, что дальнейшая настройка курьера не должна вызвать проблем(IMHO courier - один из самых простых в настройке почтовых служб, т.к. все переменные внутри его конфигов фактически имеют тот же синтаксис, что и переменные в shell).

Другой популярный мыльный сервер - postfix - также легко поддаётся бронированию с помощбю ssl. Сразу же приведу пример настройки smtpd postfixa, который использует при передаче почты механизм ssl:

main.cf:

       # Создаём стандартный серверный сертификат(как было уже несколько раз описано) и
       # незашифрованный секретный ключ. Указываем далее к ним путь
       smtpd_tls_cert_file = /etc/openssl/smtpd.pem
       smtpd_tls_key_file = /etc/openssl/smtpd.key
       # Указываем также путь к trusted root CA файлу(pem формат)
       # Можно также указать путь к каталогу с ca сертификатами, но тут возникают
       # проблемы с хеш-файлами(я их уже описывал при разговоре об апаче)
       smtpd_tls_CAfile = /etc/openssl/ca.pem
       # Уровень записи в лог. Меняется от 0 до 4:
       # 0 - забиваем на логи
       # 1 - выводим информацию о сертификатах при установке соединения
       # 2,3,4 - различная дополнительная инфа(вроде hex дампов пакетов и.т.д.)
       # Рекоммендуется использовать значение 1 или 2.
       smtpd_tls_loglevel = 1
       # По умолчанию механизм ssl не включён - включаем его.
       smtpd_use_tls = yes
       # Установкой следующей опции в yes(по умолчанию - no) можно добиться того, что
       # все команды smtp сервера будут выполняться в ssl режиме(это не подходит для
       # серверов, которые предоставляют обе услуги: защищённое мыло и стандартное).
       # smtpd_enforce_tls = no
       # Запрос на сертификат клиента. Я здесь не буду останавливаться, т.к. вряд ли
       # кто будет применять этот ужас(тем более я не видел ни одного клиента,
       # способного выполнить аутентификацию по сертификату). Поэтому лучше оставить
       # эту опцию по умолчанию в no(это также касается и опции smtpd_tls_req_ccert) 
       # smtpd_tls_ask_ccert = no
       # Для совместимости со старыми версиями postfix принимается команда AUTH без
       # шифрования, что создаёт угрозу безопасности, установка следующей опции в yes
       # говорит, что шифрование будет производиться только для команды AUTH. Для
       # полного шифрования всего траффика используйте опцию smtpd_enforce_tls
       # smtpd_tls_auth_only = no
       # Файл кеша ssl для сервера. Поддерживается только формат sdbm, т.к. необходима
       # поддержка одновременной записи нескольких процессов в данный файл
       smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache
       # Тайм-аут для кеша
       smtpd_tls_session_cache_timeout = 3600s
       # Традиционный список используемых алгоритмов
       # smtpd_tls_cipherlist = DEFAULT
       # Тайм-аут длительности соединения ss
       smtpd_starttls_timeout = 270s
       # Установки генератора случайных чисел. Используются стандартные устройства
       # рандомизации или egd генератор. Устанавливаться может также число считываемых
       # байт и время обновления установки генератора случайных чисел.
       tls_random_source = dev:/dev/urandom


Также необходимо создать запись в master.cf, чтобы указать postfix слушать smtps порт(кроме этого заставляем на порту smtps использовать полную шифрацию передаваемого трафика)

       # tls_random_source = egd:/var/run/egd-pool
       # tls_random_bytes = 32
       # tls_random_reseed_period = 3600s
       # service type  private unpriv  chroot  wakeup  maxproc command + args
       #               (yes)   (yes)   (yes)   (never) (50)
       smtps     inet  n       -       y       -       -       smtpd -o smtpd_enforce_tls=yes


Вместо имени сервиса можно указать номер порта(обычно 465).

Sendmail также обладает возможностью использования ssl, но я не являюсь специалистом по sendmail(наверное, виной тому паталогическая лень и наличие более простых в освоении инструментов).

SSL, похоже, будет всё больше и больше использоваться в сети, защищая стандартные протоколы. Поэтому каждый администратор должен знать принципы работы с ssl. И если я помог кому-то в освоении данной темы, то могу считать свою задачу выполненной!

Приведу некоторые ссылки:

http://www.openssl.org -- основной сайт с документацией и исходниками openssl
http://www.apache-ssl.org -- домашняя страница mod_ssl апача
http://www.postfix.org  -- страница производителей postfix
http://www.lothar.com/tech/crypto/ -- страница генератора энтропии EGD
http://www.thawte.com -- одна из коммерческих фирм, предоставляющих сертификаты

И ещё информация для тех, кто решил работать с ssl: не так давно в механизме openssl были обнаружены уязвимости, поэтому не поленитесь сходить на http://www.openssl.org за последними патчами.