воскресенье, 27 ноября 2016 г.

Как создавать и администрировать цепочки сертификатов X.509, часть I

Перевод: How to create and administer X.509 Certificate chains, Part I
Автор: Дитер Клюнтер (Dieter Klünter)

Сертификаты X.509 широко используются для обеспечения безопасной передачи данных и проверки целостности. Первая часть описывает создание частного удостоверяющего центра и сертификатов узла, а вторая часть имеет дело с администрированием сертификатов. Третья часть позволит вам создать собственные инструменты администрирования на основе Bash и Perl. Приведённые ниже примеры основаны на OpenSSL. В этой части мы опишем шаги, необходимые для генерации:
  • корневого ключа для подписания,
  • частного удостоверяющего центра,
  • ключа узла и частного подписанного сертификата,
  • ключа пользователя и частного подписанного сертификата.
Если у вас имеется доступ к доверенному общедоступному удостоверяющему центру, вы можете пропустить шаги инструкции по созданию своего собственного удостоверяющего центра и перейти к инструкции по созданию сертификата узла или пользователя.

Создание удостоверяющего центра

Для подписания сертификатов нужно сначала обзавестись корневым ключом для подписания.
Важно! Этот корневой ключ нужно оберегать
Сначала приготовим файл с паролем:
$ touch myPassfile
$ chmod 0600 myPassfile
$ echo 'secret' > myPassfile
Теперь создадим корневой ключ для подписания:
$ openssl genrsa \
  -des3 \
  -passout file:myPassfile \
  -out privateRoot.key \
  2048
Эта команда создаст ключ для подписания с именем privateRoot.key размером 2048 бит, защищённый паролем. На странице руководства genrsa(1) можно найти дополнительную информацию о доступных параметрах.

Перед созданием удостоверяющего центра и цепочки сертификатов нужно предпринять ряд шагов, которые облегчат дальнейшие действия.
  • Файл конфигурации с параметрами для инициирования удостоверяющего центра, myCA.conf
  • Файл конфигурации с параметрами для инициирования сертификата узла, host.conf
  • Файл конфигурации с дополнительными параметрами X.509 для инициирования удостоверяющего центра, myCA.ext
  • Файл конфигурации с дополнительными параметрами X.509 для инициирования сертификата узла, host.ext
  • Последовательный файл для административных нужд, myCA.serial
Для создания последовательного файла просто выполните следующие команды:
$ touch myCA.serial
$ chmod 0644 myCA.serial
$ echo '00' > myCA.serial
Теперь подготовим необходимые файлы конфигурации для инициации удостоверяющего центра.

myCA.conf:
[req]
default_bits                   = 2048
distinguished_name             = req_DN
string_mask                    = nombstr

[req_DN]
countryName                    = "1. Название страны (двухбуквенный код)"
countryName_default            = DE
countryName_min                = 2
countryName_max                = 2
stateOrProvinceName            = "2. Название штата или провинции (полное название)"
#stateOrProvinceName_default =
localityName                   = "3. Название местности (например, город)"
localityName_default           = Гамбург
0.organizationName             = "4. Название организации (например, компания)"
0.organizationName_default     = Моя организация
organizationalUnitName         = "5. Название подразделения (например, отдел)"
organizationalUnitName_default = Центр сертификации
commonName                     = "6. Простое имя (например, название центра сертификации)"
commonName_max                 = 64
commonName_default             = Мой собственный центр сертификации
emailAddress                   = "7. Адрес электронной почты (например, имя@полное_доменное_имя)"
emailAddress_max               = 40
emailAddress_default           = admin@example.com
myCA.ext:
extensions            = x509v3

[x509v3]
basicConstraints      = CA:true,pathlen:0
crlDistributionPoints = URI:http://example.com/ca/myca.crl
nsCertType            = sslCA,emailCA,objCA
nsCaPolicyUrl         = "http://example.com/ca/policy.html"
nsCaRevocationUrl     = "http://example.com/ca/myca.crl"
nsComment             = "Мой собственный центр сертификации"
Для облегчения администрирования любой удостоверяющий центр должен предоставлять информацию о точках распространения, политике URL и URL списка отозванных сертификатов.

