В протоколе TLS (Transport Layer Security) используется шифрование, чтобы защитить трафик от подслушивания.

При этом, если кто-то сможет видеть проходящие по сети пакеты TCP/IP, то он не сможет прочитать их содержимое, поскольку это содержимое будет зашифровано. Трафик идет по зашифрованной "трубе" от отправителя к получателю и никто кроме отправителя или получателя не может его прочитать. Но одного шифрования недостаточно. Когда отправитель устанавливает зашифрованную трубу по направлению к получателю, он должен знать, что он ведет переговоры именно с тем получателем, который ему нужен. Когда получатель соглашается на установление зашифрованной трубы, он должен знать, что он ведет переговоры именно с тем отправителем, который ему нужен. Если злоумышленник окажется в середине между отправителем и получателем, то отправитель начнет переговоры об установлении зашифрованной трубы с злоумышленником, думая, что он ведет переговоры с получателем. Злоумышленник будет использовать информацию, полученную от отправителя, чтобы начать переговоры об установлении зашифрованной трубы с получателем. В результате и отправитель и получатель будут устанавливать зашифрованную трубу с злоумышленником, при этом они будут думать, что они напрямую разговаривают друг с другом, а не с злоумышленником. При этом злоумышленник окажется в середине и сможет видеть и даже изменять незашифрованный трафик, проходящий между отправителем и получателем в обоих направлениях. Такая атака на зашифрованный трафик называется "злоумышленник в середине" (Man-in-the-Middle attack). Такая атака возможна, когда отправитель и получатель не используют аутентификацию. Поэтому протокол TLS предусматривает обязательное использование аутентификации хотя бы в одном направлении (сервер обязан предъявить сертификат клиенту). Использование аутентификации в обратном направлении возможно, но не является обязательным (сервер может потребовать у клиента предъявить сертификат).

Использование аутентификации и цифровых сертификатов основано на свойствах пары шифровальных ключей:

  1. Если информация зашифрована с помощью первого ключа из пары, то она может быть расшифрована только с помощью второго ключа из этой же пары;
  2. Если известен первый ключ из пары, то по нему практически невозможно восстановить второй ключ из этой же пары.

Используя свойство 2, можно один из ключей сделать публичным и публично асоциировать его с именем сервера, так, чтобы все могли его видеть, а второй ключ всегда держать в секрете и хранить его на сервере. Когда клиент подключается к серверу, то сервер предъявляет клиенту свой публичный ключ, который ассоциирован с именем этого сервера. Клиент генерирует случайное число, шифрует это число, используя публичный ключ сервера, и посылает это зашифрованное число на сервер. Сервер расшифровывает это число, используя свой секретный ключ, и посылает расшифровыванное число назад клиенту. Клиент проверяет, что сервер вернул то же самое число, которое ему было отправлено. При этом клиент убеждается (используя свойство 1), что сервер имеет секретный ключ, который работает в паре с публичным ключом сервера. Это означает, что публичный ключ сервера принадлежит именно этому серверу, с которым устанавливается соединение, в противном случае сервер не смог бы правильно расшифровать случайное число.

В этой ситуации клиент полагается на то, что ему заранее известен публичный ключ сервера, и этот ключ используется, чтобы подтвердить, что этот сервер именно тот, за кого он себя выдает. Проблема в том, что клиент должен знать заранее и из надежных источников публичные ключи всех серверов, к которым он будет подключаться. В протоколе SSH эта проблема обычно решается просто. Когда сервер посылает публичный ключ клиенту, клиентская программа показывает этот ключ (число, содержащее 2048 бит) своему пользователю и спрашивает его: "Сервер, к которому я подключился прислал мне вот такой ключ. Действительно ли этот ключ принадлежит этому серверу? ". При этом предполагается, что пользователь клиентской программы может связаться с владельцем сервера (например, по зашифрованному телефонному каналу, зашифрованному E-mail или Chat) и попросить владельца сервера подтвердить, что этот публичный ключ действительно принадлежит этому серверу. На практике никто этого не делает и в большинстве случаев владелец клиентской программы просто отвечает: "да, этот ключ действительно принадлежит этому серверу", без того, чтобы действительно проверить это утверждение, связавшись с владельцем сервера. На самом деле этот публичный ключ может принадлежать злоумышленнику, но, это слишком хлопотно, проверить кому принадлежит этот ключ. Владелец SSH сервера должен распространять публичный ключ своего SSH сервера для установки во все клиентские программы SSH, которые будут подключаться к его серверу. Владельцы клиентских программ SSH должны устанавливать полученный публичный ключ SSH сервера в свои клиентские программы SSH, которые будут подключаться к этому серверу.

