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
Совершенная прямая секретность
Термин "Прямая секретность" или "Совершенная прямая секретность" описывает особенность методов согласования ключей (т.е. обмена ключами). То есть, ключи сервера и клиента используются для согласования новых временных ключей, которые применяются только для текущей сессии связи. Практически это означает, что даже если приватный ключ сервера скомпрометирован, связь могут расшифровать злоумышленники только в том случае, если злоумышленник получает пару ключей, сгенерированных специально для этой сессии.
Совершенная прямая секретность достигается случайной генерацией пары ключей для согласования ключей на каждом 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.
Событие: 'tlsClientError'
Событие 'tlsClientError' излучается, когда возникает ошибка до установления защищённого соединения. Обработчик событий получает два аргумента:
-
exception<Ошибка> ОбъектErrorописывающий ошибку -
tlsSocket<tls.TLSSocket> Экземплярtls.TLSSocketиз которого произошла ошибка.
Событие: '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. 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, указывающее, был ли клиент проверен одним из предоставленных сертифицирующих центров (Certificate Authorities) сервера. Если tlsSocket.authorized равно false, то socket.authorizationError задано, описывая, как произошел отказ авторизации. Обратите внимание, что в зависимости от настроек TLS-сервера неавторизованные соединения могут быть все еще приняты.
Свойства tlsSocket.npnProtocol и tlsSocket.alpnProtocol — это строки, содержащие выбранные протоколы NPN и ALPN соответственно. При получении расширений NPN и ALPN, ALPN имеет приоритет над NPN, и следующий протокол выбирается по ALPN.
Когда у ALPN нет выбранного протокола, tlsSocket.alpnProtocol возвращает false.
Свойство tlsSocket.servername — это строка, содержащая имя сервера, запрошенное через SNI.
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.getTicketKeys()
Возвращает экземпляр Buffer, содержащий ключи, которые в настоящее время используются для шифрования/расшифровки TLS-сессионных билетов.
server.listen(port[, hostname][, callback])
-
port<число> Порт TCP/IP, на котором необходимо начать прослушивание подключений. Значение0(ноль) назначит случайный порт. -
hostname<строка> Имя хоста, IPv4 или IPv6 адрес, на котором необходимо начать прослушивание подключений. Еслиundefined, сервер будет принимать подключения на любой IPv6 адрес (::) при наличии IPv6 или любой IPv4 адрес (0.0.0.0) в противном случае. -
callback<Функция> Функция обратного вызова, которая будет вызвана, когда сервер начнёт прослушиватьportиhostname.
Метод server.listen() сообщает серверу начать приём подключений на указанный port и hostname.
Эта функция работает асинхронно. Если callback задан, он будет вызван, когда сервер начнёт прослушивать.
Для получения дополнительной информации см. 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 будет добавлено в приветствие клиента, и событие'OCSPResponse'будет отправлено на сокет до установления защищённого канала связи. -
secureContext: Дополнительный объект контекста TLS, созданный с помощьюtls.createSecureContext(). ЕслиsecureContextне предоставлен, он будет создан путём передачи всего объектаoptionsвtls.createSecureContext(). Примечание: фактически, все опцииtls.createSecureContext()могут быть предоставлены, но они будут полностью проигнорированы, если опцияsecureContextотсутствует. - ...: Дополнительные опции
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.authorized
Возвращает true если сертификат узла был подписан одной из CA, указанных при создании экземпляра tls.TLSSocket, в противном случае false.
tlsSocket.authorizationError
Возвращает причину, по которой сертификат узла не был проверен. Это свойство устанавливается только при tlsSocket.authorized === false.
tlsSocket.encrypted
Всегда возвращает true. Это может использоваться для различения сокетов TLS от обычных экземпляров net.Socket.
tlsSocket.getCipher()
Возвращает объект, представляющий имя шифра и версию протокола SSL/TLS, впервые определившую этот шифр.
Например: { name: 'AES256-SHA', version: 'TLSv1/SSLv3' }
См. SSL_CIPHER_get_name() и SSL_CIPHER_get_version() в https://www.openssl.org/docs/man1.0.2/ssl/SSL_CIPHER_get_name.html для получения дополнительной информации.
tlsSocket.getEphemeralKeyInfo()
Возвращает объект, представляющий тип, имя и размер параметра обмена эфемерным ключом в Совершенной Дискретности Вперёд при подключении клиента. Возвращает пустой объект, если обмен ключами не эфемерный. Так как это поддерживается только на клиенте, то null возвращается, если вызвана на сокете сервера. Поддерживаемые типы — 'DH' и 'ECDH'. Свойство name доступно только при type равном 'ECDH'.
Например: { type: 'ECDH', name: 'prime256v1', size: 256 }
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.getProtocol()
Возвращает строку, содержащую переговорённую версию протокола SSL/TLS текущего соединения. Значение 'unknown' будет возвращено для подключенных сокетов, которые не завершили процесс рукопожатия. Значение null будет возвращено для сокетов сервера или отключенных сокетов клиента.
Примеры ответов включают:
SSLv3TLSv1TLSv1.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<Object>-
rejectUnauthorized<boolean> requestCert
-
-
callback<Function> Функция, которая будет вызвана по завершении запроса на переподключение.
Метод tlsSocket.renegotiate() инициирует процесс повторного согласования TLS. По завершении функция callback получит один аргумент, который будет либо Error (если запрос не удался), либо null.
Примечание: Этот метод можно использовать для запроса сертификата узла после установления защищённого соединения.
Примечание: При запуске в качестве сервера сокет будет уничтожен с ошибкой после истечения срока ожидания handshakeTimeout.
tlsSocket.setMaxSendFragment(size)
-
size<число> Максимальный размер фрагмента TLS. По умолчанию16384. Максимальное значение16384.
Метод tlsSocket.setMaxSendFragment() устанавливает максимальный размер фрагмента TLS. Возвращает true если ограничение установлено успешно; false в противном случае.
Меньшие размеры фрагментов уменьшают задержку буферизации на клиенте: более крупные фрагменты буферизуются слоем TLS до тех пор, пока весь фрагмент не будет получен и не будет проверена его целостность; большие фрагменты могут охватывать несколько запросов, и их обработка может быть задерживается из-за потери или переупорядочения пакетов. Однако, меньшие фрагменты добавляют дополнительные байты фрейминга TLS и накладные расходы ЦП, что может снизить общую пропускную способность сервера.
tls.connect(port[, host][, options][, callback])
-
port<число> Значение по умолчанию дляoptions.port. -
host<строка> Необязательное значение по умолчанию дляoptions.host. -
options<Объект> См.tls.connect(). -
callback<Функция> См.tls.connect().
Аналогично tls.connect(), за исключением того, что port и host могут быть переданы как аргументы вместо options.
Примечание: Если указан параметр порта или хоста, он будет иметь приоритет над соответствующим аргументом.
tls.connect(path[, options][, callback])
-
path<строка> Значение по умолчанию дляoptions.path. -
options<Объект> См.tls.connect(). -
callback<Функция> См.tls.connect().
Аналогично tls.connect(), за исключением того, что path может быть предоставлен как аргумент вместо опции.
Примечание: Если указан параметр пути, он будет иметь приоритет над аргументом пути.
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<логическое> Еслиtrue, сертификат сервера проверяется по списку предоставленных центров сертификации. Если проверка завершится неудачей, выводится событие'error';err.codeсодержит код ошибки OpenSSL. По умолчаниюtrue. -
NPNProtocols<строковый массив> | <Буферный массив> Массив строк илиBufferсодержащий поддерживаемые протоколы NPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт — длина следующего имени протокола. Передача массива обычно намного проще, например,['hello', 'world']. -
ALPNProtocols: <строковый массив> | <Буферный массив> Массив строк илиBufferсодержащий поддерживаемые протоколы ALPN.Bufferдолжны иметь формат[len][name][len][name]..., например,0x05hello0x05world, где первый байт — длина следующего имени протокола. Передача массива обычно намного проще:['hello', 'world']. -
servername: <строка> Имя сервера для расширения TLS SNI (Server Name Indication). -
checkServerIdentity(servername, cert)<Функция> Функция обратного вызова, которая используется (вместо встроенной функцииtls.checkServerIdentity()при проверке имени хоста сервера по сертификату. Она должна возвращать <Ошибка>, если проверка завершится неудачей. Метод должен возвращатьundefinedеслиservernameиcertпроверены. -
session<Буфер> ЭкземплярBuffer, содержащий сеанс TLS. -
minDHSize<число> Минимальный размер параметра DH в битах для принятия соединения TLS. Когда сервер предлагает параметр DH с размером меньшеminDHSize, соединение TLS уничтожается, и выбрасывается ошибка. По умолчанию1024. -
secureContext: Необязательный объект контекста TLS, созданный с помощьюtls.createSecureContext(). ЕслиsecureContextне предоставлен, он будет создан путём передачи всего объектаoptionsвtls.createSecureContext(). Примечание: По сути, все опцииtls.createSecureContext()могут быть предоставлены, но они будут полностью проигнорированы, если опцияsecureContextотсутствует. -
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.createSecureContext(options)
-
options<Object>-
pfx<строка> | <Буфер> Необязательный PFX или PKCS12 закодированный закрытый ключ и цепочка сертификатов.pfxявляется альтернативой предоставлениюkeyиcertпо отдельности. PFX обычно зашифрован, если это так, то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 явно указаны с помощью этого параметра. Значение может быть строкой или буфером, или массивом строк и/или буферов. Любая строка или буфер может содержать несколько PEM CA, объединённых вместе. Сертификат партнёра должен быть связан с CA, которому доверяет сервер, для аутентификации соединения. При использовании сертификатов, которые не могут быть связаны с известным CA, CA сертификата партнёра необходимо явно указать как доверенный, иначе соединение не будет аутентифицировано. Если партнёр использует сертификат, который не соответствует или не связан с одним из стандартных CA, используйте опциюcaдля предоставления сертификата CA, к которому может соответствовать или быть связан сертификат партнёра. Для самоподписанных сертификатов сертификат является собственным CA и должен быть предоставлен. -
crl<строка> | <массив строк> | <Буфер> | <массив буферов> Необязательные PEM-форматированные CRL (списки отзыва сертификатов). -
ciphers<строка> Необязательная спецификация набора шифров, заменяющая значение по умолчанию. Более подробная информация по изменению набора шифров по умолчанию. -
honorCipherOrder<логическое значение> Попытка использовать предпочтения сервера по набору шифров вместо предпочтений клиента. Приtrue, устанавливаетSSL_OP_CIPHER_SERVER_PREFERENCEвsecureOptions, см. Опции OpenSSL для получения дополнительной информации. Примечание:tls.createServer()устанавливает значение по умолчанию вtrue, другие API, создающие защищённые контексты, его не устанавливают. -
ecdhCurve<строка> Строка, описывающая именованную кривую для использования в согласовании ключей ECDH илиfalseдля отключения ECDH. По умолчаниюtls.DEFAULT_ECDH_CURVE. Используйтеcrypto.getCurves()для получения списка доступных имён кривых. В последних версияхopenssl ecparam -list_curvesтакже отображает имя и описание каждой доступной эллиптической кривой. -
dhparam<строка> | <Буфер> Параметры Диффи-Хеллмана, необходимые для совершенной прямой секретности. Используйтеopenssl dhparamдля создания параметров. Длина ключа должна быть не менее 1024 бит, в противном случае будет выброшено исключение. Для большей безопасности настоятельно рекомендуется использовать 2048 бит или больше. Если параметр опущен или некорректен, параметры будут молча игнорироваться, и шифры DHE не будут доступны. -
secureProtocol<строка> Необязательный метод SSL для использования, по умолчанию'SSLv23_method'. Возможные значения перечислены как SSL_METHODS, используйте имена функций в качестве строк. Например,'SSLv3_method'для принудительного использования версии SSL 3. -
secureOptions<число> Необязательно влияет на поведение протокола OpenSSL, что обычно не требуется. Это следует использовать с осторожностью! Значение — это числовая битовая маскаSSL_OP_*опций из Опций OpenSSL. -
sessionIdContext<строка> Необязательный неявный идентификатор, используемый серверами для обеспечения того, чтобы состояние сеанса не разделялось между приложениями. Не используется клиентами. Примечание:tls.createServer()использует значение хэша SHA1 длиной 128 бит, сгенерированное изprocess.argv, другие API, создающие защищённые контексты, не имеют значения по умолчанию.
-
Метод tls.createSecureContext() создаёт объект данных.
Ключ обязателен для шифров, использующих сертификаты. Можно использовать key или pfx для его предоставления.
Если опция 'ca' не указана, Node.js будет использовать стандартный публичный список доверенных CA, как указано в http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.
tls.createServer([options][, secureConnectionListener])
-
options<Объект>-
handshakeTimeout<число> Прервать соединение, если рукопожатие SSL/TLS не завершится в течение указанного количества миллисекунд. По умолчанию120секунды. Событие'tlsClientError'генерируется объектомtls.Serverпри истечении времени ожидания рукопожатия. -
requestCert<логическое> Еслиtrue, сервер запросит сертификат у подключившихся клиентов и попытается проверить этот сертификат. По умолчаниюfalse. -
rejectUnauthorized<логическое> Еслиtrue, сервер отклонит любое подключение, которое не авторизовано предоставленным списком центров сертификации. Этот параметр действует только еслиrequestCertравенtrue. По умолчаниюfalse. -
NPNProtocols<строковый массив> | <Буфер> Массив строк илиBuffer, определяющий возможные протоколы NPN. (Протоколы должны быть упорядочены по приоритету.) -
ALPNProtocols<строковый массив> | <Буфер> Массив строк илиBuffer, определяющий возможные протоколы ALPN. (Протоколы должны быть упорядочены по приоритету.) Если сервер получает как расширения NPN, так и ALPN от клиента, ALPN имеет приоритет над NPN, и сервер не отправляет клиенту расширение NPN. -
SNICallback(servername, cb)<Функция> Функция, которая будет вызвана, если клиент поддерживает расширение SNI TLS. При вызове будут переданы два аргумента:servernameиcb. ФункцияSNICallbackдолжна вызватьcb(null, ctx), гдеctx— экземпляр SecureContext. (tls.createSecureContext(...)может быть использован для получения соответствующего SecureContext.) ЕслиSNICallbackне был предоставлен, будет использоваться стандартный обработчик обратного вызова с API высокого уровня (см. ниже). -
sessionTimeout<число> Целое число, определяющее количество секунд, через которое идентификаторы сеанса TLS и билеты сеанса TLS, созданные сервером, истекут. Подробности см. в SSL_CTX_set_timeout. -
ticketKeys: ЭкземплярBufferобъёмом 48 байт, состоящий из 16-байтного префикса, 16-байтного ключа HMAC и 16-байтного ключа AES. Его можно использовать для приема билетов сеанса TLS на нескольких экземплярах сервера TLS. Примечание: этот параметр автоматически обменивается между рабочими процессами модуляcluster. - ...: Любые параметры
tls.createSecureContext()могут быть предоставлены. Для серверов обычно требуются параметры идентификации (pfxилиkey/cert).
-
-
secureConnectionListener<Функция>
Создаёт новый сервер tls.Server. Параметр secureConnectionListener, если он предоставлен, автоматически устанавливается в качестве обработчика события 'secureConnection'.
Ниже приведён пример простого сервера эха:
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<логическое>trueдля указания того, что соединение TLS должно быть открыто как серверное. -
requestCert<логическое>trueдля указания того, должен ли сервер запрашивать сертификат у подключающегося клиента. Применимо только когдаisServerравноtrue. -
rejectUnauthorized<логическое>trueдля указания того, должен ли сервер автоматически отклонять клиентов с недействительными сертификатами. Применимо только когда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<логическое> Если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-v6.x/docs/api/tls.html