Чтобы создать запрос на сертификат, нужно предоставить некоторую информацию удостоверяющему центру, для чего надо создать myCA.conf. В этом файле конфигурации задаются значения по умолчанию, что позволяет изменять значения в соответствии с требованиями. Создадим запрос на подпись сертификата (Certificate Signing Request) на основе предоставленной информации:
$ openssl req \
  -config myCA.conf \
  -new \
  -key privateRoot.key \
  -passin file:myPassfile \
  -out myPrivateCA.csr
Для подписания этого запроса на сертификат приготовим файл конфигурации с дополнительными параметрами удостоверяющего центра myCA.ext, как это было описано выше.
$ openssl x509 \
  -days 3650 \
  -extfile myCA.ext \
  -signkey privateRoot.key \
  -CAserial myCA.serial \
  -passin file:myPassfile \
  -in myPrivateCA.csr \
  -req \
  -out myPrivateCA.crt
Теперь у нас есть удостоверяющий центр в формате PEM, который можно использовать для подписания сертификатов узлов и пользователей.

Создание сертификата узла

Веб-сервер, SMTP-сервер, IMAP-сервер, LDAP-сервер и многие другие требуют безопасный транспортный слой (Transport Layer Security), проверку целостности клиентских приложений и служебных узлов. Чтобы включить это требование, сертификат узла должен быть соответствующим образом подписан удостоверяющим центром. В этой главе описано создание:
  • приватного ключа узла
  • сертификата узла
  • файла конфигурации host.conf
  • файл конфигурации host.ext
Сначала приготовим файл host.conf.

host.conf:
[req]
default_bits                   = 2048
distinguished_name             = req_DN
string_mask                    = nombstr

[req_DN]
countryName                    = "1. Название страны (двухбуквенный код)"
countryName_default            = DE
countryName_min                = 2
countryName_max                = 2
stateOrProvinceName            = "2. Название штата или провинции (полное название)"
#stateOrProvinceName_default =
localityName                   = "3. Название местности (например, город)"
localityName_default           = Гамбург
0.organizationName             = "4. Название организации (например, компания)"
0.organizationName_default     = Моя организация
organizationalUnitName         = "5. Название подразделения (например, отдел)"
organizationalUnitName_default = Мой сервер
commonName                     = "6. Простое имя (например, название центра сертификации)"
commonName_max                 = 64
commonName_default             = host.example.com
emailAddress                   = "7. Адрес электронной почты (например, имя@полное_доменное_имя)"
emailAddress_max               = 40
emailAddress_default           = admin@example.com
host.ext:
extensions       = x509v3

[x509v3]
nsCertType       = server
keyUsage         = digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage = msSGC,nsSGC,serverAuth
subjectAltName   = DNS:ldap.example.com

Атрибут типа commonName принимает в качестве значения полное имя узла. Атрибут типа subjectAltName позволяет указать несколько псевдонимов узлов, разделённых запятыми.

Сначала создадим приватный ключ узла:
$ touch hostPassfile
$ chmod 0600 hostPassfile
$ echo 'secret' > hostPassfile
$ openssl genrsa \
  -des3 \
  -passout file:hostPassfile \
  -out myHost.key \
  2048
Совет. Если вы не хотите использовать ключ узла, защищённый паролем, воспользуйтесь такой командой:
$ openssl genrsa -out myHost.key 2048
Следующая команда создаст запрос на подпись сертификата:
$ openssl req \
  -config host.conf \
  -new \
  -key myHost.key \
  -passin file:hostPassfile \
  -out MyHost.csr