В протоколе TLS для аутентификации используются не сами публичные ключи, а цифровые сертификаты. Каждый владелец сервера посылает свой публичный ключ и свое имя сервера интернет-нотариусу (Certificate Authority - CA). Интернет-нотариус - это большая организация, которой все доверяют, она проверяет личность владельца сервера, а также имя его сервера, добавляет к этой проверенной информации публичный ключ сервера и скрепляет все три элемента информации в одно целое своей цифровой подписью.

Полученный подписанный файл, содержащий имя сервера и его публичный ключ, называется цифровым сертификатом. Когда клиент TLS получает цифровой сертификат сервера, то он сначала проверяет, что сервер имеет секретный ключ который соответствет публичному ключу указанному на сертификате сервера. Это значит что сервер являтся владельцем публичного ключа, указанного на сертификате. После этого клиент должен проверить, что этот публичный ключ ассоциирован именно с тем именем сервера, к которому нужно установить подключение. Для этого клиент должен проверить цифровую подпись нотариуса, которая скрепляет между собой имя сервера и его публичный ключ. Эта цифровая подпись проверяется с помощью публичного ключа самого интернет-нотариуса, который содержится в собственном сертификате интернет-нотариуса. Если цифровая подпись на сертификате сервера действительна, то клиент действительно имеет дело с сервером, имя которого указано на его сертификате. При этом клиент должен доверять интернет-нотариусу и иметь его собственный сертификат для проверки других сертификатов, которые выданы этим интернет-нотариусом.

Таким образом протокол TLS поручает проверку того, что данный публичный ключ принадлежит серверу с заданным именем интернет-нотариусу, а не пользователю клиентской программы, как это сделано в протоколе SSH. В результате аутентификация выполняется полностью автоматически, единственное, что пользователь клиентской TLS-программы должен сделать - это заранее установить сертификаты тех интернет-нотариусов, которым он доверяет. Для достижения того же уровня безопасности пользователь клиентской программы SSH должен лично связаться с владельцем каждого сервера, получить от него публичный ключ сервера и установить этот ключ в свою клиентскую программу SSH перед тем, как пытаться установить соединение с этим сервером.

Как показано выше, протокол TLS делегирует проверку ключей сервера интернет-нотариусу. Таких интернет-нотариусов, которому все доверяют имеется ограниченное количество и их собственные сертификаты, как правило, уже установлены в операционной системе и в ведущих веб браузерах. В больших корпорациях имеются подразделения, которые выполняют функции интернет-нотариусов внутри компании, при этом их сертификаты уже установлены на корпоративные компьютеры. Таким образом, в большинстве случаев инфраструктура для проверки сертификатов TLS сервера и TLS клиента уже присутствует на компьютере пользователя. Программа TLS сервера и TLS клиента просто должна иметь возможность воспользоваться этой существующей инфраструктурой.

Программа Proxy32 дает пользователю две возможности. Пользователь может либо использовать доверяемый список сертификатов нотариуса, который хранится в операционной системе и используется глобально для всего компьютера. На корпоративных компьютерах содержимое глобального списка может изменяться системными администраторами, а также пользователем самого компьютера, если у него есть соответствующие привилегии. Если пользователь не хочет пользоваться глобальным списком, который хранится в операционной системе, то он может создать собственное хранилище доверяемых сертификатов нотариуса в специальном файле с расширением ".pfx", который защищается паролем. Этот файл указывается программе Proxy32 как хранилище доверяемых сертификатов нотариуса, и с этого момента только сертификаты, подписанные нотариусами из этого списка будут приниматься программой Proxy32 при подключении по протоколу TLS. Proxy32 имеет специальные функции, которые позволяют пользователю создавать PFX-файлы (хранилища сертификатов), а также просматривать, удалять, импортировать и экспортировать сертификаты из таких файлов.

