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 появилась возможность использовать STARTTLS в ходе общения с SMTP-серверами.
# порт 25/TLS; использовать такой же синтаксис для порта 587 openssl s_client -connect remote.host:25 -starttls smtp # порт 465/SSL openssl s_client -connect remote.host:465
Чтобы использовать для обозначения конца строки именно CRLF, а не CR или LF, используется опция -crlf. Это важно особенно для Qmail.
openssl s_client -connect remote.host:25 -crlf -starttls smtp
Как подключиться к [какому-либо] безопасному серверу?
На момент написания openssl поддерживал TLS из командной строки только с SMTP, поэтому для других протоколов нужно использовать прямые SSL-соединения.
# https: HTTP over SSL openssl s_client -connect remote.host:443 # ldaps: LDAP over SSL openssl s_client -connect remote.host:636 # imaps: IMAP over SSL openssl s_client -connect remote.host:993 # pop3s: POP-3 over SSL openssl s_client -connect remote.host:995
Как запустить SSL-сервер из командной строки?
Подкоманда s_server позволяет запустить сервер с поддержкой SSL прямо из командной строки; сервер предназначен только для проверки и отладки. Для полноценной работы рекомендуется использовать stunnel.
Подкоманда s_server работает намного лучше, если есть сертификат; когда его нет, её возможности сильно сокращаются.
# при использовании опции -www # каждому HTTP-клиенту, запросившему страницу # будет отправляться статусная страничка HTML openssl s_server -cert mycert.pem -www # опция -WWW эмулирует простой web-сервер; # поиск страничек будет выполняться относительно текущего каталога # В этом примере прослушивание будет выполнять на порт 443, не на 4433 как обычно openssl s_server -accept 443 -cert mycert.pem -WWW
Дайджесты
Создание дайджестов (криптографических контрольных сумм) с помощью подкоманды dgst — одна из наиболее распространённых задач, выполняемых с помощью openssl.
Как создавать дайджесты MD5 или SHA1?
Дайджесты создаются с помощью подкоманды dgst:
# MD5 digest openssl dgst -md5 filename # SHA1 digest openssl dgst -sha1 filename
Дайджест MD5 эквивалентен дайджесту, создаваемому известной утилитой md5sum, хотя выводится в другом формате:
$ openssl dgst -md5 foo-2.23.tar.gz MD5(foo-2.23.tar.gz)= 81eda7985e99d28acd6d286aa0e13e07 $ md5sum foo-2.23.tar.gz 81eda7985e99d28acd6d286aa0e13e07 foo-2.23.tar.gz
То же верно и для дайджестов SHA1 и программы sha1sum:
$ openssl dgst -sha1 foo-2.23.tar.gz SHA1(foo-2.23.tar.gz)= e4eabc78894e2c204d788521812497e021f45c08 $ sha1sum foo-2.23.tar.gz e4eabc78894e2c204d788521812497e021f45c08 foo-2.23.tar.gz
Как подписать дайджест?
Для того, чтобы быть уверенным, что дайджест никто не изменял, его можно подписать с помощью своего закрытого ключа.
Подписать дайджест SHA1 для файла foo-1.23.tar.gz:
# подписанный дайджест будет в foo-1.23.tar.gz.sha1 openssl dgst -sha1 \ -sign mykey.pem -out foo-1.23.tar.gz.sha1 \ foo-1.23.tar.gz
Как проверить подписанный дайджест?
Для того чтобы проверить правильность дайджеста, нужен файл, на основе которого был получен дайджест, сам подписанный дайджест и открытый ключ того, кто подписывал дайджест:
# есть файл foo-1.23.tar.gz, дайджест foo-1.23.tar.gz.sha1 # и открытый ключ pubkey.pem openssl dgst -sha1 \ -verify pubkey.pem \ -signature foo-1.23.tar.gz.sha1 \ foo-1.23.tar.gz
Как создать запись типа digest для файла паролей Apache?
У web-сервера Apache есть специальный формат файла с паролями, использующийся для выполнения digest-аутентификации. В комплект с web-сервером входит утилита htdigest, но она умеет записывать данные только в файл, а не на стандартный поток вывода. При работе с удалёнными пользователями может быть целесообразным им сначала сгенерировать хэш, а потом переправить его по почте или другому каналу информации для включения в базу.
Формат базы паролей прост: список нескольких полей, разделённых двоеточиями. Поля:
- имя пользователя (username);
- область авторизации (authorization realm; AuthRealm);
- MD5-суммы для этих полей и пароля.
Скрипт, представленный ниже, повторяет действие htdigest с той разницей, что выводит данные на стандартный поток вывода. Кроме того, он умеет считывать данные со стандартного потока ввода.
#!/bin/bash echo "Create an Apache-friendly Digest Password Entry" echo "-----------------------------------------------" # get user input, disabling tty echoing for password read -p "Enter username: " UNAME read -p "Enter Apache AuthName: " AUTHNAME read -s -p "Enter password: " PWORD; echo printf "\n%s:%s:%s\n" \ "$UNAME" \ "$AUTHNAME" \ $(printf "${UNAME}:${AUTHNAME}:${PWORD}" | openssl dgst -md5)
Какие ещё есть дайджесты?
Подкоманда list-message-digest-commands даёт список типов дайджестов, доступных в данной инсталляции.
openssl list-message-digest-commands
Шифрование/расшифровка
Как закодировать что-то по методу base64?
Использовать опцию -base64.
# закодировать file.txt в base64 и вывести его на стандартный поток вывода openssl enc -base64 -in file.txt # то же, но вывести результат в файл file.txt.enc openssl enc -base64 -in file.txt -out file.txt.enc
Закодировать одну строку:
$ echo "encode me" | openssl enc -base64 ZW5jb2RlIG1lCg==
Без перевода строки (важно для паролей):
$ echo -n "encode me" | openssl enc -base64 ZW5jb2RlIG1l
Опция -d выполняет обратный процесс (то есть, раскодирование):
$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d encode me
Как зашифровать файл?
Простое шифрование файлов, вероятно, лучше делать инструментами типа GPG. Тем не менее, иногда может возникнуть необходимость зашифровать файл без развёртывания инфраструктуры ключей и сертификатов, а пользуясь одним только паролем. Второе, что нужно будет запомнить — это шифр, с помощью которого выполнялось шифрование.
Список поддерживаемых шифров есть на странице enc(1). Более просто (и более точно) узнать этот список у самой программы openssl.
# в подзаголовке 'Cipher commands' есть список openssl -h # или длинный список, по одному шифру в строке openssl list-cipher-commands
Кроме выбора шифра нужно также решить, будут ли данные закодированы в base64. Если будут, то их можно будет, грубо говоря, вставить в почтовое сообщение, прямо в текст. В противном случае это будет простой бинарный файл.
# зашифровать file.txt в file.enc с помощью 256-битного шифра AES в режиме CBC openssl enc -aes-256-cbc -salt -in file.txt -out file.enc # то же, но выполнять кодирование base64 openssl enc -aes-256-cbc -a -salt -in file.txt -out file.enc
Расшифровка файла на стороне получателя:
# расшифровать бинарный файл openssl enc -d -aes-256-cbc -in file.enc # расшифровать base64-файл openssl enc -d -aes-256-cbc -a -in file.enc
Можно не вводить парольную фразу постоянно при шифровании и расшифровке, а передавать её автоматически (подробнее: openssl(1); раздел "PASS PHRASE ARGUMENTS"). Формат аргумента прост:
# provide password on command line openssl enc -aes-256-cbc -salt -in file.txt \ -out file.enc -pass pass:mySillyPassword # provide password in a file openssl enc -aes-256-cbc -salt -in file.txt \ -out file.enc -pass file:/path/to/secret/password.txt
Ошибки
Как интерпретировать сообщения об ошибках SSL?
В системных журналах обнаружились строки, которые, похоже, имеют отношение к OpenSSL или crypto:
sshd[31784]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106) sshd[770]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
В первом приближении определить, что не так, можно с помощью подкоманды errstr, которая умеет интерпретировать код ошибки. Код ошибки находится между "error:" и ":lib". В данном случае это 0407006A.
$ openssl errstr 0407006A error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
Дальше информацию надо искать в документации. В данном случае в man-странице RSA_padding_add_PKCS1_type_1(3) будет написано, что PKCS #1 использует для подписей блочные методы.
Ключи
Как сгенерировать ключ RSA?
Использовать подкоманду genrsa:
# по умолчанию длина ключа 512 бит; ключ выводится на стандартный поток openssl genrsa # ключ 1024 бита, сохраняется в файл mykey.pem openssl genrsa -out mykey.pem 1024 # то же, что выше, только зашифрован с помощью парольной фразы openssl genrsa -des3 -out mykey.pem 1024
Как сгенерировать открытый ключ RSA?
С помощью подкоманды rsa можно создать открытую версию для закрытого ключа RSA:
openssl rsa -in mykey.pem -pubout
Как сгенерировать ключ DSA?
Для построения ключей DSA нужен специальный файл параметров (parameter file), кроме того, операции с DSA медленнее чем аналогичные операции с RSA, в связи с этим, DSA используется не так часто, как RSA.
Если нужно сгенерировать только один ключ DSA, то это можно сделать одной командой, с помощью подкоманды dsaparam:
# ключ будет называться dsakey.pem openssl dsaparam -noout -out dsakey.pem -genkey 1024
Если же нужно создавать несколько ключей DSA, перед тем как их генерировать, можно сделать общий файл параметров. Файл параметров генерируется сравнительно медленно, а файлы ключей очень быстро.
# записать параметры в dsaparam.pem openssl dsaparam -out dsaparam.pem 1024 # создать первый ключ openssl gendsa -out key1.pem dsaparam.pem # и второй openssl gendsa -out key2.pem dsaparam.pem
Как создать ключ, основанный на эллиптических кривых (elliptic curve key)?
Процедуры для работы с эллиптическими кривыми были добавлены в openssl, начиная с версии 0.9.8. Работа с этими процедурами выполняется через подкоманду ecparam.
openssl ecparam -out key.pem -name prime256v1 -genkey # openssl может показать полный список параметров кривых, # который можно передавать с опцией <tt>-name</tt> openssl ecparam -list_curves
Как создать открытый EC ключ?
С помощью подкоманды ec можно создать открытую версию для закрытого ключа EC (elliptic curve):
openssl ec -in key.pem -pubout -out pub.pem
Как удалить парольную фразу у ключа?
Каждый раз, когда запускается демон, использующий ключ, надо будет набирать парольную фразу. Её можно убрать.
Допустим, ключ, зашифрованный парольной фразой, находится в файле key.pem; после выполнения команды расшифрованный ключ будет в newkey.pem:
# надо будет ввести парольную фразу openssl rsa -in key.pem -out newkey.pem
Если закрытый ключ (private key) и открытый сертификат хранятся в одном файле, нужно будет выполнить две команды:
# надо ввести парольную фразу ещё раз openssl rsa -in mycert.pem -out newcert.pem openssl x509 -in mycert.pem >>newcert.pem
Хэши для паролей
С помощью подкоманды passwd можно генерировать хэши паролей, которые совместимы со стандартными хэшами из /etc/passwd, /etc/shadow или файла паролей Apache.
Как сгенерировать хэш в стиле crypt?
Сгенерировать хэш очень просто:
$ openssl passwd MySecret 8E4vqBR4UOYF.
Если salt для пароля известен, можно воссоздать хэш.
$ openssl passwd -salt 8E MySecret 8E4vqBR4UOYF.
Как сгенерировать хэш пароля в стиле shadow?
В новых UNIX/Linux-системах вместо старого crypt-хэша используется новый, более стойкий хэш MD5. Его генерирование выполняется с помощью ключа -1:
$ openssl passwd -1 MySecret $1$sXiKzkus$haDZ9JpVrRHBznY5OxB82.
В этом формате salt состоит из 8 символов; он находится между вторым и третьим знаком $, в данном случае это sXiKzkus.
$ openssl passwd -1 -salt sXiKzkus MySecret $1$sXiKzkus$haDZ9JpVrRHBznY5OxB82.
Простые числа
Поскольку openssl активно использует механизмы для работы с простыми числами, не удивительно, что в нём есть соответствующие процедуры. Начиная с версии 0.9.7e (или где-то так), в openssl появилась подкоманда binary.
Как проверить, является ли число простым?
Передать число как аргумент к подкоманде prime. Результат будет не в десятичном, а в шестнадцатеричном виде.
$ openssl prime 119054759245460753 1A6F7AC39A53511 is not prime
Можно проверять и шестнадцатеричные числа:
$ openssl prime -hex 2f 2F is prime
Как сгенерировать набор простых чисел?
Сгенерировать множество чисел и оставить только простые среди них. Для генерирования последовательностей удобно использовать seq.
# начальная и конечная точки AQUO=10000 ADQUEM=10100 for N in $(seq $AQUO $ADQUEM); do # в десятичную форму преобразуем с помощью bc openssl prime $N | awk '/is prime/ {print "ibase=16;"$1}' | bc done
Случайные данные
Как генерировать случайные данные?
Используйте подкоманду rand.
# Выдать 128 случайных байтов, закодированных в base64 на стандартный поток вывода openssl rand -base64 128 # Записать 1024 случайных байта в файл openssl rand -out random-data.bin 1024 # Инициализировать генератор случайныхх чисел полуслучайными данными из кэша браузера cd $(find ~/.mozilla/firefox -type d -name Cache) openssl rand -rand $(find . -type f -printf '%f:') -base64 1024
На UNIX/Linux-системах, в которых есть файл /dev/urandom, похожего эффекта можно добиться иначе, и иногда с лучшим результатом даже:
# взять 32 символа из /dev/urandom и закодировать их в base64 head -c 32 /dev/urandom | openssl enc -base64
Между устройствами random и urandom есть разница. Дополнительная информация в random(4) для Linux и BSD или random(7D) для Solaris.
S/MIME
S/MIME — стандарт для получения и отправки безопасных MIME-данных, в особенности, почтовых сообщений. Большинство почтовых клиентов умеет работать с такими сообщениями сами, но для этого же можно использовать и openssl smime.
Много хороших примеров есть в smime(1).
Как проверить подписанное сообщение S/MIME?
Проверить, сохранённое в файле msg.txt подписанное сообщение:
openssl smime -verify -in msg.txt
Если сертификат отправителя подписан сервером сертификатов, которому доверяет инсталляция OpenSSL, будут показаны заголовки сообщения, копия сообщения и заключительная строка "Verification successful".
Если сообщение было изменено, в выводе будет содержаться сообщение о том, что подпись или дайджест (контрольная сумма) не соответствуют действительности:
Verification failure 23016:error:21071065:PKCS7 routines:PKCS7_signatureVerify:digest failure:pk7_doit.c:804: 23016:error:21075069:PKCS7 routines:PKCS7_verify:signature failure:pk7_smime.c:265:
Если сертификат не опознан, возникнет похожая ошибка:
Verification failure 9544:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:222:Verify error:self signed certificate
Большинство почтовых клиентов отправляют копию открытого сертификата прикреплёнными к сообщению. Данные сертификата можно посмотреть из командной строки. Используется хитрая комбинация подкоманд smime -pk7out и pkcs7. Немного странно на первый взгляд, но работает!
openssl smime -pk7out -in msg.txt | \ openssl pkcs7 -text -noout -print_certs
Если нужно вытащить сертификат автора письма, для того, чтобы использовать его в дальнейшем, то нужна только первая часть команды:
openssl smime -pk7out -in msg.txt -out her-cert.pem
Дальше этот сертификат можно или интегрировать в инфраструктуру OpenSSL, или сохранить его для будущего использования, например, такого:
openssl smime -verify -in msg.txt -CAfile /path/to/her-cert.pem
Как зашифровать сообщение S/MIME?
Допустим, кто-то прислал вам свой сертификат, которым попросил шифровать сообщения ему. Сертификат сохранён в her-cert.pem. Ответ сохранен в файле my-message.txt.
Для того чтобы получить шифрование по умолчанию RC2-40 (оно, правда, слабое), нужно только сказать 'openssl, где находится сертификат:
openssl smime her-cert.pem -encrypt -in my-message.txt
Если есть уверенность, что на удалённой стороне есть современная поддержка SSL, можно использовать алгоритм шифрования посильнее чем DES:
openssl smime her-cert.pem -encrypt -des3 -in my-message.txt
По умолчанию, зашифрованные сообщения, включая почтовые заголовки, отправляются на стандартный поток вывода. С помощью опции -out их можно отправить в файл. Если постараться, то передать сообщение можно и сразу программе sendmail.
openssl smime her-cert.pem \ -encrypt \ -des3 \ -in my-message.txt \ -from 'Your Fullname <you@youraddress.com>' \ -to 'Her Fullname <her@heraddress.com>' \ -subject 'My encrypted reply' |\ sendmail her@heraddress.com
Как подписать сообщение S/MIME?
Подписать (но не шифровать) сообщение своим собственным сертификатом, так чтобы получатель имел возможность убедиться, кто является истинным автором.
openssl smime \ -sign \ -signer /path/to/your-cert.pem \ -in my-message.txt \ -from 'Your Fullname <you@youraddress.com>' \ -to 'Her Fullname <her@heraddress.com>' \ -subject 'My signed reply' |\ sendmail her@heraddress.com
Подключение сертифицированного СКЗИ Рутокен ЭЦП к OpenSSL
http://forum.rutoken.ru/topic/1639/
Дополнительная информация
- openssl.org (англ.) — домашний сайт проекта
- Использование OpenSSL (рус.), Всеволод Стахов — большая статья, посвящённая использованию OpenSSL
- OpenSSL demystified (англ.) — несколько дополнительных примеров использования OpenSSL и родственных инструментов
Криптография на Xgu.ru | ||
---|---|---|
Основы | Криптография | |
AAA | Kerberos • EAP • Host-based аутентификация в OpenSSH | |
Шифрование данных на диске | Шифрование LVM • LUKS | |
Шифрование сетевых данных | VPN • IPsec • OpenVPN • SSL • OpenSSL • TLS • SSH | |
Криптография в VoIP | Шифрование звонков в Asterisk • SRTP |