И наконец, можно подписать сертификат узла:
$ openssl x509 \
  -days 1825 \
  -extfile host.ext \
  -CA myPrivateCA.crt \
  -CAkey privateRoot.key
  -passin file:myPassfile \
  -CAserial myCA.serial \
  -in MyHost.csr \
  -req \
  -out myHost.crt
Теперь у нас есть сертификат узла, ключ сертификата узла и удостоверяющий центр. Далее мы подготовим сертификат пользователя.

Создание сертификата пользователя

Обычно сертификаты пользователя используются для аутентификации и подписания электронных писем. Как и в прошлый раз, для создания ключа пользователя и сертификата пользователя нужны те же шаги. Дополнительно в файл pkcs12 можно поместить полную цепочку сертификатов. Как и в случае сертификатов узлов, нужны несколько подготовительных шагов:
  • файл user.conf
  • файл user.ext
  • ключ пользователя
  • сертификат пользователя
Сначала создадим файл user.conf.

user.conf:
[req]
default_bits                   = 2048
distinguished_name             = req_DN
string_mask                    = nombstr

[req_DN]
countryName                    = "1. Название страны (двухбуквенный код)"
countryName_default            = DE
countryName_min                = 2
countryName_max                = 2
stateOrProvinceName            = "2. Название штата или провинции (полное название)"
#stateOrProvinceName_default =
localityName                   = "3. Название местности (например, город)"
localityName_default           = Гамбург
0.organizationName             = "4. Название организации (например, компания)"
0.organizationName_default     = Моя организация
organizationalUnitName         = "5. Название подразделения (например, отдел)"
organizationalUnitName_default = Люди
commonName                     = "6. Простое название (например, название центра сертификации)"
commonName_max                 = 64
commonName_default             = Пол Смит
emailAddress                   = "7. Адрес электронной почты (например, имя@полное_доменное_имя)"
emailAddress_max               = 40
emailAddress_default           = paul@example.com

Этот набор данных создаст сертификат с выделенным именем:
dn: cn=Пол Смит,ou=Люди,o=Моя организация,c=DE
user.ext:
extensions = x509v3

[x509v3]
nsCertType = client,email,objsign
keyUsage   = digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
Сначала создадим файл с приватным паролем и с приватным ключом:
$ touch userPassfile
$ chmod 0600 userPassfile
$ echo 'secret' > userPassfile
$ openssl genrsa \
  -des3 \
  -passout file:userPassfile \
  -out myUser.key \
  2048
Далее создадим запрос на подписание сертификата пользователя:
$ openssl req \
  -config user.conf \
  -new \
  -key myUser.key \
  -passin file:userPassfile \
  -out MyUser.csr
И наконец, подпишем сертификат пользователя:
$ openssl x509 \
  -days 1825 \
  -extfile user.ext \
  -CA myPrivateCA.crt \
  -CAkey privateRoot.key
  -passin file:myPassfile \
  -CAserial myCA.serial \
  -in MyUser.csr \
  -req \
  -out myUser.crt
Теперь у нас есть правильная цепочка сертификатов, которая позволит нам создать архив pkcs12:
$ openssl pkcs12 \
  -export \
  -in myUser.crt \
  -inkey myUser.key \
  -passin file:userPassfile \
  -CAfile myPrivateCA.crt \
  -name MyUsercertificate \
  -out myUser.pkcs12
В части II будет рассмотрено администрирование сертификатов, обслуживание серийного файла и файла индекса.

Примечание переводчика: Вторая часть пока не опубликована автором, поэтому пока не будет и её перевода. Зато я нашёл другое более подробное руководство по администрированию собственного удостоверяющего центра на основе OpenSSL. Перевод этого руководства будет опубликован в дальнейших заметках этого блога. Следите за обновлениями.

воскресенье, 20 ноября 2016 г.

Шифрование и расшифровывание файлов публичными ключами с помощью OpenSSL из командной строки

Перевод: Encrypt and decrypt files to public keys via the OpenSSL Command Line
Автор: Реми ван Элст (Remy van Elst)