Имеются также различные опции, которые позволяют настроить процесс проверки сертификата сервера с помощью сертификата нотариуса. Обычно сертификат сервера должен быть подписан одним из доверяемых нотариусов, если цифровая подпись действительна, то после этого проверяется информация, содержащаяся в самом сертификате: - срок действия этого сертификата не должен быть истекшим; - имя на сертификате должно соответствовать имени или IP адресу компьютера, на котором находится TLS сервер, предъявляющий этот сертификат; - иногда также требуется, чтобы сертификат сервера был явно помечен как разрешенный для использования в качестве сертификата сервера; - кроме того, в некоторых случаях также требуется, чтобы сертификат сервера был помечен, что он не является сертификатом нотариуса; - в некоторых случаях также требуется, чтобы сам сертификат сервера был заранее установлен в доверяемом хранилище в клиентской программе. при этом клиентская программа проверяет, что сертификат, который прислал сервер в точности соответствует сертификату, который уже установлен в доверяемом хранилище в клиентской программе. Это требование может применяться как в дополнение, так и вместо требования, чтобы сертификат был подписан доверяемым нотариусом.

Все перечисленные проверки могут иметь значение для того, примет ли клиентская программа сертификат сервера или откажется от установления соединения. В хорошей программе все перечисленные проверки могут включаться или выключаться в зависимости от требований пользователя.

Аналогичные проверки выпоняются над сертификатом клиента в серверной программе, если сервер сконфигурирован, чтобы запрашивать сертификат у клиента и, если клиент имеет и предъявляет такой сертификат. Единственная разница состоит в том, что обычно имя на сертификате клиента может отражать имя пользователя клиентской программы, а не имя компьютера, на котором эта программа запущена. По этой причине сравнение имени на сертификате клиента с именем компьютера клиента обычно не производится по умолчанию.

До сих пор мы рассматривали, как осуществляется проверка сертификата, который прислан с противоположной стороны и заметили, что обычно это осуществляется с помощью существующей инфраструктуры и не требует вмешательства пользователя. Для того, чтобы предъявить сертификат предъявляющая сторона должна его уже иметь и он должен быть уже установлен (вместе с секретным ключом) в TLS клиенте или в TLS сервере. В крупных корпорациях, такие сертификаты могут быть уже заранее установлены в системное хранилище на компьютере пользователя или заказаны и установлены на компьютер пользователя по его заказу.

Обычный пользователь имеет две возможности:

Следует подчеркнуть, что использование интернет-нотариуса является основной опцией для аутентификации в TLS протоколе. Она позволяет большой группе пользователей аутентифицировать друг друга по протоколу TLS, при этом все эти пользователи не должны обмениваться ключами друг с другом, а только регистрировть свои ключи у глобального интернет-нотариуса, которому они доверяют. Вторая опция, когда пользователь сам выполняет функции локального интернет-нотариуса, имеет смысл только, когда она экономически обоснована, например, когда группа пользователей, которые должны взаимодействовать очень небольшая и все пользователи могут обменяться своими сертификатами друг с другом. Другая ситуация, когда вторая опция необходима - это когда IP адрес TLS сервера является динамическим и клиенты не могут подключаться к этому серверу, используя имя компьютера вместо IP адреса.

Когда пользователь собирается использовать протокол TLS, он должен выбрать необходимую конфигурацию этого протокола:

Пользователь имеет две опции, которые обеспечивают аутентификацию и достаточную защиту (2048 бит или 4096 бит).

