OpenSSL
Материал из Xgu.ru
OpenSSL — универсальный криптографический инструмент,
построенный вокруг протоколов SSL/TLS и сертификатов X.509.
Помимо того, что этот инструмент позволяет работать с соединениями SSL/TLS, сертификатами X.509, он может делать множество других полезных вещей: шифровать и расшифровывать файлы, создавать и проверять цифровые подписи, проверять числа на простоту, тестировать производительность компьютера и другое.
Вопросы и ответы
- Раздел написан на основе OpenSSL Command-Line HOWTO[1]
Введение
Как определить какую версию OpenSSL я использую?
Использовать опцию version:
$ openssl version OpenSSL 0.9.8b 04 May 2006
Расширенная информация с опцией -a:
$ openssl version -a OpenSSL 0.9.8b 04 May 2006 built on: Fri Sep 29 18:45:58 UTC 2006 platform: debian-i386-i686/cmov options: bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -march=i686 -Wa,--noexecstack -g -Wall -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2 -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM OPENSSLDIR: "/usr/lib/ssl"
Как получить список доступных команд?
Вызвать с неправильным ключом (например, help или -h).
$ openssl help openssl:Error: 'help' is an invalid command. Standard commands asn1parse ca ciphers crl crl2pkcs7 dgst dh dhparam dsa dsaparam ec ecparam enc engine errstr gendh gendsa genrsa nseq ocsp passwd pkcs12 pkcs7 pkcs8 prime rand req rsa rsautl s_client s_server s_time sess_id smime speed spkac verify version x509 Message Digest commands (see the `dgst' command for more details) md2 md4 md5 rmd160 sha sha1 Cipher commands (see the `enc' command for more details) aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc aes-256-ecb base64 bf bf-cbc bf-cfb bf-ecb bf-ofb cast cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb des3 desx rc2 rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb rc4 rc4-40
Аналогично с подкомандами:
$ openssl dgst -h unknown option '-h' options are -c to output the digest with separating colons -d to output debug info -hex output as hex dump -binary output in binary form -sign file sign digest using private key in file -verify file verify a signature using public key in file -prverify file verify a signature using private key in file -keyform arg key file format (PEM or ENGINE) -signature file signature to verify -binary output in binary form -engine e use engine e, possibly a hardware device. -md5 to use the md5 message digest algorithm (default) -md4 to use the md4 message digest algorithm -md2 to use the md2 message digest algorithm -sha1 to use the sha1 message digest algorithm -sha to use the sha message digest algorithm -sha256 to use the sha256 message digest algorithm -sha512 to use the sha512 message digest algorithm -mdc2 to use the mdc2 message digest algorithm -ripemd160 to use the ripemd160 message digest algorithm
Как посмотреть список доступных шифров?
Использовать команду ciphers:
# все доступные шифры openssl ciphers -v # только шифры TLSv1 openssl ciphers -v -tls1 # только шифры длиною больше 128 битов (high ciphers) openssl ciphers -v 'HIGH' # только шифры длиною больше 128 битов, использующие AES openssl ciphers -v 'AES+HIGH'
Измерение производительности
Как измерить производительность системы с помощью openssl?
Общая производительность:
openssl speed
Пример для 2.16GHz Intel Core 2.
The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes md2 1736.10k 3726.08k 5165.04k 5692.28k 5917.35k mdc2 0.00 0.00 0.00 0.00 0.00 md4 18799.87k 65848.23k 187776.43k 352258.73k 474622.63k md5 16807.01k 58256.45k 160439.13k 287183.53k 375220.91k hmac(md5) 23601.24k 74405.08k 189993.05k 309777.75k 379431.59k sha1 16774.59k 55500.39k 142628.69k 233247.74k 288382.98k rmd160 13854.71k 40271.23k 87613.95k 124333.06k 141781.67k rc4 227935.60k 253366.06k 261236.94k 259858.09k 194928.50k des cbc 48478.10k 49616.16k 49765.21k 50106.71k 50034.01k des ede3 18387.39k 18631.02k 18699.26k 18738.18k 18718.72k idea cbc 0.00 0.00 0.00 0.00 0.00 rc2 cbc 19247.24k 19838.12k 19904.51k 19925.33k 19834.98k rc5-32/12 cbc 0.00 0.00 0.00 0.00 0.00 blowfish cbc 79577.50k 83067.03k 84676.78k 84850.01k 85063.00k cast cbc 45362.14k 48343.34k 49007.36k 49202.52k 49225.73k aes-128 cbc 58751.94k 94443.86k 111424.09k 116704.26k 117997.57k aes-192 cbc 53451.79k 82076.22k 94609.83k 98496.85k 99150.51k aes-256 cbc 49225.21k 72779.84k 82266.88k 85054.81k 85762.05k sha256 9359.24k 22510.83k 40963.75k 51710.29k 56014.17k sha512 7026.78k 28121.32k 54330.79k 86190.76k 104270.51k sign verify sign/s verify/s rsa 512 bits 0.000522s 0.000042s 1915.8 23969.9 rsa 1024 bits 0.002321s 0.000109s 430.8 9191.1 rsa 2048 bits 0.012883s 0.000329s 77.6 3039.6 rsa 4096 bits 0.079055s 0.001074s 12.6 931.3 sign verify sign/s verify/s dsa 512 bits 0.000380s 0.000472s 2629.3 2117.9 dsa 1024 bits 0.001031s 0.001240s 969.6 806.2 dsa 2048 bits 0.003175s 0.003744s 314.9 267.1
Каждый тест можно вызывать отдельно:
# проверить скорость rsa openssl speed rsa # проверить то же самое на 2-процессорной системе openssl speed rsa -multi 2
Как измерить производительность сетевого соединения?
openssl s_time -connect remote.host:443
Помимо этого простейшего измерения у подкоманды s_time есть множество других возможностей:
# получить удалённую страницу test.html, используя только новые сеансы openssl s_time -connect remote.host:443 -www /test.html -new # аналогично, но только используя SSLv3 и сильное шифрование # (подробности относительно шифрования в ciphers(1)) openssl s_time \ -connect remote.host:443 -www /test.html -new \ -ssl3 -cipher HIGH # сравнить относительную производительность разных шифров # 10-секундные тесты IFS=":" for c in $(openssl ciphers -ssl3 RSA); do echo $c openssl s_time -connect remote.host:443 \ -www / -new -time 10 -cipher $c 2>&1 | \ grep bytes echo done
Сэмулировать web-сервер с помощью openssl s_server:
# запустить сервер (на порту 4433) openssl s_server -cert mycert.pem -www # на втором хосте (или даже этом же) запустить s_time openssl s_time -connect myhost:4433 -www / -new -ssl3
Сертификаты
Как сгенерировать самоподписной сертификат?
Создать файл mycert.pem, в котором будет и секретный ключ и открытый сертификат, основанный на нём. Сертификат будет действителен в течение 365 дней; ключ (благодаря опции -nodes) будет нешифрованным.
openssl req \ -x509 -nodes -days 365 \ -newkey rsa:1024 -keyout mykey.pem -out mycert.pem
После вызова команды надо будет ответить на несколько вопросов: Country Name, State, City и так далее. На вопрос “Common Name” нужно отвечать именем сервера, по которому будут обращаться люди.
Можно автоматизировать ввод ответов с помощью опции -subj.
openssl req \ -x509 -nodes -days 365 \ -subj '/C=US/ST=Oregon/L=Portland/CN=www.madboa.com' \ -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
Как сгенерировать запрос сертификата у VeriSign?
Секретный ключ в файле mykey.pem и запрос на сертификат myreq.pem:
openssl req \ -new -newkey rsa:1024 -nodes \ -keyout mykey.pem -out myreq.pem
Если ключ уже есть, и его надо использовать только для генерации сертификата, используется команда попроще:
openssl req -new -key mykey.pem -out myreq.pem
Или, с информацией для сертификата прямо в командной строке:
openssl req \ -new -newkey rsa:1024 -nodes \ -subj '/CN=www.mydom.com/O=My Dom, Inc./C=US/ST=Oregon/L=Portland' \ -keyout mykey.pem -out myreq.pem
Не допускайте ошибок в названиях! Каждый символ важен.
Проверка:
# проверить подпись openssl req -in myreq.pem -noout -verify -key mykey.pem # проверить информацию openssl req -in myreq.pem -noout -text
Файл с ключом нужно сохранить в надёжном месте.
Как проверить новый сертификат?
Подкоманда s_server предоставляет простой, но эффективный метод тестирования. В примерах ниже предполагается, что ключ и сертификат хранятся в файле mycert.pem.
Запустите тестовый сервер на машине, на которой будет использоваться сертификат. По умолчанию, открывается порт 4433; другой порт можно задать опцией -accept.
openssl s_server -cert mycert.pem -www
Если команда запустилась без ошибок, открывайте в браузере страницу: https://127.0.0.1:4433/
Как получить удалённый сертификат?
С помощью openssl и sed:
#!/bin/sh # # usage: retrieve-cert.sh remote.host.name [port] # REMHOST=$1 REMPORT=${2:-443} echo |\ openssl s_client -connect ${REMHOST}:${REMPORT} 2>&1 |\ sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
Можно вернуть данные openssl, например, для того чтобы выяснить, для каких дат он действителен:
#!/bin/sh # for CERT in \ www.yourdomain.com:443 \ ldap.yourdomain.com:636 \ imap.yourdomain.com:993 do echo |\ openssl s_client -connect ${CERT} 2>/dev/null |\ sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\ openssl x509 -noout -subject -dates done
Как извлечь какую-либо информацию из сертификата?
В SSL-сертификате есть много информации, в частности:
- кто выдал сертификат (issuer);
- насколько долго он действителен (valid dates);
- получатель сертификата (subject);
- разнообразная криптографическая информация.
Опция текст даёт весь объём информации:
openssl x509 -text -in cert.pem
Другие опции дают другую информацию:
# кто его выдал? openssl x509 -noout -in cert.pem -issuer # кому его выдали? openssl x509 -noout -in cert.pem -subject # до какой даты он действителен? openssl x509 -noout -in cert.pem -dates # всё вышеперечисленное: openssl x509 -noout -in cert.pem -issuer -subject -dates # какой у него хэш? openssl x509 -noout -in cert.pem -hash # какой у него отпечаток MD5? openssl x509 -noout -in cert.pem -fingerprint
Извлечение открытого ключа, который требуется для проверки цифровой подписи (дайджеста):
openssl x509 -noout -in cert.pem -pubkey > pubkey.pem
Как экспортировать или импортировать сертификат PKCS#12?
Файлы PKCS#12 используются в разных приложениях типа MS IIS. Они часто имеют расширение .pfx.
# создать файл, содержащий ключ и самоподписной сертификат openssl req \ -x509 -nodes -days 365 \ -newkey rsa:1024 -keyout mycert.pem -out mycert.pem # экспортировать mycert.pem как файл PKCS#12, mycert.pfx openssl pkcs12 -export \ -out mycert.pfx -in mycert.pem \ -name "My Certificate"
Превратить pfx в pem:
# export certificate and passphrase-less key openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes # same as above, but you’ll be prompted for a passphrase for # the private key openssl pkcs12 -in mycert.pfx -out mycert.pem
Проверка сертификата
Приложения, слинкованные с библиотеками OpenSSL, могут проверять подлинность сертификатов, выданных сервером сертификатов (certificate authority, CA).
Как проверить сертификат?
Использовать подкоманду verify:
openssl verify cert.pem
Если в сертификате всё в норме, то будет выдано сообщение OK:
$ openssl verify remote.site.pem remote.site.pem: OK
Если чего-то не хватает, появятся соответствующие сообщения об ошибках, например:
- error 10 at 0 depth lookup:certificate has expired. Время действия сертификата истекло.
- error 18 at 0 depth lookup:self signed certificate. Если не указать явным образом, openssl не будет проверять самоподписные сертификаты (self-signed certificate).
Какие центры сертификации распознаёт OpenSSL?
При сборке OpenSSL в нём настраивается местоположение OpenSSL-файлов (Directory for OpenSSL files). Этот параметр задаётся опцией --openssldir, передающейся конфигурационному скрипту. В этом каталоге, как правило, хранится информация о центрах сертификации, которым доверяет система.
По умолчанию, этот каталог находится в /usr/local/ssl, но большинство сборщиков размещает его в других местах, таких как /etc/pki/tls (Red Hat/Fedora), /etc/ssl (Gentoo), /usr/lib/ssl (Debian) или /System/Library/OpenSSL (Macintosh OS X).
Посмотреть, какой именно каталог используется в конкретной инсталляции, можно с помощью опции version(параметр OPENSSLDIR):
openssl version -d
Внутри данного каталога есть подкаталог certs/, в котором находятся файлы трёх разных типов:
- Большой файл под названием cert.pem, объёмистый сборник многих сертификатов от признанных общеизвестных центров сертификации, таких как VeriSign и Thawte.
- Множество маленьких файлов с расширением .pem, каждый из которых содержит сертификат от отдельного центра сертификации;
- Символические ссылки в со странными именами вида 052eae11.0. Как правило, для каждого .pem-файла есть такая ссылка.
Первая часть странного имени ссылки — это, на самом деле, хэш, основанный на сертификате внутри .pem-файла, на который эта ссылка указывает. Расширение файла это итератор (то есть, номер), поскольку теоретически возможно, что разные сертификаты укажут на одинаковый хэш.
Например, ссылка f73e89fd.0 указывает на файл vsignss.pem. Значит, сертификат соответствует хэшу, который равен имени ссылки:
$ openssl x509 -noout -hash -in vsignss.pem f73e89fd
Когда приложение получает удалённый сертификат, оно сначала проверяет, есть ли этот сертификат в cert.pem и, если нет, смотрит в файле, соответствующем хэшу сертификата. Если такой файл найден, сертификат считается верным.
Нужно иметь в виду, что некоторые приложения, такие как Sendmail, например, позволяют во время исполнения указывать местоположение сертификатов, а некоторые, например Pine, нет.
Как мне заставить OpenSSL признавать сертификат?
Сертификат, которому нужно доверять, должен быть размещён в каталоге certs/. После этого необходимо создать хэшированную символическую ссылку на него. Вот небольшой скрипт, который делает это:
#!/bin/sh # # usage: certlink.sh filename [filename ...] for CERTFILE in "$@"; do # Убедиться, что файл существует и это сертификат test -f "$CERTFILE" || continue HASH=$(openssl x509 -noout -hash -in "$CERTFILE") test -n "$HASH" || continue # использовать для ссылки наименьший итератор for ITER in 0 1 2 3 4 5 6 7 8 9; do test -f "${HASH}.${ITER}" && continue ln -s "$CERTFILE" "${HASH}.${ITER}" test -L "${HASH}.${ITER}" && break done done
Клиенты и серверы для командной строки
Подкоманды s_client и s_server предоставляют возможность для запуска SSL-клиентов для командной строки.
Как подключиться к безопасному SMTP-серверу?
С помощью подкоманды s_client можно проверить или даже использовать SMTP-сервер с поддержкой SSL.
Безопасные SMTP-серверы могут предлагать безопасные соединения на портах: 25 (TLS), 465 (SSL) и 587 (TLS). Где-то в районе релиза 0.9.7 у openssl появила