Содержание
  1. Получение публичного ключа
  2. Создание случайного файла пароля
  3. Шифрование файла случайным ключом
  4. Шифрование случайного ключа файлом публичного ключа
  5. Расшифровывание случайного ключа при помощи файла своего приватного ключа
  6. Расшифровывание большого файла случайным ключом
Этот небольшой рецепт показывает, как использовать openssl из командной строки для шифрования файла публичным ключом и расшифровывания файла. Сначала мы создадим случайный ключ, зашифруем этот случайный ключ публичным ключом другого человека и с помощью этого случайного ключа зашифруем сам файл, используя симметричное шифрование.

Из-за особенностей алгоритма RSA, с его помощью невозможно шифровать большие файлы. Если создать ключ из n бит, то шифруемый файл не должен быть больше чем (n минус 11) бит. Наиболее эффективное использование RSA - шифрование случайного пароля, с последующим шифрованием файла паролем с помощью алгоритма симметричного шифрования. Если файл больше, чем размер ключа, то команда шифрования завершится ошибкой:
RSA operation error: 020:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:.\crypto\rsa\rsa_pk1.c:151:
Создадим случайный файл и используем его в качестве ключа для шифрования большого файла алгоритмом симметричного шифрования. Этот случайный файл выполнит роль пароля, который мы сообщим. Большой файл зашифруем маленьким файлом, выступающим в роли пароля. Затем отправим зашифрованный файл и зашифрованный ключ получателю, а он сможет расшифровать ключ своим приватным ключом и использовать этот ключ для расшифровывания большого файла.

Для работы с ключами RSA используются следующие команды:
  • openssl genrsa: Создание приватных ключей RSA.
  • openssl rsa: Управление приватными ключами RSA (включая создание публичного ключа из приватного).
  • openssl rsautl: Шифрование и расшифровывание файлов ключами RSA.
Ключ - это просто строка случайных байтов. Воспользуемся строкой из 128 байтов, из которых в результате кодирования base64 получится 175 символов. Поскольку 175 символов - это 1400 бит, ключ получится достаточно маленьким, чтобы можно было зашифровать его при помощи RSA.

Получение публичного ключа

Попросите получателя отправить вам его сертификат или публичный ключ. Если он отправил сертификат, можно извлечь из него публичный ключ с помощью следующей команды:
openssl rsa -in certificate.pem -out publickey.pem -outform PEM -pubout
Создание случайного файла пароля

Воспользуемся следующей командой, чтобы создать случайный ключ:
openssl rand -base64 128 -out key.bin
Делайте это при каждом шифровании файла. Каждый раз используйте новый ключ!

Шифрование файла случайным ключом

Воспользуемся следующей командой, чтобы зашифровать большой файл случайным ключом:
openssl enc -aes-256-cbc -salt -in largefile.pdf -out largefile.pdf.enc -pass file:./bin.key
Размер файла вырастет ненамного:
$ ls -larth
-rw-r--r-- 1 user group 40M Nov 9 21:14 Linux-Voice-Issue-020.pdf
-rw-r--r-- 1 user group 40M Nov 9 22:03 Linux-Voice-Issue-020.pdf.enc
Однако, он зашифрован:
$ file Linux-Voice-Issue-020.pdf
Linux-Voice-Issue-020.pdf: PDF document, version 1.4

$ file Linux-Voice-Issue-020.pdf.enc
Linux-Voice-Issue-020.pdf.enc: data
Шифрование случайного ключа файлом публичного ключа

Воспользуемся следующей командой для шифрования файла случайного ключа публичным ключом получателя:
openssl rsautl -encrypt -inkey publickey.pem -pubin -in key.bin -out key.bin.enc
Теперь можно без опаски отправить получателю key.bin.enc и largefile.pdf.enc.

Полезно также подписать оба файла своим публичным ключом.

Расшифровывание случайного ключа при помощи файла своего приватного ключа