Первая опция - это использовать готовый сертификат, подписанный глобальным интернет-нотариусом или интернет-нотариусом компании. Этот сертификат может быть уже установлен на компьютер пользователя или его нужно заказать интернет-нотариусу, а затем установить его на компьютер пользователя. Сертификат может быть установлен на компьютере пользователя или в системном хранилище сертификатов Windows или в PFX-файле. Proxy32 позволяет загружать сертификат для использования в TLS сервере или из системного хранилища Windows или из PFX-файла на диске. Поскольку сертификат должен загружаться вместе с его секретным ключом, то он может быть защищен паролем, который пользователь должен ввести при загрузке секретного ключа. При использовании системного хранилища Windows пароль может и не использоваться, если ключ был установлен в системное хранилище без пароля. При загрузке ключа из PFX-файла пароль используется всегда, но можно задать его, например, как "password" и позволить программе автоматически вводить этот пароль при загрузке ключа, не спрашивая пользователя. Все эти опции доступны в программе Proxy32. Для того, чтобы загрузить сертификат, пользователь должен задать имя системного хранилища или имя и пароль PFX-файла. После этого пользователь должен просмотреть выбранное хранилище и выбрать в этом хранилище сертификат, который он хочет загрузить в TLS сервер. Сертификат должен иметь секретный ключ и этот ключ должен соответствовать публичному ключу, который указан на сертификате. После того, как сертификат загружен вручную, Proxy32 запоминает имя этого сертификата и его контрольную сумму (SHA1 hash). Используя эти два параметра, Proxy32 сможет загрузить этот сертификат автоматически при следующем старте программы. Контрольная сумма нужна потому, что в одном хранилище могут находится несколько сертификатов с одним и тем же именем. При автоматической загрузке сертификата при следующем старте программы пользователь не должен вводить пароль, если секретный ключ установлен в системное хранилище без пароля или если секретный ключ загружается из PFX-файла, который создан с паролем "password", если программе разрешено автоматически вводить этот пароль при загрузке PFX-файла.

Вторая опция позволяет пользователю самому выполнять функции интрнет-нотариуса вместо того, чтобы обращаться к существующему интернет-нотариусу за сертификатом. В этом случае пользователь создает себе свой собственный сертификат интернет-нотариуса, а затем использует его, чтобы подписывать сертификат для своего TLS сервера и своего TLS клиента. Такой подход имеет один недостаток: пользователь должен сам распространять свой сертификат интернет-нотариуса на все компьютеры и программы, с которыми он будет устанавливать соединения. Этот сертификат должен быть установлен в хранилище доверяемых сертификатов нотариуса для того, чтобы компьютер или программа могли использовать его для проверки сертификата, который они получают от противоположной стороны. Имеется два варианта использования такого подхода. При обычном варианте пользователь создает сертификаты для своего сервера и клиента и устанавливает их в системное хранилище Windows или в файл PFX для их использования на постоянной основе. Такой вариант является оптимальным, поскольку пользователь создает сертификат только один раз и дальше этот сертификат просто хранится и не нужно тратить время на его повторное создание, а также его можно послать противоположной стороне для того, чтобы его установили до создания соединения и использовали для дополнительной проверки. В некоторых случаях TLS сервер может быть запущен на компьютере, к которому нельзя подключаться, используя имя компьютера. В этом случае можно подключаться к серверу по IP адресу, но, если этот IP адрес часто изменяется (является динамическим, а не статическим), то адрес для подключения к серверу будет часто изменяться. Поскольку имя на сертификате сервера должно совпадать с адресом компьютера, на котором запущен сервер, в такой ситуации невозможно использовать один заранее выпущенный сертификат сервера. Сертификат сервера нужно перевыпускать заново при каждом изменении адреса сервера. При этом возможно, используя собственный сертификат нотариуса (который загружается из системного хранилища или из PFX-файла) создавать новый сертификат сервера при каждом изменении адреса сервера. Можно перевыпускать сертификат сервера вручную, а затем сохранять его в системное хранилище или PFX-файл для последующей загрузки в сервер. А можно перевыпускать сертификат сервера автоматически при каждом старте программы, загружать его в сервер, но не сохранять его в системное хранилище или в PFX-файл. Таким образом, имеется две опции для загрузки сертификата в TLS сервер: загрузка существующего сертификата из системного хранилища или из PFX-файла (безотносительно к тому, выпущен ли сертификат глобальны нотариусом или пользователь сам выполнял функции нотариуса) или автоматическое создание нового сертификата и загрузка его в сервер без сохранения этого сертификата в системное хранилище или в PFX-файл.

Две опции по процессу создания сертификата:

  1. Заказать его глобальному интернет-нотариусу;
  2. Самому выпустить сертификат, используя свой собственный сертификат интернет-нотариуса.

Две опции по процессу загрузки сертификата в сервер:

  1. Загрузить существующий сертификат сервера из системного хранилища или из PFX-файла;
  2. Загрузить сертификат нотариуса из системного хранилища или из PFX-файла и использовать его для автоматического создания временного сертификата сервера.

Процесс загрузки сертификата в сервер может выполняться: