Обзор библиотеки OpenSSL / Часть вторая

Это продолжение статьи meego.e-werest.org/blog/general/2893.html


openssl req

Для создания сертификата используется команда 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=Leningrad		        # Область
	L=Spb				# Город
	O=osll				# Название организации
        OU=osll-dev			# Название отделения
        CN=Your personal certificate	# Имя для сертификата
	emailAddress=osll@spb.ru 	# e-mail организации



Если не указывать 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 (city)
      organizationName        = Organization Name (org)
      organizationalUnitName	= Organizational Unit Name (section)
      commonName		= Common Name (YOUR name)
      commonName_max		= 64
      emailAddress		= Email Address
      emailAddress_max	= 40




Примеры



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

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

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

$ openssl req -x509 -new -key private_key.pem -config cfg -out selfcert.pem -days 365


openssl x509



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


Примеры



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

$ openssl x509 -in cert.pem -noout -text

Certificate:
          Data:
              Version: 3 (0x2)
              Serial Number: 0 (0x0)
              Signature Algorithm: md5WithRSAEncryption
              Issuer: C=RU, ST=Leningrad, L=Spb, O=osll, OU=osll-dev,
       CN=OSLL/Email=osll@spb.ru
              Validity
                  Not Before: Nov  9 08:51:03 2002 GMT
                  Not After : Nov  9 08:51:03 2003 GMT
              Subject: C=RU, ST=Leningrad, L=Spb, O=osll, OU=osll-dev,
       CN=OSLL/Email=osll@spb.ru 
              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:
<skip>
                      Exponent: 65537 (0x10001)
              Signature Algorithm: md5WithRSAEncryption
               1e:c1:ff:39:28:4f:84:19:f8:3e:38:ef:98:34:d6:ee:e0:0a:
<skip>
              09:c2





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

$ 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

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

$ openssl x509 -in CAcert.pem -addtrust sslclient -alias “myorganization CA” -out CAtrust.pem


Пример создания сертификата x.509 на основе эллиптических кривых

Рассмотрим пример создания сертификата x.509 на основе эллиптических кривых. Криптография на основе эллиптических кривых работает на много раз быстрее RSA и при меньшей длине ключа обеспечивает большую стойкость к взлому. Однако данный вид шифрования слабо распространен.

На Рис. 1 приведено сравнение необходимых длин ключей для обеспечения сравнимой стойкости к взлому для различных алгоритмов.

Рис. 1. Сравнение длин ключей алгоритмов

Рис. 1. Сравнение длин ключей алгоритмов

На Рис. 1 видно, что ключам RSA длиной 1024-2048 бит, соответствует всего 160-224 битный ключ ECC (Elliptic Curve Cryptography).

Определимся, какой длины ключ нам нужен. В ECC определенной длине ключа соответствуют определенные параметры кривой.

Посмотреть список доступных кривых можно командой:

$ openssl ecparam -list_curves



Для создания сертификата нам необходимо:

  1. Сгенерировать корневой самоподписный сертификат (CA);
  2. Сгенерировать клиентский сертификат;
  3. Подписать клиентский сертификат серверным.


Генерируем корневой сертификат

1. Генерируем ключ для корневого сертификата:

$ openssl ecparam -name secp521r1 -genkey -out CA.key


   -----BEGIN EC PARAMETERS-----
   BgUrgQQAIw==
   -----END EC PARAMETERS----
   -----BEGIN EC PRIVATE KEY-----
   MIHcAgEBBEIBrtyWCH0+OAZqbr84CLFvsxbB2/AfjKD6+fpXQF5qs7n1yRmxItRH
<skip>
   XlkYPvEKRkQDLJP22vXE/NEirdZ/WzO6QTWku5q0UQ==
   -----END EC PRIVATE KEY-----'





Вначале идут параметры кривой (её название secp521r1), а потом сгенерированный на её основе ключ.



2. Защищаем его паролем (шифруем по алгоритму AES с длиной ключа 256 бит):

$ openssl ec -in CA.key -out ca.protected.key -aes256


   -----BEGIN EC PRIVATE KEY-----
   Proc-Type: 4,ENCRYPTED
   DEK-Info: AES-256-CBC,E34E27512B4DCB01524A5F17937DA7D5
<skip>
   sE71UwiaIddFHkOe3UnlAxjohABpZytUud8uS0Wi+5E=
   -----END EC PRIVATE KEY-----




Генерируем запрос на сертификат



Запрос — это структура из открытого ключа, его хеша и данных о владельце сертификата. Алгоритм хеширования ключа выбираем SHA512:

$ openssl req -new -key ca.protected.key -sha512 -out CA.req


   -----BEGIN CERTIFICATE REQUEST-----
   MIIBrzCCARACAQAwazELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0G
<skip>
   SpXtPgYEEelkOm3Ua+/0XVoZviBT7wF5nrqTYnMJ2MQtyvKKMCO74qqUiMoudZ7z
   MSgO
   -----END CERTIFICATE REQUEST-----




Подписываем закрытым ключом

Подписываться будет не весь запрос, а только его хеш, поэтому мы на предыдущем шаге указывали какой алгоритм хеширования выбрать.



1. Изменить в openssl.cfg в разделе [CA_default] dir на «путь_к_сертификату» вместо ./DemoCA.

2. В папке сертификата создать 2 файла: пустой index.txt и файл serial, в который записать 01 без пробелов и переносов строк.

3. Выполнить команду:

$ openssl ca -days 365 -policy policy_anything -keyfile CA.protected.key -in CA.req -selfsign -out ca.crt -outdir.



На вход мы подаем запрос на сертификат, закрытый ключ и говорим, что сертификат будет самоподписанным (-selfsign). На выходе получаем сертификат ca.crt.


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: ecdsa-with-SHA1
        Issuer: C=RU, ST=Spb, L=Spb, O=osll, OU=IT, CN=osll.spb.ru
        Validity
            Not Before: Jun 11 05:12:03 2010 GMT
            Not After : Jun 11 05:12:03 2011 GMT
        Subject: C=RU, ST=Spb, L=Spb, O=osll, OU=IT, CN=osll.spb.ru
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (521 bit)
                pub: 
                    04:01:31:f8:e4:da:b3:7f:dd:8f:11:4c:5b:b1:8d:
<skip>
                    ad:d6:7f:5b:33:ba:41:35:a4:bb:9a:b4:51
                ASN1 OID: secp521r1
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                3D:FF:46:92:1C:7E:C1:F3:84:D0:26:BA:CD:5D:AD:25:B8:CC:DE:44
            X509v3 Authority Key Identifier: 
                keyid:3D:FF:46:92:1C:7E:C1:F3:84:D0:26:BA:CD:5D:AD:25:B8:CC:DE:44
    Signature Algorithm: ecdsa-with-SHA1
        30:81:88:02:42:01:bf:ca:f1:4c:51:85:b4:65:26:de:eb:14:
<skip>
        2b:68:94:9d:0d:8c:89:aa:b9:1d:e8:a2:05
-----BEGIN CERTIFICATE-----
MIICxjCCAiigAwIBAgIBATAJBgcqhkjOPQQBMGsxCzAJBgNVBAYTAlJVMQ8wDQYD
<skip>
PDevVDl43q7Z11Vv3sycdc/Vjo7MLQza0b7FjS0raJSdDYyJqrkd6KIF
-----END CERTIFICATE-----





Таким же образом можно сгенерировать сертификат для клиента. Весь процесс состоит из трёх шагов, рассмотрим их:

  1. $ openssl ecparam -name secp521r1 -genkey -out Client.key
  2. $ openssl ec -in Client.key -out Client.protected.key -aes256
  3. $ openssl req -new -key Client.protected.key -sha512 -out Client.req



Шаг 3 отличается тем, что на вход подается сертификат CA, закрытый ключ CA, клиентский запрос и убирается параметр –selfsign:

$ openssl ca -days 365 -policy policy_anything -keyfile CA.protected.key -cert CA.crt -in Client.req -out Client.crt -outdir.


SMIME



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


Примеры

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



$ openssl smime -sign -in mail.txt -text -from osll@spb.ru -to user@mail.ru -subject “Signed message” -signer mycert.pem -inkey private_key.pem | sendmail user@mail.ru



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



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



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



$ openssl smime -encrypt -in mail.txt -from osll@spb.ru -to user@mail.ru -subject “Encrypted message” -des3 user.pem | sendmail user@mail.ru



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



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



Есть альтернатива не указывать 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 представляет собой только подпись (attachment), а -content непосредственно текст письма. Можно также заставить smime подписывать сообщения подобным образом, если указать опцию -pk7out (PEM формат).

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


Вспомогательные утилиты OpenSSL



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



— Тестирование скорости различных алгоритмов, если запускать без параметров, то тестируются все алгоритмы; алгоритмы внутри списка разделяются пробелом, например openssl speed md5 rsa idea blowfish des 3des sha1. В конце работы выводится общая скорость работы различных алгоритмов (в 1000-х байт в секунду), для обработки различной длины блоков.



$ openssl rand -out file -rand file num



— Генерация num рандомных байт, можно использовать для проверки случайной последовательности rand.



$ openssl ciphers -ssl2 -ssl3 -tls1 NAME



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

Обычно в настоящее время используются алгоритмы групп MEDIUM и HIGH, которые ещё долго не смогут быть взломаны прямым перебором. Можно также вывести список алгоритмов из нескольких групп, разделив их “:” (например, MEDIUM:HIGH)



Стоит отметить, что начиная с версии 1.0.0, включена поддержка российских алгоритмов ГОСТ.



Kirill Yudenok / OSLL (osll.fruct.org/)