Если нужно расшифровать файл, зашифрованный описанным способом, воспользуйтесь следующей командой, указав ей свой приватный ключ (соответствующий публичному ключу, которым был зашифрован случайный ключ) для расшифровывания случайного ключа:
openssl rsautl -decrypt -inkey privatekey.pem -in key.bin.enc -out key.bin
В результате получим расшифрованный случайный ключ, которым зашифрован полученный файл.

Расшифровывание большого файла случайным ключом

Как только был получен случайный ключ, можно расшифровать расшифрованным ключом зашифрованный файл:
openssl enc -d -aes-256-cbc -in largefile.pdf.enc -out largefile.pdf -pass file:./bin.key
В результате получим расшифрованный большой файл.

воскресенье, 13 ноября 2016 г.

Подписание и проверка текстов/файлов публичными ключами с помощью OpenSSL из командной строки

Перевод: Sign and verify text/files to public keys via the OpenSSL Command Line
Автор: Реми ван Элст (Remy van Elst)

Содержание
  1. Создание пары ключей
  2. Подписание файла
  3. Проверка подписи
  4. Подпись
В этом небольшом руководстве рассматривается, как использовать OpenSSL из командной строки для подписания файла и как проверить подпись этого файла. Это делается для того, чтобы доказать владение ключом или чтобы доказать, что файл не был изменён с тех пор, как был подписан. Руководство пригодно и для небольших текстовых файлов, и для больших фотографий, и для документов, и файлов PDF.

Создание пары ключей

Сначала создадим новую пару ключей. Можно использовать существующую пару. Измените тему в следующей команде и выполните её, чтобы создать самозаверенную пару ключей:
openssl req -nodes -x509 -sha256 -newkey rsa:4096 -keyout "$(whoami)s Sign Key.key" -out "$(whoami)s Sign Key.crt" \
-days 365 -subj "/C=NL/ST=Zuid Holland/L=Rotterdam/O=Sparkling Network/OU=IT Dept/CN=$(whoami)s Sign Key"
Также создадим небольшой текстовый файл для тестирования процесса подписания:
echo "Здравствуй, мир!" > sign.txt
Подписание файла

Воспользуемся следующей командой, чтобы подписать файл. На самом деле мы одной командой openssl посчитаем хэш файла по алгоритму sha256 и подпишем его:
openssl dgst -sha256 -sign "$(whoami)s Sign Key.key" -out sign.txt.sha256 sign.txt
В результате получим файл sign.txt с его содержимым и файл sign.txt.sha256 с подписанным хэшем этого файла.

Можно разместить этот файл и публичный ключ ($(whoami)s Sign Key.crt) в интернете или в другом месте. Храните приватный ключ ($(whoami)s Sign Key.key) в безопасности и секретности.

Проверка подписи

Для проверки подписи нужен публичный ключ, относящийся к сертификату. Его можно получить из сертификата с помощью следующей команды:
openssl x509 -in "$(whoami)s Sign Key.crt"
Можно избежать этого этапа, объединив два этапа в одной команде. Следующая команда проверяет файл с помощью подписи хэша:
openssl dgst -sha256 -verify <(openssl x509 -in "$(whoami)s Sign Key.crt" -pubkey -noout) -signature sign.txt.sha256 sign.txt
Если содержимое не было изменено с момента подписания, вывод команды будет таким:
Verified OK
Если проверка завершилась неудачно, это означает, что хэш файла не соответствует подписанному хэшу. Весьма вероятно, что файл был изменён или подделан. Результат неудачной проверки выглядит следующим образом:
Verification Failure
Подпись

Чтобы получить текстовую версию подписи (файл содержит двоичные данные), можно воспользоваться командой base64. Текстовую версию вместе с файлом проще разместить в интернете:
base64 sign.txt.sha256 > sign.txt.sha256.txt
Для обратного преобразования в формат, пригодный для использования в openssl, воспользуйтесь командой base64 -d:
base64 -d sign.txt.sha256.txt > sign.txt.sha256