Сам себе PKI: Практика на примере OpenSSL и CA Smallstep. (Статья 2)
В предыдущей статье «Сам себе PKI: Теория на примере Let’s Encrypt» мы рассмотрели теорию и разобрали пример, как происходит установка HTTPS соединения между браузером и веб-сайтом при использовании сертификатов Let’s Encrypt. В этой статье перейдем к практике и самостоятельно реализуем ту же самую схему:
Сначала вручную (с помощью OpenSSL) пройдем цепочку генерации и использования самоподписанных сертификатов в HTTPS сервере.
Далее развернем собственный удостоверяющий центр Smallstep и будем получать сертификаты, подписанные им.
Схема PKI остаётся той же, только изменяются компоненты:
В качестве CA вместо Let’s Encrypt, будет использоваться OpenSSL и CA Smallstep.
В роли Web-сервера вместо Интернет веб-сайта, будет выступать простой HTTPS сервер, запущенный на Node.js.
Практика Self-signed certificate
OpenSSL
Начнем с классики криптографии OpenSSL. Сейчас широко используется версия 1.1.1, но ее поддержка заканчивается в 2023. Следующая версия 3.0 будет поддерживаться до 2026 года. Проверка установленной версии:
OpenSSL 1.1.1k FIPS 25 Mar 2021
Если OpenSSL не установлен, то его можно установить на всех востребованных платформах.
Реализация TLS
Для нашего CA генерируем приватный ключ 2048-бит RSA. Администратор CA должен хранить его в секрете от всех:
openssl genrsa -out root_ca.key 2048
Далее для нашего CA генерируем X.509 сертификат на 365 дней (root_ca.crt) и подписываем его приватным ключом (root_ca.key). Получается самоподписанный сертификат, его можно и нужно будет скопировать на все компьютеры, между которыми необходимо организовать TLS соединение. При ответах на вопросы, которые будет задавать OpenSSL, можно указывать произвольные данные, CA я назвал «My CN»:
openssl req -x509 -new -key root_ca.key -days 365 -out root_ca.crt
Смотрим получившийся сертификат, убеждаемся, что данные в нем корректные:
openssl x509 -text -in root_ca.crt
Генерируем приватный ключ для HTTPS сервера, его нужно будет скопировать только на компьютер, на котором он будет работать и никуда больше:
openssl genrsa -out server.key 2048
Генерируем запрос на сертификат CSR. В этом запросе нужно передать конкретные значения в параметре «subj». Это должны быть один или несколько параметров CN (Common Name), которые будут прописаны в атрибутах сертификата «Subject» и «Subject Alternative Name». Фактически CN-ы — это IP адреса и имена хостов, по которым будет осуществляться доступ к серверу. Имена хостов могут быть как в формате доменного имени, так и FQDN:
openssl req -new -key server.key -subj «/CN=xx.xx.xx.xx/CN=server/CN=server.example.com» -out server.csr
Можно посмотреть получившийся запрос на сертификат и убедиться в его корректности:
openssl req -text -in server.csr
Теперь генерируем сертификат X.509 (server.crt) на 365 дней для HTTPS сервера и подписываем его приватным ключом CA (root_ca.key):
openssl x509 -req -in server.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out server.crt -days 365 -extensions SAN -extfile openssl.cnf
Файл openssl.cnf должен содержать список SAN (Subject Alternative Name) идентичный тому, что был в CSR запросе на сертификат:
Можно посмотреть на получившийся сертификат и убедиться в его корректности:
openssl x509 -text -in root_ca.crt
С ключами и сертификатами закончили, переходим к запуску HTTPS сервера. Копируем следующие файлы на компьютер, на котором будет работать HTTPS сервер:
Пишем простейший HTTPS сервер, на JS:
Запускать данный скрипт будем с помощью Node.js. Если Node.js не установлен, то устанавливаем:
sudo yum groupinstall ‘Development Tools’
sudo yum install nodejs
Проверяем, что Node и Npm установились успешно:
Проверяем сервер curl-ом:
При первом запросе возникнет ошибка:
curl: (60) SSL certificate problem: self signed certificate in certificate chain
Это значит, что самоподписанный корневой сертификат нашего CA (root_ca.crt) не находится в хранилище доверительных сертификатов. Процесс загрузки сертификатов в это хранилище специфичен для операционной системы. Приведу алгоритм для RH Linux:
Если сертификат не в PEM (текстовом) формате, то его надо сконвертировать в текстовой формат:
openssl x509 -in root_ca.crt -out root_ca.pem -outform PEM
Копируем сертификат в определенный каталог на сервере. ДляRH 7 и выше это каталог:
Выполняем команду обновления хранилища сертификатов:
Теперь curl проходит
на Windows есть специфика — в curl необходимо добавлять параметр «ssl-no-revoke», чтобы не проверялся список отозванных сертификатов:
curl —ssl-no-revoke https://server.example.com:9443
При этом сервер выведет в консоль строку:
Это значит, что мы установили TLS соединение только с проверкой сертификата сервера, а не клиента. Переходим к mTLS.
Реализация mTLS
В коде сервера включаем mTLS, а именно выставляем в true параметр requestCert, чтобы HTTPS сервер запрашивал клиентский сертификат и параметр rejectUnauthorized, чтобы сервер отклонял запросы клиентов, которые не прошли авторизацию:
Алгоритм генерации клиентских сертификатов аналогичен серверным.
Генерируем приватный ключ для клиента:
openssl genrsa -out client.key 2048
Генерируем запрос на сертификат CSR со списком CN:
openssl req -new -key client.key -subj «/CN=xx.xx.xx.xx/CN=client/CN=client.example.com» -out client.csr
Генерируем сертификат для клиента и подписываем его приватным ключом CA:
openssl x509 -req -in client.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out client.crt -days 365 -extensions SAN -extfile openssl.cnf
Файл openssl.cnf — такой же как и для сервера, только вместо «server» пишем «client».
Копируем следующие файлы на компьютер, на котором будет работать клиент:
Теперь если просто вызвать curl:
То произойдет ошибка авторизации
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Поэтому вызываем curl с дополнительными параметрами, в которых указываем ключ клиента и сертификаты клиента и СА:
curl —cert ./client.crt —key client.key —cacert root_ca.crt https://server.example.com:9443
Теперь запрос проходит, при этом сервер выведет в консоль следующую строку и далее содержимое полученного от клиента сертификата:
Это значит, что мы установили mTLS соединение с проверкой сертификата как сервера, так и клиента. Теперь установим mTLS из браузера.
Реализация mTLS в браузере
Если просто запустить наш запрос к серверу (https://server.example.com:9443) из браузера, то выдается ошибка клиентского сертификата ERR_BAD_SSL_CLIENT_AUTH_CERT. Рабочие адреса закрасил желтым:
Для загрузки в браузер клиентский сертификат и приватный ключ надо сконвертировать в формат p12. Этот формат определяется стандартом PKCS #12 и является архивом для хранения нескольких объектов. В нашем случае файл будет хранить клиентский сертификат и его приватный ключ. Понятно, что приватный ключ — это чувствительная к разглашению информация и ее владелец не должен выкладывать p12 сертификат в открытый доступ. Для конвертации тоже используем OpenSSL:
openssl pkcs12 -inkey client.key -in client.crt -export -out client.p12
Импортируем client.p12 в браузер. Для этого, например в Chrome, идем в меню: Settings / Privacy and security / Manage certificates, в открывшемся окне нажимаем Import, выбираем наш файл client.p12 и место хранения «Personal». Видим, что клиентский сертификат, выданный нашим удостоверяющим центром «My CN», появился в хранилище персональных сертификатов:
Вызываем запрос заново, уже лучше, но браузер все равно пишет, что соединение не безопасно. Это из-за того, что клиентский сертификат выдан удостоверяющим центром «My CN», которого нет в списке доверительных CA (Trusted Root Certification Authorities).
Добавляем корневой сертификат нашего CA (root_ca.crt) в Trusted Root Certification Authorities. Делается с помощью того же вызова Import, что и для клиентского сертификата, но хранилище указываем Trusted Root Certification Authorities. Проверяем, что наш CA «My CN» появился в хранилище:
Повторяем наш запрос (https://server.example.com:9443). При первом запросе браузер находит подходящий клиентский сертификат и просит явно подтвердить его использование:
Дальнейшие вызовы проходят без запросов на подтверждение клиентского сертификата:
Если щелкнуть на замочке а адресной строке, то можно посмотреть сертификат сервера и убедиться, что мы взаимодействуем с правильным сервером (Issued to: server.example.com), сертификат которому выдан нашим удостоверяющим центром (Issued by: My CN) и время действия сертификата еще не прошло (Valid to: 31.05.2023):
Таким образом мы организовали mTLS соединение из браузера. Далее приведу для справки несколько дополнительных возможностей OpenSSL, которые могут пригодиться в процессе работы.
Дополнительные возможности OpenSSL
Конвертация форматов сертификатов
Конвертируем сертификат в der (бинарный формат):
openssl x509 -outform der -in client.crt -out client.der
Конвертируем сертификат в PEM (текстовой формат)
openssl x509 -inform der -in client.cer -out client.pem
Отладка с помощью OpenSSL
Проверка, что сертификат подписан определенным (root_ca.pem) удостоверяющим центром:
openssl verify -verbose -x509_strict -CAfile root_ca.pem server.crt
Запускаем OpenSSL server
openssl s_server -accept 9443 -cert server.crt -key server.key
Запускаем OpenSSL client
openssl s_client -connect xx.xx.xx.xx:9443 -prexit -showcerts -state -status -tlsextdebug -verify 10
При вызове curl параметр:
-k — позволяет подсоединяться к серверу без проверки цепочки сертификатов (certificate path validation).
—ssl-no-revoke — предотвращает проверку отозванных сертификатов
Практика CA Smallstep
Установка Smallstep и CLI step
CA Smallstep — это open source CA, который можно развернуть локально для автоматического получения X.509 сертификатов. На официальном сайте есть ряд инструкций по его установке и настройке. Для экспериментов я использовал вариант с docker:
Краткая выжимка из инструкции по установке на RH Linux. Сначала устанавливаем docker:
sudo yum -y update
sudo yum install -y yum-utils
sudo yum-config-manager —add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum -y install docker-ce
sudo systemctl start docker
Проверяем корректность установки docker:
sudo docker run hello-world
sudo docker pull smallstep/step-ca
Инициализируем наш CA:
docker run -it -v step:/home/step smallstep/step-ca step ca init
При инициализации по умолчанию будет ряд ограничений, например, будут одинаковые пароли для корневого и промежуточного приватного ключа. Для разворота в промышленную среду необходимо внимательно изучить рекомендации Production considerations when running a certificate authority server.
При создании CA в консоль будет выведен fingerprint корневого сертификата в виде шестнадцатеричной строки (например: 55de8dc05cd. 8a70f725a56). Ее надо сохранить для последующей инициализации утилиты CLI step, которая используется для взаимодействия с CA Smallstep. Проверяем, что CA Smallstep запущен корректно. xx.xx.xx.xx:9000 — это IP и порт, на котором запущен Smallstep CA:
должна вернуться строка:
На этом же или другом компьютере по инструкции устанавливаем утилиту CLI step. Краткая выжимка:
tar -xf step_linux_0.19.0_386.tar.gz
Копируем утилиту step в /usr/bin
Регистрируем CLI step для использования с нашим CA. Этот процесс называется «bootstrap». Значение параметра «ca-url» — это IP и порт, на котором запущен Smallstep CA, «fingerprint » — это сохраненное значение при инициализации CA:
step ca bootstrap —ca-url https://xx.xx.xx.xx:9000 —fingerprint 55de8dc05cd. 8a70f725a56 —install
Проверка связи с CA:
должна вернуться строка:
Все готово для генерации ключей и сертификатов.
Генерация ключей и сертификатов
Также как и в случае с OpenSSL, сначала генерируем ключ и сертификат для сервера и установки TLS соединения, потом для клиента и установки mTLS.
Зачем нужны сертификаты¶
Итак, сертификат (certificate) — это файл, содержащий информацию о персоне или организации и подписанный цифровой подписью, нечто вроде паспорта персоны или организации. Главное содержимое сертификата — это публичный ключ шифрования. У любого сертификата существует его автор-создатель и у этого автора есть секретный ключ шифрования. По сути сертификат — это всего лишь обёртка над публичным ключом, где помимо собственно ключа содержится разнообразная дополнительная информация: имя персоны или организации, страна, телефон, емейл и так далее.
Секретный и публичный ключи используются для асиметричной схемы шифрования: данные шифруются секретным ключом, а расшифровываются публичным. Или наоборот: шифруются публичным, а расшифровываются секретным. За подробностями традиционно отправляю в википедию, в статью Криптосистема с открытым ключом.
Помним главное: в паре с сертификатом всегда идёт секретный ключ. Когда мы в браузере открываем сайт через HTTPS, сервер отправляет нам сертификат, который мы должны использовать для установки дальнейшего безопасного соединения. В этом сертификате лежит публичный ключ, а также адрес сайта. Браузер проверяет, что адрес сайта соответствует запрошенному и разрешает установку соединения. Секретный ключ при этом находится на сервере сайта и пределы этого сервера никогда не покидает.
Но тут возникает вопрос: а где гарантия, что этот сертификат (и соответственно публичный ключ) настоящий, что он действительно создан автором сайта, а не вклинившимся в сеть злоумышленником? Как проверить подлинность этого «удостоверения сайта»?
Есть два решения этой проблемы. Самое очевидное: на стороне браузера имеется хранилище сертификатов и для каждого сайта в нём уже существует сертификат, дальше мы просто сравниваем полученный сертификат и если он совпадает с имеющимся, устанавливаем соединение. Такая схема используется, например, в работе программы SSH, у неё имеется локальная база сертификатов, при установке соединения она проверяется, что полученный сертификат с этого адреса соответствует уже сохранённому в базе. Очевидный недостаток этой схемы: необходимо каким-то образом заполучить сертификаты заранее.
Если для SSH схема с заранее сохранённым сертификатом более-менее работает, то для HTTPS в браузере она уже не годится, абсолютно невозможно получить сертификаты для всех сайтов в интернете. Поэтому в HTTPS используется другая схема, называемая инфраструктурой публичных ключей или по-английски Public Key Infrastructure, сокращённо PKI.
Суть PKI очень простая: в браузере хранятся не сертификаты браузеров, а сертификаты так называемых удостоверяющих центров (по-английски Certificate Authority, сокращённо CA). Предназначение CA — это подписывание всех остальных сертификатов, это означает, что когда ваш браузер получает сертификат сайта при установке соединения, он видит помимо адреса сайта ещё и «адрес» удостоверяющего центра, а также цифровую подпись, которую сгенерировал удостоверяющий центр с использованием своего секретного ключа. Дальше браузер берёт из локального хранилища сертификат удостоверяющего центра, достаёт из него публичный ключ и с помощью него проверяет подпись в сертификате сайта. Если подпись правильная, соединение успешно устанавливается.
Естественно, удостоверяющие центры не подписывают сертификаты кому попало. Владелец сайта должен каким-то образом подтвердить свою личность и принадлежность к сайту, только после этого сертификат будет подписан. Естественно, всё это делается не бесплатно и удостоверяющие центры делают весьма много денег из воздуха.
Локальное хранилище сертификатов удостоверяющих центров меняется достаточно редко и контролируется создателями либо операционной системы, либо браузера.
Технические подробности¶
А теперь самое главное, ради чего эта статья и писалась — технические подробности, стандарты и особенности реализации системы сертификатов.
В основе всего лежит множество индустриальных стандартов, созданных очень давно — в конце восьмидесятых и начале девяностых годов XX века. Благодаря этим стандартам, мы сейчас имеет вполне успешно функционирующую систему, несмотря на то, что отдельные её компоненты созданы совершенно разными компаниями.
Секретный ключ¶
Главный компонент всего — криптография, точнее криптографические алгоритмы.
Всё начинается с генерации пары ключей: секретного и публичного. Сначала при помощи математической и компьютерной магии генерируется секретный ключ, а затем из него вычисляется публичный. Чаще всего для сертификатов используется алгоритм RSA, вот как это делается в консоли через программу openssl:
В этом примере мы сгенерили секретный ключ для алгоритма RSA. Собственно сам ключ находится между специальными маркерами ——BEGIN RSA PRIVATE KEY—— и ——END RSA PRIVATE KEY—— . Чтобы при генерации ключа сохранить его сразу в файл, добавьте аргумент -out private.pem :
С подобным форматом представления криптографических данных вам предстоит сталкиваться постоянно, называется он PEM, что расшифровывается как Privacy-enhanced Electronic Mail. Его предназначение — кодировать бинарные криптографические данные в виде ASCII-текста. И фактически между маркерами из минусов находятся закодированные в base64 бинарные данные, в данном случае — секретный ключ.
Мы можем при помощи openssl сконвертировать секретный ключ из текстового формата PEM в изначальный бинарный, сохраним его в файл private.der:
Имя формата данных DER расшифровывается как Distinguished Encoding Rules и является частью стандарта ASN.1. В стандарте ASN.1 описываются правила и структуры для кодирования, раскодирования и передачи данных по телекоммуникационным и компьютерным сетям. По сути можно считать ASN.1 форматом для сериализации структурированных бинарных данных. Существует специальный компилятор, который из формальных спецификаций ASN.1 генерирует C-код для работы с бинарными данными такой структуры.
Также существует консольная программа dumpasn1 для просмотра бинарных данных, в дебиане/убунте она ставится через sudo apt-get install dumpasn1 , для макоси можно поставить через macports, через homebrew (инструкция), либо скомпилировать самостоятельно из исходников.
Вот так, например, выглядит дамп нашего созданного секретного ключа:
В нашем файле секретного ключа «упакованы» девять целых чисел, структура ключа для алгоритма RSA весьма простая и описана, например, в RFC 3447, в секции A.1.2 RSA private key syntax.
Ну и чтобы два раза не вставать, вытащим из секретного ключа публичный ключ в файл public.der, закодированный в бинарный формат DER, openssl умеет делать и это тоже:
И сразу же посмотрим на его структуру через dumpasn1:
Структура публичного ключа также описана в RFC3447, в секции A.1.1, если вы туда посмотрите, то увидите, что дамп файла public.der не соответствует этому описанию. Поздравляю с первыми граблями в openssl, с ними вам тоже придётся сталкиваться постоянно. В данном случае зачем-то добавляется заголовок, указывающий, что дальше будет RSA, и на этом заголовке многим библиотекам срывает крышу.
Для манипуляциями публичными и секретными ключами можно также использовать команду pkey, она позволяет работать с произвольными поддерживаемыми типами ключей. Вот как выглядит её вызов для вытаскивания публичного ключа из приватного:
Сертификат¶
Но хватит о ключах, поговорим теперь о сертификатах. Напомню, что сертификат — это обёртка над публичным ключом. Неформально файл сертификата состоит из двух частей: данных сертификата (DATA) и цифровой подписи (SIGNATURE).
В секции DATA содержится смысловая часть сертификата, главное поле там — Subject (он же Субъект), это владелец сертификата, именно его публичный ключ находится в поле Subject Public Key Info. Также в сертификат входят другие поля, о которых мы поговорим позже, когда будем рассматривать уточнённую схему.
В секции SIGNATURE содержится цифровая подпись всех данных из секции DATA. Напомню, что в модели PKI цифровую подпись генерирует центр авторизации, используя свой секретный ключ, удостоверяя подлинность данных сертификата.
Естественно, вся работа с сертификатами регламентируется международными стандартами, конкретно для наших сертификатов используется стандарт X.509, вот его официальный сайт: http://www.itu.int/rec/T-REC-X.509. X.509 описывает множество аспектов PKI, не только форматы данных, но ещё и алгоритмы.
Для описания структур данных используется уже знакомая нам нотация ASN.1, она достаточно простая и выразительная.
Вот так определяется сертификат (раздел 4.1. Basic Certificate Fields):
Это всё значит, что сертификат состоит из трёх компонентов: tbsCertificate, signatureAlgorithm и signatureValue
tbsCertificate собственно тело сертификата, его данные, буквы tbs в названии поля расшифровываются как «to be signed», то есть это блок данных, который будет подписан, описывается ASN.1 стуктурой TBSCertificate ; signatureAlgorithm в этом поле задаётся алгоритм подписи, определяется ASN.1 структурой AlgorithmIdentifier ; signatureValue а в этом поле находится бинарный неструктурированный блок с собственно подписью.
Перед тем как погружаться в структуру тела сертификата, рассмотрим поле signatureAlgorithm, в его описании фигурирует очень важный для дальнейшего понимания элемент, но сначала формальное ASN.1-описание (раздел 4.1.1.2. signatureAlgorithm):
Здесь мы видим элемент с «типом» OBJECT IDENTIFIER , это очень важная сущность, которая дальше будет встречаться везде. OBJECT IDENTIFIER часто сокращается до OID и означает буквально «идентификатор объекта». Все OID являются «словарными», то есть они определены где-то в каком-то стандарте, где также описана вся сопутствующая семантика. В нашем случае через OID определяется криптографический алгоритм, используемый для генерации цифровой подписи сертификата.
Как и другие порождения ASN.1/X.509, OID имеет чётко заданную структуру, по которой можно однозначно идентифицировать тип и свойства объекта. Существуют разные способы представления OID. Рассмотрим их на простом примере. Для генерации цифровой подписи может использоваться алгоритм, который неформально можно описать так: посчитаем SHA256 тела сертификата и дальше зашифруем это значение приватным ключом центра авторизации. Для этого алгоритма существует OID, у этого OID есть несколько равнозначных способов представления:
- 1.2.840.113549.1.1.11
- /ISO/Member-Body/840/113549/1/1/11
Все эти способы отражают иерархичную сущность OID, по компонентам можно определить, например, кто внёс этот OID в реестр, какая страна, какая организация и так далее. Существует специальный сайт — http://www.oid-info.com, — на котором ведётся большой реестр всевозможных OID. В принципе, таких сайтов несколько, но этот самый популярный. Вот, например, страница OID для алгоритма sha256WithRSAEncryption: http://www.oid-info.com/get/1.2.840.113549.1.1.11.
Вернёмся теперь к сертификату, рассмотрим ASN.1-структуру TBSCertificate , вот её определение вместе с сопутствующими структурами:
Я не буду полностью описывать семантику этих полей, это всё приводится с подробностями в разделе 4.1. Basic Certificate Fields RFC 5280. Так, коротко пробежимся по основным полям.
В поле signature должно быть то же самое значение, что и в поле signatureAlgorithm, то есть алгоритм, которым CA подписывает сертификат.
В поле issuer находится имя центра авторизации, в поле subject — имя владельца сертификата. Оба этих имени также являются структурированными (ASN.1-структура Name) и должны быть непустыми, их тип определяется стандартом X.501 и носит название distinguished name, сокращённо DN. Это тот же самый DN, что и в LDAP.
Поля в структуре Name также задаются через OID. Вот небольшой пример, как поле issue «разворачивается» из текстового представления в строго формализованное. Возьмём DN-фрагмент реального сертификата (https://google.ru):
Небольшой хинт, как скачать сертификат с сайта и сразу конвертнуть его в DER в файл certificate.der:
А вот, в какую ASN.1-структуру «разворачивается» этот текст:
По факту это последовательность пар ключ-значение, где в роли ключа выступает OID. То есть кажущаяся обычным текстом строка оказывается одной из форм представления строго структурированного объекта. Каждая такая пара ключ-значение называется RelativeDistinguishedName, в роли ключа выступает OID.
Для дальнейшего изучения темы нам понадобится настоящий живой сертификат. Я взял сертификат c twitter.com, вы его можете скачать сами (если знаете, как это сделать вашим браузером) или взять сохранённую мной версию в виде DER-файла (скачать сохранённую версию).
Итак, сначала посмотрим, как сертификат выглядит в «человечном» формате, вот его полная распечатка (немного отформатированная, чтобы длинная строка не распирала экран):
Разберём последовательно поля сертификата.
Version: 3 (0x2) Это версия не конкретно этого сертификата, а используемого «профайла», на данный момент таких версий всего три: 1, 2, 3; чаще всего используется 3. Фактическое значение поля — 2, так как нумерация версий идёт с нуля. Serial Number: 1a:c8:5e:b7:ae:c3:51:3c:d8:0d:85:38:5e:cf:d2:08 Это «серийный номер» сертификата, по сути он является уникальным идентификатором в базе CA, для каждого подписанного сертификата этот номер должен быть свой. Signature Algorithm: sha256WithRSAEncryption Это мы уже знаем: для подписывания сертификата используется алгоритм sha256WithRSAEncryption Issuer: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA — G3 Это имя (distinguished name, DN) центра авторизации, является по сути идентификатором в браузерной базе CA-сертификатов, и чтобы корректно проверифицировать серверный сертификат, браузер должен у себя иметь CA-сертификат, в поле subject которого стоит точно такое же значение, как здесь. Validity В этом поле две даты, с какой и по какую сертификат считается валидным. Это поле является главной кормушкой центров авторизации: каждые год или два нужно выписывать (=подписывать у центра авторизации) новый сертификат, не бесплатно, конечно. Subject: 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private Organization/serialNumber=4337446, C=US/postalCode=94103-1307, ST=California, L=San Francisco/street=1355 Market St, O=Twitter, Inc., OU=Twitter Security, CN=twitter.com Субъект. Тот, кому выписан сертификат. Это DN, то есть структурированное поле. Обратите внимание на самые первые компоненты — 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware , в них мы видим, что openssl не смог распознать эти OID и вывели их в «сыром» виде. Вот они в репозитории OID: 1.3.6.1.4.1.311.60.2.1.3 jurisdictionOfIncorporationCountryName, 1.3.6.1.4.1.311.60.2.1.2 jurisdictionOfIncorporationStateOrProvinceName. Дальше идут уже распознанные компоненты, в качестве разделителя компонентов используется запятая или слеш, такие особенности вывода openssl. Обратите внимание на компонент CN, это Common name, именно здесь находится имя домена, для которого выписывается сертификат. Subject Public Key Info Этот блок содержит публичный ключ субъекта, синтаксически там два поля: OID алгоритма шифрования и собственно тело публичного ключа. Openssl при показе сертификата пытается показать детали публичного ключа, в данном случае он показывает модуль и экспоненту RSA-ключа. Ниже я покажу, как openssl справляется с сертификатми, с алгоритмами которых он не знаком. X509v3 extensions В этом блоке содержатся так называемые расширения сертификата. Хотя структура сертификата очень жёсткая, в ней были оставлены точки расширения, чтобы можно было в сертификат добавлять дополнительные данные, которые изначально не предусмотрели. Фактически, блок с расширениями — это набор пар OID-значение, где тип значения зависит от конкретного OID. Расширения допускаются только для сертификатов версии 3. Обычно в расширениях указываются дополнительные параметры сертификата. Например, в поле X509v3 Subject Alternative Name указываются дополнительные доменные адреса сайта, для которых сертификат применим. Или, например, в поле X509v3 Basic Constraints, указываются ограничения в применимости сертификата, в данном случае указано, что сертификат не может использоваться в качестве сертификата удостоверяющего центра. Signature Algorithm Этим блоком сертификат всегда завершается, в нём содержится идентификатор алгоритма подписи и собственно подпись вышестоящего блока.
Дальше я рекомендую выполнить команду dumpasn1 certificate-twitter.com.der и сравнить только что прочитанное с показанным в дампе, параллельно полезно держать открытыми RFC 5280 и RF 3280.
Цепочки удостоверяющих сертификатов¶
Удостоверяющий центр может выдать сертификат, в котором в поле X509v3 Basic Constraints разрешается его использование как удостоверяющего. Этим сертификатом тоже можно подписывать «доменные» сертификаты. Таким образом, все CA-сертификаты образуют цепочку, а в целом — дерево. В вершине этого дерева находится Самый Главный Сертификат, он называется корневым сертификатом (по-английски root certificate).
Система доверия PKI строится таким образом, что доверенным CA-сертификатом является тот, который подписан другим доверенным корневым CA-сертификатом. Вебсайт может вместе со своим сертификатом отдать браузеру также и CA-сертификат, которым он был подписан. И если этот CA-сертификат подписан кем-то из доверенных удостоверяющих центров, он автоматически становится доверенным.
Естественно, центры авторизации не выписывают CA-сертификаты кому попало, но крупная организация может этого добиться, например, у Google есть свой CA-сертификат.
Также в PKI существует механизм отзыва сертификатов, например, если кто-то из CA стал себя вести некорректно или у него украли секретный ключ, то вышестоящий удостоверяющий центр может отозвать сертификат провинившегося. Эта схема, к сожалению, на практике работает не так гладко, как это задумывалось.
Корневой сертификат является самоподписанным, то есть он подписан тем же самым ключом, публичный ключ для которого находится в теле сертификата. У корневого сертификата совпадают поля issuer и subject.
Сфера применения сертификатов не ограничивается браузером, конечно. В теории любой клиент может сам выбирать, кому он доверяет, а кому нет. В программу может быть жёстко вшит сертификат, которым она проверяет другие сертификаты, например.
Как вручную проверить цепочку сертификатов¶
Иногда возникает необходимость проверить, подписан ли один сертификат другим. Это можно сделать через openssl.
Возьмём три сертификата из Go Daddy, вот они: GD_root.pem (это корневой сертификат Go Daddy), GD_good.pem, GD_bad.pem. Нам нужно проверить, подписаны ли сертификаты GD_good.pem и GD_bad.pem корневым сертификатом Go Daddy.
Для верификации используем команду openssl verify , в ней мы должны указать файл с «доверенными» сертификатами, в нашем случае это один сертификат GD_root.pem, указывается через аргумент -CAfile GD_root.pem . Также мы указываем заведомо несуществующий путь к главному хранилищу сертификатов удостоверяющих центров, чтобы в процессе верификации участвовал только один сертификат, это делается через аргумент -CApath /nope . В новых версиях openssl (начиная с 1.1.0) введён специальный новый параметр -no-CApath .
И альтернативный вариант (предыдущий в новых версиях не работает):
И ещё о сертификатах¶
Небольшая демонстрация, как openssl работает с сертификатами, алгоритмов для которых он не знает. Возьмём вот этот сертификат, это корневой сертификат Казахстанского центра межбанковских расчётов национального банка Республики Казахстан.
Вот как выглядит попытка распечатать его как текст:
Обратите внимание на поле Signature Algorithm: 1.3.6.1.4.1.6801.1.2.2, openssl не смог распознать этот алгоритм, так как в его коде нет такого OID. Если мы попытаемся найти этот OID в репозитории http://www.oid-info.com/get/1.3.6.1.4.1.6801.1.2.2, то обнаружим, что им он неизвестен. Но зато им известен «родительский» OID (помним, что схема OID иерархичная), по адресу http://www.oid-info.com/get/1.3.6.1.4.1.6801 находим координаты владельца этой схемы — казахстанская фирма Gamma Technologies, OID предыдущего уровня (1.3.6.1.4.1.6801.1.2) выдаёт нам GOST28147, https://ru.wikipedia.org/wiki/ГОСТ_28147-89.
Как мы видим, фирма использует X.509 для хранения своих собственных сертификатов. Браузер его не сможет переварить, а вот специализированный софт — вполне. Например, dumpasn1 отлично показывает структуру ASN.1-объектов.
Следующий файл для препарирования — сертификат удостоверяющего центра Бурятии, скачайте файл ca-bur.der. Предлагаю вам самим его скачать и запустить команду:
А затем такую, для контраста:
Комментарии
клиент получил сертификат от сайта. Для проверки подлинности, он использует подпись из этого сертификата, используя публичный ключ удостоверяющего сертификата(центра). Как с помощью такого ключа можно проверить подпись?
Это очень непростой вопрос, на самом деле. Каноничная схема предполагает использование команды openssl verify , но для неё нужна ПОЛНАЯ цепочка доверия сертификатов, начиная с корневого самоподписанного.
Вот простой пример, сертификаты для него тут:
В файле ca.pem должны лежать полностью ВСЕ CA-сертификаты: корневой и все промежуточные. Если -CAfile не указывать, то программа будет пытаться использовать системные сертификаты.
Но если вы хотите проверить валидность сертификата, используя только публичный ключ сертификата удостоверяющего центра, то простого способа я не знаю. Сложный — это извлечь публичный ключ из CA-сертификата, извлечь байты подписи из проверяемого сертификата, извлечь TBSCertificate и проверить соответствие подписи.
Впрочем, начиная с какой-то версии появился флаг -partial_chain, с ним можно в -CAfile передавать только один сертификат.
-CApath /dev/null указываю для гарантии, что не будет использоваться системное хранилище сертификатов.
Никаких промежуточных сертификатов в файле ca быть не должно. Только корневые, полученные от CA. Подпись каждого сертификата в цепочке (за исключением корневого) проверяется следующим по цепочке сертификатом (его открытым ключом). Подпись корневого считается верной по факту доверия к нему.
Не силен в сертификатах, но пришлось разбираться с сертификатами из-за почты. Настроил, работает, но хотелось бы привести более удобный вид. Пока не могу найти как это сделать. Можете подсказать ? Собственно хотелось бы понять 1. Как сделать, чтобы была возможность через просмотр сертификата (в момент когда почта предупреждает, что не удается проверить сертификат) нажать «установить сертификат» для самого сертификата и для корневого сертификата, причем так, чтобы он приходил вместе с сертификатом, а не раздавался «по секрету». 2. Как встроить в сертификаты путь куда должен размещаться сертификат если при установке выбран режим автоматического размещения сертификата. 3. Ну и из «красявостей» как прописать в сертификат (особенно в основной) поле «Понятное имя». Как я понял это парамер -name, но его я нашел почему-то только применительно к pkcs12
Это всё инфраструктурные вопросы, они вне области собственно сертификатов лежат.
Сама суть инфраструктуры публичных ключей (PKI) предполагает, что корневой сертификат попадает на машину клиента другим путём, не через сетевой коннект, поэтому нормального способа «запомнить» или «автоматически скачать» нет.
По пункту 2. ничего не могу сказать. Возможно, какое-то расширение для этого есть, но для этого нужно изучать конкретную систему распространения сертификатов.
«Понятное имя» в сертификате прописать нельзя.
Конкретно для реализации подключения почтового клиента зачастую пользуются самоподписанные сертификаты. Я попробовал и такой и такой варианты. Самоподписанного для этой цели достаточно, но неудобство отсутствия возможности установить сертификат через режим просмотра подтолкнуло попробовать второй вариант. Возникает вопрос — а можно ли самоподписанный сделать так, чтобы появилась возможность его установки через режим просмотра ?
Теоретически самоподписанный сертификат установить можно, но почти все программы его будут игнорировать.
Частично разобрался. 1. Отсутствие кнопки «установить сертификат» — это похоже «сюрпрайз» от оутглюка от 7го офиса. В офисах версии старше такая кнопка появилась. 2. При установке самоподписанного сертификата можно выбирать автоматическое размещение. Видимо за счет того, что он является корневым сертификатом его автоматом заталкивает в доверенные корневые центры сертификации.
В статье строчка openssl verify -verbose -x509_strict -CApath /nope -CAfile GD_root.pem GD_bad.pem у меня не работает. Сработала такая: openssl verify -verbose -x509_strict -no-CApath -CAfile GD_root.pem GD_bad.pem Возможно, опечатка. Спасибо Вам за статью
Это не опечатка, просто эта опция есть не во всех версиях openssl. Спасибо за напоминание, обновлю текст.
Как создать CA на Linux сервере
CA или Certificate Authority -понятие в криптографии, обозначающее сторону, которая может подписывать сгенерированные на сервере SSL сертификаты. Сертификаты, которые интернет браузеры распознают как доверенные, выпускаются через известные CA и являются почти всегда платными. Для работы внутри компании (когда используются какие-то внутренние ресурсы) часто бывает полезно генерировать сертификаты самостоятельно и подписывать их. В рамках данного материала рассмотрено как создать CA.
Как создать CA (Certificate Authority Server)
Создать CA и сгенерировать ключи можно на любом Linux сервере, для этого потребуется воспользоваться пакетом openssl
Прежде всего, CA. Сгенерируем ключ сертификатционного центра
openssl genrsa -out rootCA.key 2048
rootCA.key здесь — имя файла на выходе, 2048 — клина ключа
Далее используя ключ создаем корневой сертификат
openssl req -x509 -new -key CAroot.key -days 5000 -out CAroot.crt
В примере на 5000 дней, можно указать и другой срок
Возникнет диалог в котором нужно указать произвольные данные о сертификационном центре, указываемые значения особой роли не играют
В результате в текущем каталоге появится в дополнение к файлу ключа CA файл корневого сертификата.
Далее генерируем необходимые SSL сертификаты для определенных доменов. Вопрос уже рассматривался, далее краткая инструкция.
Генерируем приватный ключ
openssl genrsa -out mysite.key 2048
На выходе имеем файл mysite.key
Создаем запрос на сертификат с использованием ключа (вновь возникает такой же диалог, в нем в качестве имени домена нужно указать то имя, которое будет использоваться)
openssl req -new -key mysite.key -out mysite.csr
Сертификат в общем случае мы бы создали такой командой
openssl x509 -req -days 365 -in mysite.csr -signkey mysite.key -out mysite.crt
Но подписанным он бы не был, поэтому укажем дополнительно корневые ключ и сертификат
openssl x509 -req -in mysite.csr -CA CAroot.crt -CAkey CAroot.key -CAcreateserial -out mysite.crt -days 5000
На этом все. Теперь серверный ключ и сертификат (rootCA) нужно расположить на основном сервере организации, корневой сертификат добавить на всех машинах.
Он просто импортируется в хранилище. Это нужно для того, чтобы браузер на конкретной распознавал сертификат как доверенный несмотря на то, что для других клиентов он доверенным не является.
Для Firefox на Linux (Desktop система) процесс представлен на скриншоте.

После того как корневой сертификат добавлен любые SSL сертификаты для доменов (в том, числе тот, что создали сейчас для mysite), подписанные CA будут распознаваться как валидные. Их можно устанавливать на любые сервера.
Ключ сертификационного центра следует держать только на той машине, на которой он был сгенерирован, сертификат можно распространять свободно.
MNorin.com
Блог про Linux, Bash и другие информационные технологии
TLS и SSL: Необходимый минимум знаний

TLS и SSL упоминаются в последнее время все чаще и чаще, более актуальным становится использование цифровых сертификатов, и даже появились компании, готовые бесплатно предоставлять цифровые сертификаты всем желающим, чтобы гарантировать шифрование трафика между посещаемыми сайтами и браузером клиента. Нужно это, естественно, для безопасности, чтобы никто в сети не мог получить данные, которые передаются от клиента серверу и обратно. Как же это всё работает и как это использовать? Чтобы это понять, надо, пожалуй, начать с теории, а потом показать на практике. Итак, SSL и TLS.
Что такое SSL и что такое TLS?
SSL — Secure Socket Layer, уровень защищенных сокетов. TLS — Transport Layer Security, безопасность транспортного уровня. SSL является более ранней системой, TLS появился позднее и он основан на спецификации SSL 3.0, разработанной компанией Netscape Communications. Тем не менее, задача у этих протоколов одна — обеспечение защищенной передачи данных между двумя компьютерами в сети Интернет. Такую передачу используют для различных сайтов, для электронной почты, для обмена сообщениями и много еще для чего. В принципе, можно передавать любую информацию таким образом, об этом чуть ниже.
Безопасная передача обеспечивается при помощи аутентификации и шифрования передаваемой информации. По сути эти протоколы, TLS и SSL, работают одинаково, принципиальных различий нет. TLS, можно сказать, является преемником SSL, хотя они и могут использоваться одновременно, причем даже на одном и том же сервере. Такая поддержка необходима для того, чтобы обеспечить работу как с новыми клиентами (устройствами и браузерами), так и с устаревшими, которые TLS не поддерживают. Последовательность возникновения этих протоколов выглядит вот так:
SSL 1.0 — никогда не публиковался
SSL 2.0 — февраль 1995 года
SSL 3.0 — 1996 год
TLS 1.0 — январь 1999 года
TLS 1.1 — апрель 2006 года
TLS 1.2 — август 2008 года
Принцип работы SSL и TLS
Принцип работы SSL и TLS, как я уже сказал, один и тот же. Поверх протокола TCP/IP устанавливается зашифрованный канал, внутри которого передаются данные по прикладному протоколу — HTTP, FTP, и так далее. Вот как это можно представить графически:

Прикладной протокол «заворачивается» в TLS/SSL, а тот в свою очередь в TCP/IP. По сути данные по прикладному протоколу передаются по TCP/IP, но они зашифрованы. И расшифровать передаваемые данные может только та машина, которая установила соединения. Для всех остальных, кто получит передаваемые пакеты, эта информация будет бессмысленной, если они не смогут ее расшифровать.
Установка соединения обеспечивается в несколько этапов:
1) Клиент устанавливает соединение с сервером и запрашивает защищенное подключение. Это может обеспечиваться либо установлением соединения на порт, который изначально предназначен для работы с SSL/TLS, например, 443, либо дополнительным запросом клиентом установки защищенного соединения после установки обычного.
2) При установке соединения клиент предоставляет список алгоритмов шифрования, которые он «знает». Сервер сверяет полученный список со списком алгоритмов, которые «знает» сам сервер, и выбирает наиболее надежный алгоритм, после чего сообщает клиенту, какой алгоритм использовать
3) Сервер отправляет клиенту свой цифровой сертификат, подписанный удостоверяющим центром, и открытый ключ сервера.
4) Клиент может связаться с сервером доверенного центра сертификации, который подписал сертификат сервера, и проверить, валиден ли сертификат сервера. Но может и не связываться. В операционной системе обычно уже установлены корневые сертификаты центров сертификации, с которыми сверяют подписи серверных сертификатов, например, браузеры.
5) Генерируется сеансовый ключ для защищенного соединения. Это делается следующим образом:
— Клиент генерирует случайную цифровую последовательность
— Клиент шифрует ее открытым ключом сервера и посылает результат на сервер
— Сервер расшифровывает полученную последовательность при помощи закрытого ключа
Учитывая, что алгоритм шифрования является асимметричным, расшифровать последовательность может только сервер. При использовании асимметричного шифрования используется два ключа — приватный и публичный. Публичным отправляемое сообщение шифруется, а приватным расшифровывается. Расшифровать сообщение, имея публичный, ключ нельзя.
6) Таким образом устанавливается зашифрованное соединение. Данные, передаваемые по нему, шифруются и расшифровываются до тех пор, пока соединение не будет разорвано.
Корневой сертификат
Чуть выше я упомянул корневой сертификат. Это сертификат авторизационного центра, подпись которым подтверждает, что сертификат, который подписан, является именно тем, который принадлежит соответствующему сервису. В самом сертификате обычно содержится ряд информационных полей, в которых содержится информация об имени сервера, которому выдан сертификат, и сроках действия этого сертификата. Если срок действия сертификата истек, он признается недействительным.
Запрос на подпись (CSR, Certificate Sign Request)
Для получения подписанного серверного сертификата необходимо сгенерировать запрос на подпись (CSR, Certificate Sign Request) и отправить этот запрос авторизационному центру, который вернет подписанный сертификат, устанавливаемый непосредственно на сервер, чуть ниже посмотрим, как это сделать на практике. Сначала генерируется ключ для шифрования, затем на основании этого ключа генерируется запрос на подпись, CSR-файл.
Клиентский сертификат
Клиентский сертификат может быть сгенерирован как для использования в устройствах, так и для использования пользователями. Обычно такие сертификаты используются при двусторонней верификации, когда клиент верифицирует, что сервер действительно тот, за кого себя выдает, и сервер в ответ делает то же самое. Такое взаимодействие называется двусторонней аутентификацией или mutual authentication. Двусторонняя аутентификация позволяет повысить уровень безопасности по сравнению с односторонней, а также может служить заменой аутентификации с использованием логина и пароля.
Цепочка действий по генерации сертификатов
Давайте посмотрим на практике, как происходят действия, связанные с генерацией сертификатов, с самого начала, и при этом на практике.
Первое, что делается — это генерация корневого сертификата. Корневой сертификат подписывается самим собой. А потом уже этим сертификатом будут подписываться другие сертификаты.
Таким образом мы сгенерировали сначала приватный ключ, затем запрос подписи, а затем своим ключом подписали свой же запрос и получили собственный цифровой сертификат, выданный на 10 лет. Пароль (challenge password) при генерации сертификата можно не вводить.
Приватный ключ ОБЯЗАТЕЛЬНО необходимо хранить в надежном месте, имея его можно подписать от вашего имени любой сертификат. А полученный корневой сертификат можно использовать для идентификации того, что сертификат, например, сервера подписан именно нами, а не кем-то еще. Именно такие действия выполняют авторизационные центры, когда генерируют собственные сертификаты. После создания корневого сертификата можно приступать к генерации сертификата сервера.
Просмотр информации о сертификате
Содержимое сертификата можно просмотреть таким образом:
Мы видим, кто выдал этот сертификат и когда заканчивается срок его годности.
Серверный сертификат
Для подписи сертификата для сервера нам нужно выполнить следующие действия:
1) Сгенерировать ключ
2) Сгенерировать запрос на подпись
3) Отправить CSR-файл в авторизационный центр или подписать самостоятельно
В серверный сертификат может включаться цепочка сертификатов, которыми подписан сертификат сервера, но ее можно также хранить в отдельном файле. В принципе, выглядит всё примерно так же, как и при генерации корневого сертификата
Таким образом сертификат сервера подписан и мы будем знать, какой организацией выдан этот сертификат. После подписи готовый сертификат можно использовать по назначению, например, установить на веб-сервер.
Установка SSL/TLS-сертификата на сервер с nginx
Для установки SSL/TLS-сертификата на веб-сервер nginx надо выполнить несколько простых шагов:
1) Скопировать файлы .key и .pem на сервер. В различных операционных системах сертификаты и ключи могут храниться в разных директориях. В Debian’е, к примеру, это директория /etc/ssl/certs для сертификатов и /etc/ssl/private для ключей. В CentOS это /etc/pki/tls/certs и /etc/pki/tls/private
2) Прописать необходимые настройки в конфигурационный файл для хоста. Вот как это примерно должно выглядеть (это просто пример):
3) Перезапустить nginx
4) Зайти браузером на 443 порт сервера — https://www.mycompany.com и проверить его работоспособность.
Установка SSL/TLS-сертификата на сервер с Apache
Установка SSL/TLS-сертификата на Apache выглядит примерно так же.
1) Скопировать файлы ключа и сертификата на сервер в соответствующие директории
2) Включить модуль ssl для Apache командой «a2enmod ssl», если он еще не включен
3) Создать виртуальный хост, который будет слушать 443 порт. Конфиг будет выглядеть примерно так:
При этом надо сделать еще кое-что. Найти в файле httpd.conf, или apache2.conf, или ports.conf, в зависимости от системы, такой участок конфига:
Если такого условия нет, его надо добавить в конфиг. И еще одно: Надо добавить строку
Эта строка может находиться в файле httpd.conf, apache2.conf или ports.conf
4) Перезапустить веб-сервер Apache
Создание клиентского сертификата
Клиентский сертификат создается примерно так же, как серверный.
Если необходим клиентский сертификат в формате PKCS12, создаем его:
Теперь можно использовать клиентский сертификат для работы с нашим сервером.
Настройка nginx на использование клиентских сертификатов
Чаще всего, как я уже сказал, используется односторонняя аутентификация, обычно проверяется только сертификат сервера. Давайте посмотрим, как заставить веб-сервер nginx проверять клиентский сертификат. Необходимо в секцию server добавить опции для работы с клиентскими сертификатами:
После этого надо перезагрузить настройки или сервер целиком и можно проверять работу.
Настройка Apache на использование клиентских сертификатов
Apache настраивается также через добавление дополнительных опций в секцию виртуального хоста:
Как видите, опции примерно такие же, как и для nginx, поскольку процесс проверки организован единообразно.
«Прослушка» информации о сертификате при помощи openssl
Для проверки взаимодействия сервера с клиентскими сертификатами можно проверить, устанавливается ли соединение с использованием TLS/SSL.
На стороне сервера запускаем прослушку порта при помощи openssl:
На стороне клиента обращаемся к серверу, например, culr’ом:
В консоли со стороны сервера можно наблюдать процесс обмена информацией между сервером и клиентом.
Можно также использовать опции -verify [глубина проверки] и -Verify [глубина проверки]. Опция с маленькой буквы запрашивает у клиента сертификат, но он не обязан его предоставлять. С большой буквы — если сертификат не предоставлен, возникнет ошибка. Запустим прослушку со стороны сервера таким образом:
Со стороны сервера ошибка выглядит так:
Со стороны клиента так:
Добавим с клиентской стороны сертификат и доменное имя (можно для проверки вписать в файл /etc/hosts имя хоста для адреса 127.0.0.1):
Теперь соединение пройдет успешно и можно устанавливать серверный сертификат на веб-сервер, клиентский отдать клиенту, и работать с ними.
Безопасность
При использовании SSL/TLS одним из основных методов является метод MITM (Man In The Middle), «человек посередине». Этот метод основывается на использовании серверного сертификата и ключа на каком-то узле, который будет прослушивать трафик и расшифровывать информацию, которой обмениваются сервер и клиент. Для организации прослушивания можно использовать, например, программу sslsniff. Поэтому корневой сертификат и ключ обычно желательно хранить на машине, которая не подключена к сети, для подписания приносить запросы на подпись на флэшке, подписывать и так же уносить. И, естественно, делать резервные копии.
В общих чертах именно так и используются цифровые сертификаты и протоколы TLS и SSL. Если есть вопросы/дополнения, пишите в комментарии.