TLS (SSL)
Модуль tls предоставляет реализацию протоколов Transport Layer Security (TLS) и Secure Socket Layer (SSL), построенную поверх OpenSSL. К модулю можно обратиться, используя:
const tls = require('tls');
Концепции TLS/SSL
TLS/SSL использует инфраструктуру открытых ключей (PKI). В большинстве распространённых случаев каждый клиент и сервер должен иметь приватный ключ.
Приватные ключи можно генерировать различными способами. Пример ниже демонстрирует использование командной строки OpenSSL для генерации приватного ключа RSA с размером 2048 бит:
openssl genrsa -out ryans-key.pem 2048
В TLS/SSL все серверы (и некоторые клиенты) должны иметь сертификат. Сертификаты являются открытыми ключами, соответствующими приватным ключам, и подписаны либо центром сертификации, либо владельцем приватного ключа (такие сертификаты называются "самоподписанными"). Первым шагом получения сертификата является создание файла запроса на подписание сертификата (CSR).
Командная строка OpenSSL может использоваться для генерации CSR для приватного ключа:
openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem
После генерации файла CSR его можно отправить в центр сертификации для подписания или использовать для генерации самоподписанного сертификата.
Создание самоподписанного сертификата с использованием командной строки OpenSSL проиллюстрировано в примере ниже:
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
После генерации сертификата его можно использовать для создания файла .pfx или .p12:
openssl pkcs12 -export -in ryans-cert.pem -inkey ryans-key.pem \
-certfile ca-cert.pem -out ryans.pfx
Где:
-
in: подписанный сертификат -
inkey: соответствующий приватный ключ -
certfile: объединение всех сертификатов центров сертификации (CA) в один файл, напримерcat ca1-cert.pem ca2-cert.pem > ca-cert.pem
Совершенная передача секрета
Термин "Совершенная передача секрета" или "Perfect Forward Secrecy" описывает функцию методов согласования ключей (т.е., обмена ключами). То есть, ключи сервера и клиента используются для переговоров о новых временных ключах, которые используются только для текущей сессии связи. Практически это означает, что даже если приватный ключ сервера скомпрометирован, связь может быть расшифрована злоумышленниками только если злоумышленник получит пару ключей, сгенерированную специально для этой сессии.
Совершенная передача секрета достигается случайным генерированием пары ключей для согласования ключей на каждом рукопожатии TLS/SSL (в отличие от использования одного ключа для всех сессий). Методы, реализующие эту технику, называются "эфемеразными".
В настоящее время для достижения совершенной передачи секрета обычно используются два метода (обратите внимание на добавленную букву "E" в традиционных сокращениях):
- DHE - Эфемеральная версия протокола обмена ключами Диффи-Хеллмана.
- ECDHE - Эфемеральная версия протокола обмена ключами эллиптических кривых Диффи-Хеллмана.
Эфемеральные методы могут иметь некоторые недостатки производительности, потому что генерация ключей ресурсоемка.
Для использования совершенной передачи секрета с использованием DHE с модулем tls необходимо сгенерировать параметры Диффи-Хеллмана и указать их с помощью параметра dhparam к tls.createSecureContext(). Следующее иллюстрирует использование командной строки OpenSSL для генерации таких параметров:
openssl dhparam -outform PEM -out dhparam.pem 2048
Если использовать совершенную передачу секрета с ECDHE, параметры Диффи-Хеллмана не требуются, и будет использована кривая ECDHE по умолчанию. Свойство ecdhCurve может быть использовано при создании TLS-сервера для указания списка имён поддерживаемых кривых, см. tls.createServer() для получения дополнительной информации.
ALPN, NPN и SNI
ALPN (расширение протокола уровня приложения), NPN (следующий протокол) и SNI (указание имени сервера) — это расширения рукопожатия TLS:
- ALPN/NPN — позволяет использовать один TLS-сервер для нескольких протоколов (HTTP, SPDY, HTTP/2)
- SNI — позволяет использовать один TLS-сервер для нескольких имен хостов с различными SSL-сертификатами.
Примечание: Использование ALPN рекомендуется по сравнению с NPN. Расширение NPN никогда не было официально определено или задокументировано и, как правило, не рекомендуется для использования.
Смягчение атак на переподключение, инициируемых клиентом
Протокол TLS позволяет клиентам переподключаться к определённым аспектам сессии TLS. К сожалению, переподключение требует непропорционально больших ресурсов на стороне сервера, что делает его потенциальным вектором атак типа "отказ в обслуживании".
Для смягчения риска переподключение ограничено тремя попытками каждые десять минут. Событие 'error' генерируется на экземпляре tls.TLSSocket, когда этот порог превышен. Пределы могут быть настроены:
-
tls.CLIENT_RENEG_LIMIT<число> Указывает количество запросов на переподключение. По умолчанию:3. -
tls.CLIENT_RENEG_WINDOW<число> Указывает время окна переподключения в секундах. По умолчанию:600(10 минут).
Примечание: Значения по умолчанию для ограничений переподключения не должны изменяться без полного понимания последствий и рисков.
Для проверки ограничений переподключения на сервере подключитесь к нему с помощью клиентской командной строки OpenSSL (openssl s_client -connect address:port), затем введите R<CR> (т.е. буква R, за которой следует возврат каретки) несколько раз.
Изменение набора шифров TLS по умолчанию
Node.js разработан с набором шифров TLS по умолчанию, включённых и отключённых. В настоящее время набор шифров по умолчанию:
ECDHE-RSA-AES128-GCM-SHA256: ECDHE-ECDSA-AES128-GCM-SHA256: ECDHE-RSA-AES256-GCM-SHA384: ECDHE-ECDSA-AES256-GCM-SHA384: DHE-RSA-AES128-GCM-SHA256: ECDHE-RSA-AES128-SHA256: DHE-RSA-AES128-SHA256: ECDHE-RSA-AES256-SHA384: DHE-RSA-AES256-SHA384: ECDHE-RSA-AES256-SHA256: DHE-RSA-AES256-SHA256: HIGH: !aNULL: !eNULL: !EXPORT: !DES: !RC4: !MD5: !PSK: !SRP: !CAMELLIA
Этот набор по умолчанию можно полностью заменить с помощью командной строки --tls-cipher-list. Например, следующее делает ECDHE-RSA-AES128-GCM-SHA256:!RC4 набором шифров TLS по умолчанию:
node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
Его также можно заменить на уровне клиента или сервера с помощью опции ciphers из tls.createSecureContext(), которая также доступна в tls.createServer(), tls.connect() и при создании новых tls.TLSSocket.
Для получения подробностей о формате см. документацию OpenSSL по формату списка шифров.
Примечание: Набор шифров по умолчанию в Node.js тщательно подобран для соответствия современным рекомендациям по безопасности и смягчению рисков. Изменение набора шифров по умолчанию может значительно повлиять на безопасность приложения. Переключатель --tls-cipher-list и опция ciphers должны использоваться только в крайних случаях.
Набор шифров по умолчанию отдает предпочтение шифрам GCM для настройки «современной криптографии» Chrome, а также предпочитает шифры ECDHE и DHE для совершенной передачи секрета, при этом предлагая некоторую обратную совместимость.
128-битный AES предпочтительнее 192 и 256-битного AES в свете конкретных атак, влияющих на более крупные размеры ключей AES.
Старые клиенты, которые полагаются на небезопасные и устаревшие шифры RC4 или DES (например, Internet Explorer 6), не могут завершить процесс рукопожатия с конфигурацией по умолчанию. Если эти клиенты должны поддерживаться, рекомендации TLS могут предложить совместимый набор шифров. Для получения дополнительных сведений о формате см. документацию OpenSSL по формату списка шифров.
Класс: tls.Server
Класс tls.Server — подкласс net.Server, принимающий зашифрованные подключения с использованием TLS или SSL.
Событие: 'newSession'
Событие 'newSession' генерируется при создании новой сессии TLS. Его можно использовать для хранения сессий во внешнем хранилище. Обработчик событий получает три аргумента:
-
sessionId— идентификатор сессии TLS -
sessionData— данные сессии TLS -
callback<Функция> Функция обратного вызова без аргументов, которую необходимо вызвать, чтобы данные могли быть отправлены или получены по защищённому соединению.
Примечание: Прослушивание этого события будет иметь эффект только на подключениях, созданных после добавления слушателя.
Событие: 'OCSPRequest'
Событие 'OCSPRequest' генерируется, когда клиент отправляет запрос на статус сертификата. Обработчик событий получает три аргумента:
-
certificate<Буфер> Сертификат сервера -
issuer<Буфер> Сертификат издателя -
callback<Функция> Функция обратного вызова, которую необходимо вызвать для предоставления результатов запроса OCSP.
Текущий сертификат сервера можно проанализировать, чтобы получить URL OCSP и идентификатор сертификата; после получения ответа OCSP, вызывается callback(null, resp), где resp — экземпляр Buffer, содержащий ответ OCSP. И certificate, и issuer являются Buffer DER-представлениями основных и издательских сертификатов. Эти данные можно использовать для получения идентификатора OCSP-сертификата и URL OCSP-пункта.
В качестве альтернативы, можно вызвать callback(null, null), указав, что ответа OCSP не было.
Вызов callback(err) приведёт к вызову socket.destroy(err).
Типичный поток запроса OCSP выглядит следующим образом:
- Клиент подключается к серверу и отправляет
'OCSPRequest'(через расширение информации о статусе в ClientHello). - Сервер получает запрос и генерирует событие
'OCSPRequest', вызывая обработчик, если он зарегистрирован. - Сервер извлекает URL OCSP из либо
certificate, либоissuerи выполняет запрос OCSP к CA. - Сервер получает
OCSPResponseот CA и отправляет его клиенту через аргументcallback - Клиент проверяет ответ и либо закрывает сокет, либо выполняет рукопожатие.
Примечание: issuer может быть null, если сертификат самозаверяемый или издатель отсутствует в списке корневых сертификатов. (Издатель может быть предоставлен через опцию ca при установлении TLS-соединения.)
Примечание: Прослушивание этого события будет влиять только на подключения, установленные после добавления обработчика события.
Примечание: Модуль npm, такой как asn1.js, может использоваться для анализа сертификатов.
Событие: 'resumeSession'
Событие 'resumeSession' генерируется, когда клиент запрашивает возобновление предыдущей TLS-сессии. Обработчик события получает два аргумента:
-
sessionId- Идентификатор TLS/SSL-сессии -
callback<Функция> Функция обратного вызова, которая будет вызвана, когда предыдущая сессия будет восстановлена.
При вызове обработчик события может выполнить поиск во внешнем хранилище, используя указанный sessionId, и вызвать callback(null, sessionData) по завершении. Если сессия не может быть возобновлена (т.е. не существует в хранилище), обратный вызов может быть вызван как callback(null, null). Вызов callback(err) завершит входящее соединение и уничтожит сокет.
Примечание: Прослушивание этого события будет влиять только на подключения, установленные после добавления обработчика события.
В качестве примера, возобновление TLS-сессии:
const tlsSessionStore = {};
server.on('newSession', (id, data, cb) => {
tlsSessionStore[id.toString('hex')] = data;
cb();
});
server.on('resumeSession', (id, cb) => {
cb(null, tlsSessionStore[id.toString('hex')] || null);
});
Событие: 'secureConnection'
Событие 'secureConnection' генерируется после успешного завершения процесса рукопожатия для нового соединения. Обработчик события получает один аргумент:
-
tlsSocket<tls.TLSSocket> Установленный TLS-сокет.
Свойство tlsSocket.authorized — это boolean, указывающее, был ли клиент проверен одним из предоставленных сертификатов авторизации для сервера. Если tlsSocket.authorized равно false, то socket.authorizationError описывает, как произошла ошибка авторизации. Обратите внимание, что в зависимости от настроек TLS-сервера, неавторизованные подключения могут всё же быть приняты.
Свойства tlsSocket.npnProtocol и tlsSocket.alpnProtocol — это строки, содержащие выбранные протоколы NPN и ALPN соответственно. Когда оба расширения NPN и ALPN получены, ALPN имеет приоритет над NPN, и следующий протокол выбирается по ALPN.
Если ALPN не выбрал протокол, то tlsSocket.alpnProtocol возвращает false.
Свойство tlsSocket.servername — это строка, содержащая имя сервера, запрошенное через SNI.
Событие: 'tlsClientError'
Событие 'tlsClientError' генерируется, когда происходит ошибка до установления защищенного соединения. Обработчик события получает два аргумента:
-
exception<Ошибка> ОбъектError, описывающий ошибку -
tlsSocket<tls.TLSSocket> Экземплярtls.TLSSocket, из которого произошла ошибка.
server.addContext(hostname, context)
-
hostname<Строка> Имя хоста SNI или подстановка (например,'*') -
context<Объект> Объект, содержащий любые возможные свойства из аргументовtls.createSecureContext()options(например,key,cert,caи т.д.).
Метод server.addContext() добавляет защищённый контекст, который будет использован, если имя хоста SNI клиента соответствует предоставленному hostname (или подстановке).
server.address()
Возвращает связанный адрес, имя семейства адресов и порт сервера, как сообщается операционной системой. Подробнее см. net.Server.address().
server.close([callback])
-
callback<Функция> Необязательный обработчик обратного вызова, который будет зарегистрирован для прослушивания события'close'экземпляра сервера.
Метод server.close() останавливает сервер от приема новых подключений.
Эта функция работает асинхронно. Событие 'close' будет генерироваться, когда у сервера не будет открытых подключений.
server.connections
server.getConnections() вместо этого.Возвращает текущее количество одновременных подключений на сервере.
server.getTicketKeys()
Возвращает экземпляр Buffer, содержащий ключи, которые в настоящее время используются для шифрования/расшифровки TLS Session Tickets
server.listen()
Запускает сервер, ожидающий зашифрованных подключений. Этот метод идентичен server.listen() из net.Server.
server.setTicketKeys(keys)
-
keys<Буфер> Ключи, используемые для шифрования/расшифровки TLS Session Tickets.
Обновляет ключи для шифрования/расшифровки TLS Session Tickets.
Примечание: Длина ключа Buffer должна быть 48 байт. См. опцию ticketKeys в tls.createServer для получения дополнительной информации о его использовании.
Примечание: Изменения в ключах билетов действуют только для будущих подключений сервера. Существующие или текущие ожидающие подключения сервера будут использовать предыдущие ключи.
Класс: tls.TLSSocket
tls.TLSSocket — это подкласс net.Socket, который выполняет прозрачное шифрование записанных данных и всю необходимую TLS-переговоры.
Экземпляры tls.TLSSocket реализуют интерфейс дуплексного потока Stream.
Примечание: Методы, возвращающие метаданные TLS-соединения (например, tls.TLSSocket.getPeerCertificate()), будут возвращать данные только пока подключение открыто.
new tls.TLSSocket(socket[, options])
-
socket<net.Socket> | <stream.Duplex> На стороне сервера любойDuplexпоток. На стороне клиента любой экземплярnet.Socket(для поддержки общихDuplexпотоков на стороне клиента, необходимо использоватьtls.connect()). -
options<Object>-
isServer: Протокол SSL/TLS ассиметричный, TLSSockets должны знать, будут ли они вести себя как сервер или клиент. Еслиtrue, то сокет TLS будет инициализирован как сервер. По умолчанию:false. -
server<net.Server> Необязательный экземплярnet.Server. -
requestCert: Нужно ли проверять подлинность удалённого узла, запрашивая сертификат. Клиенты всегда запрашивают сертификат сервера. Серверы (еслиisServerравно true) могут по желанию установитьrequestCertв true, чтобы запросить сертификат клиента. -
rejectUnauthorized: Необязательно, см.tls.createServer() -
NPNProtocols: Необязательно, см.tls.createServer() -
ALPNProtocols: Необязательно, см.tls.createServer() -
SNICallback: Необязательно, см.tls.createServer() -
session<Buffer> Необязательный экземплярBuffer, содержащий сеанс TLS. -
requestOCSP<boolean> Еслиtrue, указывает, что расширение запроса статуса OCSP будет добавлено в клиенту hello, и событие'OCSPResponse'будет выведено в сокете перед установлением защищенного соединения. -
secureContext: Необязательный объект контекста TLS, созданный с помощьюtls.createSecureContext(). ЕслиsecureContextне указан, он будет создан путём передачи всего объектаoptionsвtls.createSecureContext(). - ...: Необязательные опции
tls.createSecureContext(), которые используются, если опцияsecureContextотсутствует, иначе они игнорируются.
-
Создаёт новый объект tls.TLSSocket из существующего TCP-соккета.
Событие: 'OCSPResponse'
Событие 'OCSPResponse' генерируется, если опция requestOCSP была установлена при создании tls.TLSSocket и получен ответ OCSP. Обработчик событий получает один аргумент:
-
response<Buffer> Ответ OCSP сервера
Обычно, ответ OCSP — это цифрово подписанный объект от CA сервера, который содержит информацию о статусе отзыва сертификата сервера.
Событие: 'secureConnect'
Событие 'secureConnect' генерируется после успешного завершения процесса установления рукопожатия для нового соединения. Обработчик событий будет вызван независимо от того, был ли авторизован сертификат сервера. Клиент отвечает за проверку свойства tlsSocket.authorized, чтобы определить, был ли сертификат сервера подписан одной из указанных CA. Если tlsSocket.authorized === false, то ошибку можно найти, проверив свойство tlsSocket.authorizationError. Если использовались ALPN или NPN, то можно проверить свойства tlsSocket.alpnProtocol или tlsSocket.npnProtocol, чтобы определить согласованный протокол.
tlsSocket.address()
Возвращает привязанный адрес, имя семейства адресов и порт подлежащего сокета, как сообщает операционная система. Возвращает объект с тремя свойствами, например, { port: 12346, family: 'IPv4', address: '127.0.0.1' }
tlsSocket.authorizationError
Возвращает причину, по которой сертификат узла не был проверен. Это свойство устанавливается только когда tlsSocket.authorized === false.
tlsSocket.authorized
Возвращает true, если сертификат узла был подписан одной из CA, указанных при создании экземпляра tls.TLSSocket, в противном случае false.
tlsSocket.disableRenegotiation()
Отключает переустановку TLS для данного экземпляра TLSSocket. После вызова попытки переустановки приведут к срабатыванию события 'error' в TLSSocket.
tlsSocket.encrypted
Всегда возвращает true. Это может использоваться для различения TLS-сокет от обычных net.Socket экземпляров.
tlsSocket.getCipher()
Возвращает объект, представляющий имя шифра. Ключ version — это устаревшее поле, которое всегда содержит значение 'TLSv1/SSLv3'.
Например: { name: 'AES256-SHA', version: 'TLSv1/SSLv3' }
См. SSL_CIPHER_get_name() в https://www.openssl.org/docs/man1.0.2/ssl/SSL_CIPHER_get_name.html для получения дополнительной информации.
tlsSocket.getEphemeralKeyInfo()
Возвращает объект, представляющий тип, имя и размер параметра обмена временным ключом в идеальной секретности вперёд при соединении с клиентом. Возвращает пустой объект, когда обмен ключами не временный. Поскольку это поддерживается только в клиентском сокете, при вызове на серверном сокете возвращается null. Поддерживаемые типы — 'DH' и 'ECDH'. Свойство name доступно только в том случае, когда тип равен 'ECDH'.
Например: { type: 'ECDH', name: 'prime256v1', size: 256 }
tlsSocket.getFinished()
- Возвращает: <Buffer> | <undefined> Последнее сообщение
Finished, которое было отправлено в сокет в рамках процесса установления рукопожатия SSL/TLS, илиundefined, если ещё не было отправлено ни одного сообщенияFinished.
Поскольку сообщения Finished представляют собой хэши всего процесса установления рукопожатия (192 бита для TLS 1.0 и больше для SSL 3.0), они могут использоваться для внешних процедур проверки подлинности, когда проверка подлинности, предоставляемая SSL/TLS, не требуется или недостаточна.
Соответствует процедуре SSL_get_finished в OpenSSL и может использоваться для реализации привязки канала tls-unique из RFC 5929.
tlsSocket.getPeerCertificate([detailed])
-
detailed<boolean> Включать полную цепочку сертификатов, еслиtrue, иначе включать только сертификат узла.
Возвращает объект, представляющий сертификат узла. Возвращённый объект имеет некоторые свойства, соответствующие полям сертификата.
Если была запрошена полная цепочка сертификатов, каждый сертификат будет содержать свойство issuerCertificate, содержащее объект, представляющий сертификат его издателя.
Например:
{ subject:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
O: 'node.js',
OU: 'Test TLS Certificate',
CN: 'localhost' },
issuer:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
O: 'node.js',
OU: 'Test TLS Certificate',
CN: 'localhost' },
issuerCertificate:
{ ... another certificate, possibly with a .issuerCertificate ... },
raw: < RAW DER buffer >,
valid_from: 'Nov 11 09:52:22 2009 GMT',
valid_to: 'Nov 6 09:52:22 2029 GMT',
fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
serialNumber: 'B9B0D332A1AA5635' }
Если узел не предоставляет сертификат, будет возвращён пустой объект.
tlsSocket.getPeerFinished()
- Возвращает: <Buffer> | <undefined> Последнее сообщение
Finished, которое ожидается или уже получено от сокета в рамках процесса установления рукопожатия SSL/TLS, илиundefined, если пока нет сообщенияFinished.
Поскольку сообщения Finished представляют собой хэши всего процесса установления рукопожатия (192 бита для TLS 1.0 и больше для SSL 3.0), они могут использоваться для внешних процедур проверки подлинности, когда проверка подлинности, предоставляемая SSL/TLS, не требуется или недостаточна.
Соответствует процедуре SSL_get_peer_finished в OpenSSL и может использоваться для реализации привязки канала tls-unique из RFC 5929.
tlsSocket.getProtocol()
Возвращает строку, содержащую согласованную версию протокола SSL/TLS текущего соединения. Значение 'unknown' будет возвращено для подключённых сокетов, которые не завершили процесс рукопожатия. Значение null будет возвращено для серверных сокетов или отключённых клиентских сокетов.
Примеры ответов:
TLSv1TLSv1.1TLSv1.2unknown
См. https://www.openssl.org/docs/man1.0.2/ssl/SSL_get_version.html для получения дополнительной информации.
tlsSocket.getSession()
Возвращает закодированную в ASN.1 сессию TLS или undefined, если сессия не была согласована. Может использоваться для ускорения установления рукопожатия при повторном подключении к серверу.
tlsSocket.getTLSTicket()
Возвращает билет сеанса TLS или undefined, если сессия не была согласована.
Примечание: Это работает только с клиентскими TLS-сокет. Полезно только для отладки; для повторного использования сеанса укажите параметр session в tls.connect().
tlsSocket.localAddress
Возвращает строковое представление локального IP-адреса.
tlsSocket.localPort
Возвращает числовое представление локального порта.
tlsSocket.remoteAddress
Возвращает строковое представление удалённого IP-адреса. Например, '74.125.127.100' или '2001:4860:a005::68'.
tlsSocket.remoteFamily
Возвращает строковое представление семейства удалённого IP. 'IPv4' или 'IPv6'.
tlsSocket.remotePort
Возвращает числовое представление удалённого порта. Например, 443.
tlsSocket.renegotiate(options, callback)
-
options<Объект>-
rejectUnauthorized<логическое значение> Если неfalse, сертификат сервера проверяется по списку предоставленных CA. Если проверка завершилась ошибкой, генерируется событиеerr.code;err.codeсодержит код ошибки OpenSSL. По умолчанию:true. requestCert
-
-
callback<Функция> Функция, которая будет вызвана при завершении запроса на переподключение.
Метод tlsSocket.renegotiate() инициирует процесс переподключения TLS. По завершении, функция callback получит единственный аргумент, который будет либо объектом Error (если запрос не удался), либо null.
Примечание: Этот метод можно использовать для запроса сертификата клиента после установления защищённого соединения.
Примечание: При работе в качестве сервера сокет будет уничтожен с ошибкой после таймаута handshakeTimeout.
tlsSocket.setMaxSendFragment(size)
-
size<число> Максимальный размер фрагмента TLS. Максимальное значение равно16384. По умолчанию:16384.
Метод tlsSocket.setMaxSendFragment() устанавливает максимальный размер фрагмента TLS. Возвращает true, если ограничение установлено успешно; false в противном случае.
Меньшие размеры фрагментов уменьшают задержку буферизации на клиенте: большие фрагменты буферизуются слоем TLS до получения всего фрагмента и проверки его целостности; большие фрагменты могут занимать несколько раундов и их обработка может быть отложена из-за потери или переупорядочивания пакетов. Однако, меньшие фрагменты добавляют дополнительные байты фрейминга TLS и накладные расходы на процессор, что может снизить общую пропускную способность сервера.
tls.checkServerIdentity(host, cert)
-
host<строка> Имя хоста для проверки сертификата -
cert<Объект> Объект, представляющий сертификат клиента. Возвращаемый объект содержит некоторые свойства, соответствующие полям сертификата.
Проверяет, что сертификат cert выдан для хоста host.
Возвращает объект <Ошибка>, заполняя его причиной, хостом и сертификатом при ошибке. При успехе возвращает <неопределено>.
Примечание: Эту функцию можно переопределить, предоставив альтернативную функцию в рамках параметра options.checkServerIdentity, переданного в tls.connect(). Переопределяющая функция, конечно, может вызвать tls.checkServerIdentity() для дополнения проверок дополнительной проверкой.
Примечание: Эта функция вызывается только в том случае, если сертификат прошёл все другие проверки, например, выдан ли он доверенной CA (options.ca).
Объект cert содержит распарсенный сертификат и будет иметь структуру, аналогичную:
{ subject:
{ OU: [ 'Domain Control Validated', 'PositiveSSL Wildcard' ],
CN: '*.nodejs.org' },
issuer:
{ C: 'GB',
ST: 'Greater Manchester',
L: 'Salford',
O: 'COMODO CA Limited',
CN: 'COMODO RSA Domain Validation Secure Server CA' },
subjectaltname: 'DNS:*.nodejs.org, DNS:nodejs.org',
infoAccess:
{ 'CA Issuers - URI':
[ 'http://crt.comodoca.com/COMODORSADomainValidationSecureServerCA.crt' ],
'OCSP - URI': [ 'http://ocsp.comodoca.com' ] },
modulus: 'B56CE45CB740B09A13F64AC543B712FF9EE8E4C284B542A1708A27E82A8D151CA178153E12E6DDA15BF70FFD96CB8A88618641BDFCCA03527E665B70D779C8A349A6F88FD4EF6557180BD4C98192872BCFE3AF56E863C09DDD8BC1EC58DF9D94F914F0369102B2870BECFA1348A0838C9C49BD1C20124B442477572347047506B1FCD658A80D0C44BCC16BC5C5496CFE6E4A8428EF654CD3D8972BF6E5BFAD59C93006830B5EB1056BBB38B53D1464FA6E02BFDF2FF66CD949486F0775EC43034EC2602AEFBF1703AD221DAA2A88353C3B6A688EFE8387811F645CEED7B3FE46E1F8B9F59FAD028F349B9BC14211D5830994D055EEA3D547911E07A0ADDEB8A82B9188E58720D95CD478EEC9AF1F17BE8141BE80906F1A339445A7EB5B285F68039B0F294598A7D1C0005FC22B5271B0752F58CCDEF8C8FD856FB7AE21C80B8A2CE983AE94046E53EDE4CB89F42502D31B5360771C01C80155918637490550E3F555E2EE75CC8C636DDE3633CFEDD62E91BF0F7688273694EEEBA20C2FC9F14A2A435517BC1D7373922463409AB603295CEB0BB53787A334C9CA3CA8B30005C5A62FC0715083462E00719A8FA3ED0A9828C3871360A73F8B04A4FC1E71302844E9BB9940B77E745C9D91F226D71AFCAD4B113AAF68D92B24DDB4A2136B55A1CD1ADF39605B63CB639038ED0F4C987689866743A68769CC55847E4A06D6E2E3F1',
exponent: '0x10001',
valid_from: 'Aug 14 00:00:00 2017 GMT',
valid_to: 'Nov 20 23:59:59 2019 GMT',
fingerprint: '01:02:59:D9:C3:D2:0D:08:F7:82:4E:44:A4:B4:53:C5:E2:3A:87:4D',
ext_key_usage: [ '1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2' ],
serialNumber: '66593D57F20CBC573E433381B5FEC280',
raw: <Buffer ....> }
tls.connect(options[, callback])
-
options<Объект>-
host<строка> Хост, к которому должен подключиться клиент. По умолчанию:'localhost'. -
port<число> Порт, к которому должен подключиться клиент. -
path<строка> Создаёт сокет-соединение Unix по указанному пути. Если этот параметр указан,hostиportигнорируются. -
socket<stream.Duplex> Устанавливает защищённое соединение на заданном сокете вместо создания нового сокета. Обычно это экземплярnet.Socket, но допускается любойDuplexпоток. Если этот параметр указан,path,hostиportигнорируются, за исключением проверки сертификата. Обычно сокет уже подключён, когда передаётся вtls.connect(), но он может быть подключён позже. Обратите внимание, что подключение/отключение/разрушениеsocket— ответственность пользователя; вызовtls.connect()не вызоветnet.connect(). -
rejectUnauthorized<булево> Если неfalse, сертификат сервера проверяется по списку предоставленных удостоверяющих центров. Если проверка не пройдена, генерируется событие'error';err.codeсодержит код ошибки OpenSSL. По умолчанию:true. -
NPNProtocols<массив строк> | <массив буферов> | <массив Uint8Array> | <буфер> | <Uint8Array> Массив строк,BufferилиUint8Array, или одиночныйBufferилиUint8Array, содержащий поддерживаемые протоколы NPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт — длина следующего имени протокола. Передача массива обычно намного проще, например,['hello', 'world']. -
ALPNProtocols: <массив строк> | <массив буферов> | <массив Uint8Array> | <буфер> | <Uint8Array> Массив строк,BufferилиUint8Array, или одиночныйBufferилиUint8Array, содержащий поддерживаемые протоколы ALPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт — длина следующего имени протокола. Передача массива обычно намного проще, например,['hello', 'world']. -
servername: <строка> Имя сервера для расширения TLS SNI (Server Name Indication). -
checkServerIdentity(servername, cert)<Функция> Функция обратного вызова, используемая (вместо встроенной функцииtls.checkServerIdentity()) при проверке имени хоста сервера (или предоставленногоservername, если он явно задан) по отношению к сертификату. Должна возвращать <Ошибка>, если проверка не пройдена. Метод должен возвращатьundefined, еслиservernameиcertпроверены. -
session<Буфер> ЭкземплярBuffer, содержащий сессию TLS. -
minDHSize<число> Минимальный размер параметра DH в битах для принятия соединения TLS. Когда сервер предлагает параметр DH размером меньшеminDHSize, соединение TLS уничтожается, и генерируется ошибка. По умолчанию:1024. -
secureContext: Необязательный объект контекста TLS, созданный с помощьюtls.createSecureContext(). ЕслиsecureContextне предоставлен, он будет создан путём передачи всего объектаoptionsвtls.createSecureContext(). -
lookup: <Функция> Пользовательская функция поиска. По умолчанию:dns.lookup(). - ...: Необязательные параметры
tls.createSecureContext(), которые используются, если параметрsecureContextотсутствует, в противном случае они игнорируются.
-
-
callback<Функция>
Функция callback, если задана, будет добавлена в качестве обработчика события 'secureConnect'.
tls.connect() возвращает объект tls.TLSSocket.
Следующий пример демонстрирует простой сервер «эхо»:
const tls = require('tls');
const fs = require('fs');
const options = {
// Necessary only if using the client certificate authentication
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem'),
// Necessary only if the server uses the self-signed certificate
ca: [ fs.readFileSync('server-cert.pem') ]
};
const socket = tls.connect(8000, options, () => {
console.log('client connected',
socket.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(socket);
process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
console.log(data);
});
socket.on('end', () => {
server.close();
});
Или
const tls = require('tls');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('client.pfx')
};
const socket = tls.connect(8000, options, () => {
console.log('client connected',
socket.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(socket);
process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
console.log(data);
});
socket.on('end', () => {
server.close();
});
tls.connect(path[, options][, callback])
-
path<строка> Значение по умолчанию дляoptions.path. -
options<Объект> См.tls.connect(). -
callback<Функция> См.tls.connect().
Аналогично tls.connect(), но path может быть предоставлен в качестве аргумента вместо параметра.
Примечание: Параметр пути, если указан, имеет приоритет над аргументом пути.
tls.connect(port[, host][, options][, callback])
-
port<число> Значение по умолчанию дляoptions.port. -
host<строка> Необязательное значение по умолчанию дляoptions.host. -
options<Объект> См.tls.connect(). -
callback<Функция> См.tls.connect().
Аналогично tls.connect(), но port и host могут быть предоставлены в качестве аргументов вместо параметров.
Примечание: Параметр порта или хоста, если указан, имеет приоритет над любым аргументом порта или хоста.
tls.createSecureContext(options)
-
options<Объект>-
pfx<строка> | <массив строк> | <Буфер> | <массив буферов> | <массив объектов> Необязательный PFX или PKCS12 закодированный закрытый ключ и цепочка сертификатов.pfxявляется альтернативой предоставлениюkeyиcertпо отдельности. PFX обычно зашифрован, если это так, тоpassphraseбудет использоваться для его расшифровки. Несколько PFX могут быть предоставлены либо как массив незашифрованных буферов PFX, либо как массив объектов в формате{buf: <string|buffer>[, passphrase: <string>]}. Формат объекта может использоваться только в массиве.object.passphraseявляется необязательным. Зашифрованный PFX будет расшифрован с помощьюobject.passphrase, если он предоставлен, илиoptions.passphrase, если нет. -
key<строка> | <массив строк> | <Буфер> | <массив буферов> | <массив объектов> Необязательные закрытые ключи в формате PEM. PEM позволяет зашифровать закрытые ключи. Зашифрованные ключи будут расшифрованы с помощьюoptions.passphrase. Несколько ключей с использованием различных алгоритмов могут быть предоставлены либо как массив незашифрованных строк или буферов ключей, либо как массив объектов в формате{pem: <string|buffer>[, passphrase: <string>]}. Формат объекта может использоваться только в массиве.object.passphraseявляется необязательным. Зашифрованные ключи будут расшифрованы с помощьюobject.passphrase, если он предоставлен, илиoptions.passphrase, если нет. -
passphrase<строка> Необязательный общий пароль, используемый для одного закрытого ключа и/или PFX. -
cert<строка> | <массив строк> | <Буфер> | <массив буферов> Необязательные цепочки сертификатов в формате PEM. Одна цепочка сертификатов должна быть предоставлена на каждый закрытый ключ. Каждая цепочка сертификатов должна содержать сертификат в формате PEM для предоставленного закрытогоkey, а затем промежуточные сертификаты (если таковые имеются) в формате PEM, по порядку, и без корневого CA (корневой CA должен быть известен партнеру, см.ca). При предоставлении нескольких цепочек сертификатов порядок не обязательно должен совпадать с порядком закрытых ключей вkey. Если промежуточные сертификаты не предоставлены, партнер не сможет проверить сертификат, и рукопожатие завершится неудачей. -
ca<строка> | <массив строк> | <Буфер> | <массив буферов> Необязательно переопределить доверенные сертификаты CA. По умолчанию доверяются известные CA, отобранные Mozilla. CA Mozilla полностью заменяются при явном указании CA с помощью этого параметра. Значение может быть строкой или буфером, или массивом строк и/или буферов. Любая строка или буфер может содержать несколько CA PEM, соединённых вместе. Сертификат партнёра должен быть связан с CA, которому доверяет сервер, для проверки подлинности соединения. При использовании сертификатов, не связанных с известной CA, CA сертификата партнера должна быть явным образом указана как доверенная, в противном случае соединение не будет проверено подлинности. Если партнер использует сертификат, который не соответствует или не связан с одним из стандартных CA, используйте параметрcaдля предоставления сертификата CA, к которому может соответствовать или быть связан сертификат партнера. Для самоподписанных сертификатов сертификат является собственной CA и должен быть предоставлен. -
crl<строка> | <массив строк> | <Буфер> | <массив буферов> Необязательные CRL (списки отзыва сертификатов) в формате PEM. -
ciphers<строка> Необязательное указание набора шифрования, заменяющее значение по умолчанию. Более подробная информация доступна в разделе изменение набора шифрования по умолчанию. -
honorCipherOrder<логическое значение> Попытка использовать предпочтения набора шифрования сервера вместо предпочтений клиента. При значенииtrue, приводит к установкеSSL_OP_CIPHER_SERVER_PREFERENCEвsecureOptions, см. Параметры OpenSSL для получения дополнительной информации. -
ecdhCurve<строка> Строка, описывающая заданную кривую или список кривых, разделённых двоеточием, NID или имена кривых, например,P-521:P-384:P-256, для использования в соглашении о ключах ECDH, илиfalseдля отключения ECDH. Установите значениеautoдля автоматического выбора кривой. Используйтеcrypto.getCurves()для получения списка доступных имен кривых. В последних версиях,openssl ecparam -list_curvesтакже будет отображать имя и описание каждой доступной эллиптической кривой. Значение по умолчанию:tls.DEFAULT_ECDH_CURVE. -
dhparam<строка> | <Буфер> Параметры Diffie Hellman, необходимые для Совершенной секретности вперёд. Используйтеopenssl dhparamдля создания параметров. Длина ключа должна быть не меньше 1024 бит, в противном случае будет выброшено исключение. Настоятельно рекомендуется использовать 2048 бит или больше для повышения безопасности. Если параметр опущен или недействителен, параметры будут молча проигнорированы, и шифры DHE не будут доступны. -
secureProtocol<строка> Необязательный метод SSL для использования, по умолчанию'SSLv23_method'. Возможные значения перечислены как SSL_METHODS, используйте имена функций как строки. Например,'SSLv3_method'для принудительного использования версии SSL 3. -
secureOptions<число> Необязательно повлиять на поведение протокола OpenSSL, что обычно не требуется. Следует использовать с осторожностью! Значение является числовой битовой маскойSSL_OP_*параметров из Параметров OpenSSL. -
sessionIdContext<строка> Необязательный непрозрачный идентификатор, используемый серверами для обеспечения того, чтобы состояние сеанса не разделялось между приложениями. Не используется клиентами.
-
Примечание:
-
tls.createServer()устанавливает значение по умолчанию для параметраhonorCipherOrderвtrue, другие API, создающие безопасные контексты, его не устанавливают. -
tls.createServer()использует значение 128-битного усечённого значения хеша SHA1, сгенерированного изprocess.argv, как значение по умолчанию для параметраsessionIdContext, другие API, создающие безопасные контексты, не имеют значения по умолчанию.
Метод tls.createSecureContext() создаёт объект аутентификации.
Ключ необходим для шифров, использующих сертификаты. Для его предоставления можно использовать key или pfx.
Если параметр 'ca' не задан, Node.js будет использовать список общедоступных доверенных CA, указанный в https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt.
tls.createServer([options][, secureConnectionListener])
-
options<Объект>-
handshakeTimeout<число> Прервать соединение, если рукопожатие SSL/TLS не завершится в указанное количество миллисекунд. Событие'tlsClientError'генерируется объектомtls.Serverпри истечении времени ожидания рукопожатия. По умолчанию:120000(120 секунд). -
requestCert<логическое> Еслиtrue, сервер запросит сертификат от подключенных клиентов и попытается проверить этот сертификат. По умолчанию:false. -
rejectUnauthorized<логическое> Если неfalse, сервер отклонит любое подключение, не авторизованное предоставленным списком доверенных центров сертификации. Этот параметр действует только в том случае, еслиrequestCertравноtrue. По умолчанию:true. -
NPNProtocols<строковый массив> | <Буферный массив> | <Uint8 массив> | <Буфер> | <Uint8 массив> Массив строк,BufferилиUint8Array, или одиночныйBufferилиUint8Array, содержащий поддерживаемые протоколы NPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт – длина следующего имени протокола. Передача массива обычно проще, например,['hello', 'world']. (Протоколы должны быть упорядочены по приоритету). -
ALPNProtocols: <строковый массив> | <Буферный массив> | <Uint8 массив> | <Буфер> | <Uint8 массив> Массив строк,BufferилиUint8Array, или одиночныйBufferилиUint8Array, содержащий поддерживаемые протоколы ALPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт – длина следующего имени протокола. Передача массива обычно проще, например,['hello', 'world']. (Протоколы должны быть упорядочены по приоритету). Если сервер получает от клиента и NPN, и ALPN расширения, ALPN имеет приоритет над NPN, и сервер не отправляет клиенту NPN расширение. -
SNICallback(servername, cb)<Функция> Функция, которая будет вызвана, если клиент поддерживает расширение SNI TLS. При вызове будут переданы два аргумента:servernameиcb.SNICallbackдолжна вызватьcb(null, ctx), гдеctx— экземпляр SecureContext. (tls.createSecureContext(...)может быть использован для получения правильного SecureContext.) ЕслиSNICallbackне предоставлен, будет использована стандартная функция обратного вызова высокого уровня (см. ниже). -
sessionTimeout<число> Целое число, определяющее количество секунд, по истечении которых идентификаторы сеанса TLS и билеты сеанса TLS, созданные сервером, истекут. Для получения более подробной информации см. SSL_CTX_set_timeout. -
ticketKeys: ЭкземплярBufferдлиной 48 байт, состоящий из 16-байтового префикса, 16-байтового ключа HMAC и 16-байтового ключа AES. Это можно использовать для приема билетов сеанса TLS на нескольких экземплярах TLS-сервера. - ...: Любые
tls.createSecureContext()параметры могут быть предоставлены. Для серверов обычно требуются параметры идентификации (pfxилиkey/cert).
-
-
secureConnectionListener<Функция>
Создаёт новый tls.Server. Если предоставлен secureConnectionListener, он автоматически устанавливается как обработчик события 'secureConnection'.
Примечание: Параметры ticketKeys автоматически разделяются между рабочими процессами модуля cluster.
Ниже приведён пример простого сервера эха:
const tls = require('tls');
const fs = require('fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
// This is necessary only if using the client certificate authentication.
requestCert: true,
// This is necessary only if the client uses the self-signed certificate.
ca: [ fs.readFileSync('client-cert.pem') ]
};
const server = tls.createServer(options, (socket) => {
console.log('server connected',
socket.authorized ? 'authorized' : 'unauthorized');
socket.write('welcome!\n');
socket.setEncoding('utf8');
socket.pipe(socket);
});
server.listen(8000, () => {
console.log('server bound');
});
Или
const tls = require('tls');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('server.pfx'),
// This is necessary only if using the client certificate authentication.
requestCert: true,
};
const server = tls.createServer(options, (socket) => {
console.log('server connected',
socket.authorized ? 'authorized' : 'unauthorized');
socket.write('welcome!\n');
socket.setEncoding('utf8');
socket.pipe(socket);
});
server.listen(8000, () => {
console.log('server bound');
});
Этот сервер можно протестировать, подключившись к нему с помощью openssl s_client:
openssl s_client -connect 127.0.0.1:8000
tls.getCiphers()
Возвращает массив с именами поддерживаемых шифров SSL.
Например:
console.log(tls.getCiphers()); // ['AES128-SHA', 'AES256-SHA', ...]
tls.DEFAULT_ECDH_CURVE
Имя кривой по умолчанию для использования в соглашении об обмене ключами ECDH на TLS-сервере. Значение по умолчанию — 'prime256v1' (NIST P-256). Для получения дополнительной информации см. RFC 4492 и FIPS.186-4.
Устаревшие API
Класс: CryptoStream
tls.TLSSocket вместо этого.Класс tls.CryptoStream представляет собой поток зашифрованных данных. Этот класс устарел и больше не должен использоваться.
cryptoStream.bytesWritten
Свойство cryptoStream.bytesWritten возвращает общее количество байтов, записанных в сокет, включая байты, необходимые для реализации протокола TLS.
Класс: SecurePair
tls.TLSSocket вместо этого.Возвращается методом tls.createSecurePair().
Событие: 'secure'
Событие 'secure' генерируется объектом SecurePair после установления защищённого соединения.
Как и при проверке события сервера secureConnection, необходимо проверить pair.cleartext.authorized, чтобы подтвердить, что используемый сертификат должным образом авторизован.
tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized][, options])
tls.TLSSocket вместо этого.-
context<Объект> Объект защищённого контекста, возвращаемыйtls.createSecureContext() -
isServer<boolean>true, чтобы указать, что это подключение TLS должно открываться как серверное. -
requestCert<boolean>true, чтобы указать, должен ли сервер запросить сертификат от подключаемого клиента. Применяется только когдаisServerравноtrue. -
rejectUnauthorized<boolean> Если неfalse, сервер автоматически отклоняет клиентов с невалидными сертификатами. Применяется только когдаisServerравноtrue. -
options-
secureContext: Необязательный объект контекста TLS изtls.createSecureContext() -
isServer: Еслиtrue, сокет TLS будет создан в режиме сервера. По умолчанию:false. -
server<net.Сервер> Необязательный экземплярnet.Server -
requestCert: Необязательно, см.tls.createServer() -
rejectUnauthorized: Необязательно, см.tls.createServer() -
NPNProtocols: Необязательно, см.tls.createServer() -
ALPNProtocols: Необязательно, см.tls.createServer() -
SNICallback: Необязательно, см.tls.createServer() -
session<Буфер> Необязательный экземплярBuffer, содержащий сеанс TLS. -
requestOCSP<boolean> Еслиtrue, указывает, что расширение запроса статуса OCSP будет добавлено к приветствию клиента, и событие'OCSPResponse'будет излучено в сокете перед установлением защищённого соединения
-
Создаёт новый объект безопасной пары с двумя потоками, один из которых читает и записывает зашифрованные данные, а другой — читает и записывает данные в открытом виде. Обычно зашифрованный поток направляется в/из входящий зашифрованный поток данных, а поток в открытом виде используется в качестве замены для исходного зашифрованного потока.
tls.createSecurePair() возвращает объект tls.SecurePair с свойствами потоков cleartext и encrypted.
Примечание: cleartext имеет тот же API, что и tls.TLSSocket.
Примечание: Метод tls.createSecurePair() теперь устарел и заменён на tls.TLSSocket(). Например, код:
pair = tls.createSecurePair(/* ... */); pair.encrypted.pipe(socket); socket.pipe(pair.encrypted);
может быть заменён на:
secure_socket = tls.TLSSocket(socket, options);
где secure_socket имеет тот же API, что и pair.cleartext.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v8.x/docs/api/tls.html