Что происходит на практике
Client Hello – клиент начинает общение с сервером отсылая информацию о предпочитаемой версии протокола TLS, набора поддерживаемых шифров (Cipher Spec), и случайного простого числа (client random), необходимого в дальнейшем для генерации общего ключа симметричного шифрования.
Что такое Cipher Spec? В процессе установки соединения, клиент и сервер должны договориться о: какой алгоритм использовать для обмена ключами (например, RSA – Риверт-Шамир-Адлеман, DH – Диффи-Хеллмана, ECDH – Диффи-Хеллмана на эллиптических кривых, и др.), какой алгоритм использовать для шифрования данных (AES – Advanced Encryption Standard, 3DES – Tripple Data Encryption Algorithm, и др.), какую криптографическую хэш-функцию использовать для генерации Message Authentication Code (SHA-256, SHA-384, SHA-512 – Secure Hash Algorithm с соответствующей длиной строки в битах с хэшем, и др.).
Что такое Message Authentication Code или MAC? Это хэш, сгенерированный с использованием выбранной криптографической хэш-функции и разделяемого ключа, который добавляется сзади к сообщению. Перед отправкой данных отправитель вычисляет MAC для них, а получатель перед обработкой вычисляет MAC для принятого сообщения и сравнивает его с MAC этого принятого сообщения. Предназначен для проверки целостности, то есть что сообщение не было изменено при его передаче.
Server Hello – сервер отвечает выбранной версией протокола и выбранным из предложенного набора шифром, которые будут непосредственно использоваться, своим случайным простым числом (server random) и идентификатором сессии.
Для чего нужен идентификатор сессии? Как мы посмотрим далее, процесс установления TLS соединения затратен по времени и ресурсам. Предусмотрен механизм возобновления соединения с помощью отправки клиентом этого идентификатора. Если сервер тоже все еще хранит соответствующие настройки, то клиент и сервер смогут продолжить общение использую ранее выбранные алгоритмы и ключи.
Certificate – сервер отправляет свой сертификат, а клиент производит проверку подписи удостоверяющего центра, проверку доверия к удостоверяющему центру, проверку указанного домена сайта с фактическим, срока действия, проверяет не был ли сертификат отозван.
Что представляет из себя сертификат? Сертификат – это открытый ключ и другая информация о его владельце, а также Электронная Цифровая Подпись (ЭЦП) доверенного центра.
Как работает ЭЦП? При создании ЭЦП хэш данных, которые подписываются, шифруется закрытым ключом, в отличие от обычного ассиметричного шифрования, где зашифровка выполняется открытым ключом. Таким образом, если вам удалось расшифровать открытым ключом хэш, и он оказался идентичен хэшу из данных, – вы можете быть уверены что: подпись была сделана именно владельцем приватного ключа, открытый ключ которого вы используете; данные, которые были подписаны, не изменились с момента подписания.
Но как удостовериться, что открытый ключ принадлежит не злоумышленнику? Существуют корневые удостоверяющие центры (Root Certificate Authority или просто CA – Certificate Authority), которым доверяют все участники обмена информацией. Если в цепочке подписания сертификата сервера есть подпись корневого CA (мы можем проверить ее с помощью открытого ключа CA), то мы можем ему доверять. При этом сертификаты (открытые ключи) корневых CA распространяются посредством включения их в операционную систему или браузер поставщиками. Также стоит отметить, что сертификат может быть подписан сертификатом, который подписан в свою очередь другим сертификатом – это цепочка подписания.
Кем подписан сертификат корневого CA? А никем, нет инстанции выше корневого CA. Сертификат (открытый ключ) в этом случае подписан собственным закрытым ключом. Такие сертификаты называют самоподписанные (sefl-signed).
Server Key Exchange – этот этап происходит не всегда, только если необходимы дополнительные данные для создания симметричного ключа при выбранном алгоритме. Например, при обмене ключами RSA этот шаг пропускается и для обмена общим ключ передается от клиента серверу зашифрованным открытым ключом сервера из его сертификата. Однако в этой статье рассмотрим более надежный алгоритм Диффи-Хеллмана. Сервер отправляет числа p (большое простое число) и g (может быть маленьким), а также рассчитанное число Ys=gслучайно выбранное сервером числоmod p, где mod – это операция нахождения остатка от деления. В свою очередь клиент также рассчитывает Yc=gслучайно выбранное клиентом числоmod p. После этого сервер считает Ycслучайно выбранное сервером числоmod p, а клиент Ysслучайно выбранное клиентом числоmod p, в результате чего у клиента и сервера получается одинаковое число. Разберем на примере:
Server Hello Done – сервер сообщает, что начальный этап установки соединения завершен
Client Key Exchange – как было уже сказано выше, когда сервер передал числа p, g, Ys в Server Key Echange, клиент передает свое число Yc в Client Key Exchange. Вычисленное в конце общее одинаковое число используется для создания pre-master secret – предварительного разделяемого ключа. На основании client random, server random и pre-master secret псевдослучайная функция выдает симметричный ключ и ключ вычисления MAC. Таким образом клиент и сервер имеют все необходимое для начала обмена полезной информацией.
Change Cipher Spec – клиент говорит серверу, что он готов перейти на защищенное соединение.
Finished – клиент зашифровывает симметричным ключом первое сообщение с MAC.
Change Cipher Spec – сервер проверяет сообщение Finished от клиента и отправляет в ответ свою готовность к защищенному соединению.
Finished – аналогично клиенту, сервер отправляет тестовое зашифрованное сообщение
После этого соединение считается установленным, и происходит передача полезной информации
close_notify – служебное сообщение, которое одна сторона отправляет другой, как уведомление о том, что считаетсоединение разорванным и не будет принимать больше сообщения. Другая сторона в ответ обязана послать аналогичное сообщение close_notify.
Pki и его стандарты
Отдельно следует упомянуть всякого рода национальные стандарты и нормативные требования, к примеру, в РФ это ФЗ-63, приказы ФСБ России № 795 и 796 и прочие производные от них. Следует учитывать, что многообразие стандартов RFC и описанных в них функций PKI породило несколько организационно-нормативных подходов к построению инфраструктуры PKI в отдельно взятой стране. Для иллюстрации приведу список сервисов PKI, которые описаны в стандарте X.842:
Результатом этого многообразия стало безобразие в национальных стандартах отдельных стран. Как результат – набор проблем по совместимости между различными решениями в отдельных странах и, очень часто, невозможность построения цепочки доверия между двумя пользователями технологии PKI в разных странах.
Tlsv1.3
Стоит отметить, что все выше написанное относится к TLSv1.2, которая начинает понемногу устаревать. В 2021 году была разработана новая версия 1.3 в которой: были запрещены уже ненадежные алгоритмы, ускорен процесс соединения, переработан протокол рукопожатия и др.
Выпускаем собственные сертификаты
Теперь, когда мы разобрали теорию, самое время приступить к практике! Нам понадобятся OpenSSL и keytool (входит в поставку JDK). Для начала создадим сертификат корневого CA, которым будем подписывать запросы на подпись сертификата клиента и сервера. Сгенерируем приватный ключ RSA зашифрованный AES 256 с паролем “password” длиной 4096 бит (меньше 1024 считается ненадежным) в файл CA-private-key.key:
openssl genrsa -aes256 -passout pass:password -out CA-private-key.key 4096Нет какого-то принятого стандарта расширений для файлов, связанных с сертификатами. Мы будем использовать:
Далее создадим новый запрос на подпись сертификата CA-certificate-signing-request.csr, передавая информацию о субъекте “CN=Certificate authority” (если не указывать ключ -subj вас попросят указать: Сountry (C), Locality (L), Organisation (O), Organisation Unit (OU), Common Name (CN), Email, Challenge password – все поля, кроме CN опциональны), приватный ключ и пароль от него:
openssl req -new -key CA-private-key.key -passin pass:password -subj "/CN=Certificate authority/" -out CA-certificate-signing-request.csr t $3Так как подписать сертификат другим сертификатом пока нельзя, подпишем запрос его же приватным ключом. Получившейся сертификат CA-self-signed-certificate.pem будет самоподписанным со сроком действия 1 день.
openssl x509 -req -in CA-certificate-signing-request.csr -signkey CA-private-key.key -passin pass:password -days 1 -out CA-self-signed-certificate.pempemEТеперь у нас есть сертификат, которому в будущем будут доверять наши клиент и сервер. Похожим образом сделаем приватные ключи и запросы на подпись сертификата для них:
openssl genrsa -aes256 -passout pass:password -out Server-private-key.key 4096
openssl req -new -key Server-private-key.key -passin pass:password -subj "/CN=localhost/" -out Server-certificate-signing-request.csrt $3
openssl genrsa -aes256 -passout pass:password -out Client-private-key.key 4096
openssl req -new -key Client-private-key.key -passin pass:password -subj "/CN=Client/" -out Client-certificate-signing-request.csrПодпишем запросы нашим сертификатом CA. Ключ CAcreateserial отвечает за создание файла (в данном случае CA-self-signed-certificate.srl) , в котором будет храниться серийный номер для следующего подписываемого этим сертификатом запроса. Серийный номер для текущего же сертификата сгенерируется случайно.
openssl x509 -req -in Server-certificate-signing-request.csr -CA CA-self-signed-certificate.pem -CAkey CA-private-key.key -passin pass:password -CAcreateserial -days 1 -out Server-certificate.pemt $4
openssl x509 -req -in Client-certificate-signing-request.csr -CA CA-self-signed-certificate.pem -CAkey CA-private-key.key -passin pass:password -days 1 -out Client-certificate.pemПосле этого необходимо создать хранилище ключей с сертификатами (keystore) Server-keystore.p12 для использования в нашем приложении. Положим туда сертификат сервера, приватный ключ сервера и защитим хранилище паролем “password”:
openssl pkcs12 -export -in Server-certificate.pem -inkey Server-private-key.key -passin pass:password -passout pass:password -out Server-keystore.p12 Осталось только создать хранилище доверенных сертификатов (truststore): сервер будет доверять всем клиентам, в цепочке подписания которых есть сертификат из truststore. К сожалению, для Java сертификаты в truststore должны содержать специальный object identifier, а OpenSSL пока не поддерживает их добавление. Поэтому здесь мы прибегнем к поставляемому вместе с JDK keytool:
keytool -import -file CA-self-signed-certificate.pem -keystore Server-truststore.p12 -storetype PKCS12 -storepass password -noprompt Для удобства, все описанные выше действия упакованы в bash script.
Двусторонний tls
Двусторонний TLS или Two Way TLS или mutual TLS (mTLS) означает проверку сертификата клиента. Сервер после своего сообщения Certificate посылает запрос сертификата клиента CertificateRequest. Клиент в ответ отправляет Certificate, сервер производит проверку, аналогичную проверке сертификата сервера клиентом. Далее настройка TLS происходит в описанном выше порядке.
Инфраструктура открытых ключей. цепочка корневых сертификатов x509 v.3
Неумолимо приближается час «Ч»: «использование схемы подписи ГОСТ Р 34.10-2001 для формирования подписи после 31 декабря 2021 года не допускается!». Однако потом что-то пошло не так, кто-то оказался не готов, и использование ГОСТ Р 34.10-2001 продлили на 2021 год. Но вдруг все бросились переводить УЦ на ГОСТ Р 34.10-2021, а простых граждан переводить на новые сертификаты. У людей на руках стало по нескольку сертификатов. При проверки сертификатов или электронной подписи стали возникать вопросы, а где взять корневые сертификаты, чтобы установить в хранилища доверенных корневых сертификатов.
Это касается как хранилища сертификатов в Windows, так и хранилища сертификатов в браузерах Firefox и Google Chrome, GnuPG, LibreOffice, почтовых клиентах и даже OpenSSL. Конечно, надо было озаботиться этим при получении сертификата в УЦ и записать цепочку сертификатов на флешку. А с другой стороны у нас же цифровое общество и в любой момент должна быть возможность получить эту цепочку из сети. Как это сделать на страницах Хабра показалsimpleadmin. Однако для рядового гражданина это все же сложновато (особенно, если иметь ввиду, что абсолютное их большинство сидит на Windows): нужно иметь «какой-то» openssl, утилиту fetch, которой и у меня не оказалось на компьютере, и далеко не каждый знает, что вместо нее можно использовать wget. А сколько действий нужно выполнить. Выход конечно есть, написать скрипт, но не просто скрипт поверх openssl и иже с ним, а упакованный в самодостаточный выполняемый модуль для различных платформ.
На чем писать никаких сомнений не было – на Tcl и Python. И начинаем с Tcl и вот почему:
* охренительной вики, где есть даже игрушки (там можно подсмотреть интересное 🙂
* шпаргалки
* нормальные сборки tclkit (1.5 — 2 Мб как плата за реальную кросс-платформенность)
* и моя любимая сборка eTcl от Evolane (бережно сохранённая с умершего сайта 🙁
сохраняют высокий рейтинг Tcl/Tk в моём личном списке инструментария
и, да, wiki.tcl.tk/16867 (мелкий web-сервер с cgi на Tcl, периодически используется с завидным постоянством под tclkit)
а ещё — это просто красиво и красиво 🙂
К этому бы я добавил наличии утилиты
freewrap
, которая нам и поможет собрать автономные (standalone) утилиты для Linux и MS Windows. В результате мы будем иметь утилиту chainfromcert:
bash-4.3$ ./chainfromcert_linux64
Copyright(C)2021
Usage:
chainfromcert <file with certificate> <directory for chain certificate>
Bad usage!
bash-4.3$В качестве параметров утилите задаются файл с пользовательским сертификатом (как в формате PEM, так и формате DER) и каталог, в котором будут сохранены сертификаты УЦ, входящие в цепочку:
bash-4.3$ ./chainfromcert_linux64 ./cert_test.der /tmp
Loading file: cert_test.der
Directory for chain: .
cert 1 from http://ca.ekey.ru/cdp/ekeyUC2021.cer
cert 2 from http://reestr-pki.ru/cdp/guc_gost12.crt
Goodby!
Length chain=2
Copyright(C) 2021
bash-4.3$А теперь рассмотрим как работает утилита.
Информация о центре сертификации, выдавшем сертификат пользователю, хранится в расширении с oid-ом 1.3.6.1.5.5.7.1.1. В этом расширении может хранится как о местонахождении сертификата УЦ (oid 1.3.6.1.5.5.7.48.2), так и информация о службе OCSP УЦ (oid 1.3.6.1.5.5.7.48.1):

А информация, например, о периоде использования ключа электронной подписи хранится в расширении с oid-ом 2.5.29.16.
Для разбора сертификата и доступа к расширениям сертификата воспользуемся пакетом pki:
#!/usr/bin/tclsh -f
package require pkiНам также потребуются пакет base64:
package require base64Пакет pki, а также подгружаемые им пакет asn, и пакет base64 и помогут нам преобразовывать сертификаты из PEM-кодировки в DER-кодировку, разобрать ASN-структуры и собственно получить доступ к информации о местонахождении сертификатов УЦ.
Работа утилиты начинается с проверки параметров и загрузки файла с сертификатом:
proc usage {use } {
puts "Copyright(C) 2021-2021"
if {$use == 1} {
puts "Usage:nchainfromcert <file with certificate> <directory for chain certificate>n"
}
}
if {[llength $argv] != 2 } {
usage 1
puts "Bad usage!"
exit
}
set file [lindex $argv 0]
if {![file exists $file]} {
puts "File $file not exist"
usage 1
exit
}
puts "Loading file: $file"
set dir [lindex $argv 1]
if {![file exists $dir]} {
puts "Dir $dir not exist"
usage 1
exit
}
puts "Directory for chain: $dir"
set fd [open $file]
chan configure $fd -translation binary
set data [read $fd]
close $fd
if {$data == "" } {
puts "Bad file with certificate=$file"
usage 1
exit
}Здесь все понятно и отметим только одно – файл с сертификатом рассматривается как бинарный файл:
chan configure $fd -translation binaryЭто связано с тем, что сертификат может хранится как в формате DER (двоичный код), так и в формате PEM (base64 — кодировка).
После того как файл загружен вызывается процедура chainfromcert:
set depth [chainfromcert $data $dir]которая собственно и загружает корневые сертификаты:
proc chainfromcert {cert dir} {
if {$cert == "" } {
exit
}
set asndata [cert_to_der $cert]
if {$asndata == "" } {
#Файл содержит все что угодно, только не сертификат
return -1
}
array set cert_parse [::pki::x509::parse_cert $asndata]
array set extcert $cert_parse(extensions)
if {![info exists extcert(1.3.6.1.5.5.7.1.1)]} {
#В сертификате нет расширений
return 0
}
set a [lindex $extcert(1.3.6.1.5.5.7.1.1) 0]
# if {$a == "false"} {
# puts $a
# }
#Читаем ASN1-последовательность расширения в Hex-кодировке
set b [lindex $extcert(1.3.6.1.5.5.7.1.1) 1]
#Переводим в двоичную кодировку
set c [binary format H* $b]
#Sequence 1.3.6.1.5.5.7.1.1
::asn::asnGetSequence c c_par_first
#Цикл перебора значений в засширении 1.3.6.1.5.5.7.1.1
while {[string length $c_par_first] > 0 } {
#Выбираем очередную последовательность (sequence)
::asn::asnGetSequence c_par_first c_par
#Выбираем oid из последовательности
::asn::asnGetObjectIdentifier c_par c_type
set tas1 [::pki::_oid_number_to_name $c_type]
#Выбираем установленное значение
::asn::asnGetContext c_par c_par_two
#Ищем oid с адресом корневого сертификата
if {$tas1 == "1.3.6.1.5.5.7.48.2" } {
#Читаем очередной корневой сертификат
set certca [readca $c_par $dir]
if {$certca == ""} {
#Прочитать сертификат не удалось. Ищем следующую точку с сертификатом
continue
} else {
global count
#Сохраняем корневой сертификат в указанном каталоге
set f [file join $dir [file tail $c_par]]
set fd [open $f w]
chan configure $fd -translation binary
puts -nonewline $fd $certca
close $fd
incr count
puts "cert $count from $c_par"
#ПОДЫМАЕМСЯ по ЦЕПОЧКЕ СЕРТИФИКАТОВ ВВЕРХ
chainfromcert $certca $dir
continue
}
} elseif {$tas1 == "1.3.6.1.5.5.7.48.1" } {
# puts "OCSP server (oid=$tas1)=$c_par"
}
}
# Цепочка закончилась
return $count
}К комментариям добавить нечего, но у нас осталась не рассмотренной процедура readca:
proc readca {url dir} {
set cer ""
#Читаем сертификат в бинарном виде
if {[catch {set token [http::geturl $url -binary 1]
#получаем статус выполнения функции
set ere [http::status $token]
if {$ere == "ok"} {
#Получаем код возврата с которым был прочитан сертификат
set code [http::ncode $token]
if {$code == 200} {
#Сертификат успешно прочитан и будет созвращен
set cer [http::data $token]
} elseif {$code == 301 || $code == 302} {
#Сертификат перемещен в другое место, получаем его
set newURL [dict get [http::meta $token] Location]
#Читаем сертификат с другого сервера
set cer [readca $newURL $dir]
} else {
#Сертификат не удалось прочитать
set cer ""
}
}
} error]} {
#Сертификат не удалось прочитать, нет узла в сети
set cer ""
}
return $cer
}Это процедура построена на использовании пакета http:
package require httpДля чтения сертификата мы используем следующую функцию:
set token [http::geturl $url -binary 1]Назначение остальных используемых функции понятно из комментариев. Дадим только расшифровку кодов возврата для функции http::ncodel:
200 Запрос успешно выполнен
206 Запрос успешно выполнен, но удалось скачать только часть файла
301 Файл перемещен в другое место
302 Файл временно перемещен в другое место
401 Требуется аутентификация на сервере
403 Доступ к этому ресурсу запрещен
404 Указанный ресурс не может быть найден
500 Внутренняя ошибка
Осталось не рассмотренной одна процедура, а именно cert_to_der:
proc cert_to_der {data} {
set lines [split $data n]
set hlines 0
set total 0
set first 0
#Ищем PEM-сертификат в файле
foreach line $lines {
incr total
if {[regexp {^-----BEGIN CERTIFICATE-----$} $line]} {
if {$first} {
incr total -1
break
} else {
set first 1
incr hlines
}
}
if {[regexp {^(.*):(.*)$} $line ]} {
incr hlines
}
}
if { $first == 0 && [string range $data 0 0 ] == "0" } {
#Очень похоже на DER-кодировку "0" == 0x30
return $data
}
if {$first == 0} {return ""}
set block [join [lrange $lines $hlines [expr {$total-1}]]]
#from PEM to DER
set asnblock [base64::decode $block]
return $asnblock
}Схема процедуры очень простая. Если это PEM-файл с сертификатом («—–BEGIN CERTIFICATE—– »), то выбирается тело этого файла и преобразуется в бинаоный код:
set asnblock [base64::decode $block]Если это не PEM-файл, то проверяется это «похожесть» на asn-кодировку (нулевой бит должен быть равен 0x30).
Вот собственно и все, осталось добавить завершающие строки:
if {$depth == -1} {
puts "Bad file with certificate=$file"
usage 1
exit
}
puts "Goodby!nLength chain=$depth"
usage 0
exit
Теперь все собираем в один файл с именем
Проверить работу этого файла можно с помощью интерпретарора tclsh:
$ tclsh ./chainfromcert.tcl cert_orlov.der /tmp
Loading file: cert_test.der
Directory for chain: /tmp
cert 1 from http://ca.ekey.ru/cdp/ekeyUC2021.cer
cert 2 from http://reestr-pki.ru/cdp/guc_gost12.crt
Goodby!
Length chain=2
Copyright(C) 2021
$В результате работы мы получили цепочку из двух сертификатов в каталоге /tmp.
Но мы хотели получить выполняемые модули для платформ Linux и Windowsи и чтобы пользователи не задумывались о каких-то интерпретаторах.
Для этой цели мы воспользуемся утилитой freewrapTCLSH. С помощью этой утилиты мы сделаем выполняемые модули нашей утилиты для платформ Linux и Windows как 32-х разрядных так и 64-х. Сборку утилит можно проводить для всех платформ на любой из платформ. Извините за тавтологию. Я буду собирать на linux_x86_64 (Mageia).
Для сборки потребуется:
1. Утилита freewrapTCLSH для платформы linux_x86_64;
2. Файл freewrapTCLSH с этой утилитой для каждой платформы:
— freewrapTCLSH_linux32
— freewrapTCLSH_linux64
— freewrapTCLSH_win32
— freewrapTCLSH_win64
3. Исходный файл нашей утилиты: chainfromcert.tcl
Итак, собираемый выполняемый файл chainfromcerty_linuxx86 для платформы Linux x86:
$freewrapTCLSH chainfromcert.tcl –w freewrapTCLSH_linux32 –o chainfromcerty_linuxx86
$Сборка утилиты для платформы Windows 64-х битного выглядит так:
$freewrapTCLSH chainfromcert.tcl –w freewrapTCLSH_win64 –o chainfromcerty_win64.exe
$И т.д. Утилиты готовы к использованию. Все необходимое для их работы они вобрали в себя.
Аналогичным образом пишется код и на Python-е.
В ближайшие дни я думаю дополнить пакет fsb795 (а он написан на Python-е) функцией получения цепочки корневых сертификатов.
Как построить цепочку сертификатов – бюро «печати и штампы»
2021-2021. ИП Ячменников К.А. | Бюро «Печати и штампы» | Тел.: 8 (4242) 300-445 | 7-914-748-12-98.
Адрес: Россия, Сахалинская область, г. Южно-Сахалинск, пр. Мира, 63, ТЦ “Эдем” (административный корпус, сразу за зданием ТЦ, идите за шлагбаум)
Информация на сайте не является публичной офертой.
Изготовление печатей, штампов, факсимиле, ЭЦП (электронная цифровая подпись) для ИП, ООО, ЗАО, ПАО, бюджетных учреждений. Печать врача, печать кадастрового инженера, печать адвоката, печать ИП, заказать печать ИП, заказать печать ООО, заказать печать врача, заказать печать. Штамп для организаций, штамп для бухгалтерии, штамп для отдела кадров, штамп для трудовых книжек, штамп копия верна, адресный штамп, угловой штамп.
Корневые сертификаты
Исторически и технологически сложилось так, что ряд центров сертификации получили наибольшее признание в области информационных компьютерных технологий. Поэтому было принято согласованное решение назвать их криптографические сертификаты корневыми и всегда доверять их электронным цифровым подписям.
Перечень корневых центров сертификации и их публичных ключей должен изначально храниться в компьютере пользователя: в операционной системе, в браузере, в других приложениях, использующих асимметричное шифрование.
Если цепочку последовательно подписанных сертификатов завершает корневой сертификат, все сертификаты, входящие в эту цепочку, считаются подтверждёнными.
В данном примере сертификаты «Б» и «В» называются промежуточными.
Корневые сертификаты, находящиеся в компьютере пользователя, хранятся в специальном контейнере, защищённом от случайного доступа посторонних. Тем не менее, возможность пополнять контейнер новыми корневыми сертификатами имеется, и в этом состоит один из источников опасности.
При определённых усилиях и наличии доступа к атакуемому компьютеру злоумышленник может включить в число корневых сертификатов свой и использовать его для расшифровки данных пользователя.
Корневым центр сертификации может быть назначен правительством той или иной страны или руководством корпорации. В этих случаях корневые центры сертификации не будут глобальными, но при этом они могут вполне успешно использоваться в конкретной стране или в рамках конкретного предприятия.
Сейчас перечень корневых центров сертификации в компьютере пользователя может автоматически изменяться при обновлении операционной системы, программных продуктов или вручную системным администратором.
Посмотреть локальные списки корневых сертификатов можно в настройках браузеров или операционной системы.
Поручители
В роли поручителя-удостоверителя выступает центр сертификации, который выпустил SSL-сертификат по запросу владельца сайта.
Сертификат и сайт, для которого он выпущен, удостоверяются электронной цифровой подписью (ЭЦП). Эта подпись, во-первых, указывает, кому принадлежит она сама, а во-вторых, фиксирует содержимое сертификата, то есть позволяет проверить, не был ли он кем-то изменён после выпуска и подписания.
Пусть некто «Б» удостоверил личность некоего «А».
Проблему можно считать преодолённой, если вы знаете и доверяете «Б», а что, если — нет: не знаете или не доверяете.
«Б», в свою очередь, может сообщить, что его знает «В».
В принципе, длина цепочки удостоверений не ограничена. Главное, чтобы в ней оказался тот, кому мы доверяем.
Мишу знает Боря, Борю знает Дима, Диму знает Вова, а вот уж Вову мы знаем сами. Помните шуточную теорию о шести рукопожатиях между двумя любыми людьми, одновременно живущими на Земле?
Однако в реальной жизни в цепочке знакомых между собой людей может долго не быть знакомого лично нам. Или эта цепочка может оказаться слишком длинной. Или потребовать слишком много ресурсов на свою обработку.
Сложности
В этот момент начинаются сложности. Сложность первая. Случается, что сертификат пользователя заполнен неправильно, не соответствует требованиям законодательства, в этом случае он должен быть перевыпущен. Как правило, подобную проблему порождает работник УЦ, который неправильно его заполнил, а проблемы получает пользователь, когда не может его нормально использовать.
Сложность вторая. Законодательство говорит о том, что УЦ – это юридическое лицо, и ГУЦ должен подписать сертификат этого УЦ. Ситуация, когда у одного юридического лица несколько комплексов УЦ и несколько сертификатов этих УЦ, толком в законах не прописана.
УЦ этим пользуются, часть сертификатов не подписывают с помощью сертификата ГУЦ и делают их в лучшем случае самовыпущенными – когда цепочку к ГУЦ можно построить только по имени УЦ в сертификате – или вообще самоподписанными – когда связи между сертификатами одного УЦ технически не существует, она есть только на бумаге.
Сложность третья. Если сертификат отозвали, УЦ обязан его добавить в список отозванных сертификатов (СОС), обязанность эта прописывается в RFC, если они приняты как стандарт в стране, или в регламенте ГУЦ, к которому обязаны присоединиться все аккредитованные УЦ.
В случае когда СОС (CRL) большой, УЦ для удобства пользователей выпускает дельта СОС (deltaCRL) с изменениями за короткий период. В регламенте ГУЦ прописана периодичность обновления 12 часов или по факту отзыва сертификатов. В реальности различные УЦ свои СОС публикуют как хотят, существуют некоторые УЦ, которые обновляют их 1 раз в несколько месяцев.
Или же СОС подписывается ключом, который не имеет отношения к сертификату УЦ, что тоже сводит шанс построить цепочку доверия к нулю. Потихоньку возникает проблема с обработкой самих СОС, за время существования УЦ они уже стали достаточно большого размера, но дельта СОС не выпускает почти никто.
Сложность четвертая, связная. Построение цепочки доверия в PKI так или иначе требует наличия связи с УЦ и ГУЦ и работу в онлайне. Работа в офлайне не предусмотрена. Существует ряд мест и приложений, где работа с подписями и сертификатами в офлайне очень бы пригодилась.
Сложность пятая, техническая. Иногда в программно-аппаратных комплексах УЦ все-таки находятся ошибки в логике и реализации, это также может влиять на построение цепочки доверия.
И только если на пути пользователя эти проблемы не встретились, цепочка доверия должна построится. В случае использования OCSP/TSP-служб проблемы тоже существуют, но это тема для отдельной статьи.
Итоги
В данной статье мы разобрались как работает протокол TLS и для чего он нужен. На практике научились создавать собственные сертификаты и использовать их в Java приложении на Spring Boot. Надеюсь, представленная информация оказалась Вам полезной. Спасибо за внимание!
Заключение
Важно понимать, что любая система криптографической защиты данных не может быть основана только на технических и технологических решениях. Она должна обязательно включать в себя и организационные аспекты.
P.S. Что еще можно почитать на тему SSL-сертификатов:
