Node.js TLS/SSL

2022-02-26 10:32 更新
Stability: 3 - Stable

Node.js可以使用require('tls')來訪問TLS/SSL模塊:

const tls = require('tls');

tls模塊使用OpenSSL來提供傳輸層安全性(Transport Layer Security,TLS)和安全套接層(Secure Socket Layer,SSL):加密過的流通訊。

TLS/SSL是一種公鑰/私鑰基礎(chǔ)架構(gòu),每個客戶端和服務(wù)端都需要一個私鑰。私鑰的創(chuàng)建方法如下:

openssl genrsa -out ryans-key.pem 2048

你還需要為所有服務(wù)器和某些客戶端添加證書。證書由認證中心(Certificate Authority)簽名,或者自簽名。獲得證書第一步是創(chuàng)建一個證書簽名請求"Certificate Signing Request" (CSR)文件。證書的創(chuàng)建方法如下:

openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem

使用CSR創(chuàng)建一個自簽名的證書:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

或者你可以發(fā)送CSR給認證中心(Certificate Authority)來簽名。

(TODO: 創(chuàng)建CA的文檔,感興趣的讀者可以在Node源碼test/fixtures/keys/Makefile里查看)

創(chuàng)建.pfx或.p12,可以這么做:

openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
    -certfile ca-cert.pem -out agent5.pfx
  • in: 簽名證書
  • inkey: 關(guān)聯(lián)的私鑰
  • certfile: 是將所有證書頒發(fā)機構(gòu) (CA) 證書連接到單個文件中,例如,cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

協(xié)議支持

Node.js默認遵循SSLv2和SSLv3協(xié)議,不過這些協(xié)議被禁用。因為他們不太可靠,很容易受到威脅,參見CVE-2014-3566。某些情況下,舊版本客戶端/服務(wù)器(比如 IE6)可能會產(chǎn)生問題。如果你想啟用SSLv2或SSLv3 ,使用參數(shù)--enable-ssl2--enable-ssl3運行Node。Node.js的未來版本中不會再默認編譯SSLv2 和SSLv3。

有一個辦法可以強制node進入僅使用SSLv3或SSLv2模式,分別指定secureProtocol'SSLv3_method''SSLv2_method'。

Node.js使用的默認協(xié)議方法準(zhǔn)確名字是AutoNegotiate_method, 這個方法會嘗試并協(xié)商客戶端支持的從高到底協(xié)議。為了提供默認的安全級別,Node.js(v0.10.33 版本之后)通過將secureOptions設(shè)為SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2 ,明確的禁用了SSLv3和SSLv2(除非你給secureProtocol 傳值--enable-ssl3,或--enable-ssl2,或SSLv3_method)。

如果你設(shè)置了secureOptions,我們不會重新這個參數(shù)。

改變這個行為的后果:

  • 如果你的應(yīng)用被當(dāng)做為安全服務(wù)器,SSLv3客戶端不能協(xié)商建立連接,會被拒絕。這種情況下,你的服務(wù)器會觸發(fā)clientError事件。錯誤消息會包含錯誤版本數(shù)字('wrong version number')。
  • 如果你的應(yīng)用被當(dāng)做安全客戶端,和一個不支持比SSLv3更高安全性的方法的服務(wù)器通訊,你的連接不會協(xié)商成功。這種情況下,你的客戶端會觸發(fā) clientError事件。錯誤消息會包含錯誤版本數(shù)字('wrong version number')。

Client-initiated renegotiation attack mitigation

TLS協(xié)議讓客戶端協(xié)商TLS會話的某些方法內(nèi)容。但是,會話協(xié)商需要服務(wù)器端響應(yīng)的資源,這回讓它成為阻斷服務(wù)攻擊(denial-of-service attacks)的潛在媒介。

為了降低這種情況的發(fā)生,重新協(xié)商被限制為每10分鐘3次。當(dāng)超出這個界限時,在tls.TLSSocket實例上會觸發(fā)錯誤。這個限制可設(shè)置:

  • tls.CLIENT_RENEG_LIMIT: 重新協(xié)商limit,默認是3。

  • tls.CLIENT_RENEG_WINDOW: 重新協(xié)商窗口的時間,單位秒,默認是10分鐘。

除非你明確知道自己在干什么,否則不要改變默認值。

要測試你的服務(wù)器的話,使用openssl s_client -connect address:port連接服務(wù)器,并敲R<CR>(字母 R 鍵加回車)幾次。

NPN 和 SNI

NPN(Next Protocol Negotiation 下次協(xié)議協(xié)商)和SNI (Server Name Indication 域名指示)都是TLS握手?jǐn)U展:

  • NPN - 同一個TLS服務(wù)器使用多種協(xié)議 (HTTP, SPDY)
  • SNI - 同一個TLS服務(wù)器使用多個主機名(不同的 SSL 證書)。certificates.

完全正向保密

"Forward Secrecy"或"Perfect Forward Secrecy-完全正向保密"協(xié)議描述了秘鑰協(xié)商(比如秘鑰交換)方法的特點。實際上這意味著及時你的服務(wù)器的秘鑰有危險,通訊僅有可能被一類人竊聽,他們必須設(shè)法獲的每次會話都會生成的秘鑰對。

完全正向保密是通過每次握手時為秘鑰協(xié)商隨機生成密鑰對來完成(和所有會話一個key相反)。實現(xiàn)這個技術(shù)(提供完全正向保密-Perfect Forward Secrecy)的方法被稱為"ephemeral"。

通常目前有2個方法用于完成完全正向保密(Perfect Forward Secrecy):

  • DHE - 一個迪菲-赫爾曼密鑰交換密鑰協(xié)議(Diffie Hellman key-agreement protocol)短暫(ephemeral)版本。
  • ECDHE - 一個橢圓曲線密鑰交換密鑰協(xié)議( Elliptic Curve Diffie Hellman key-agreement protocol)短暫(ephemeral)版本。

短暫(ephemeral)方法有性能缺點,因為生成 key 非常耗費資源。

tls.getCiphers()

返回支持的SSL密碼名數(shù)組。

例子:

var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]

tls.createServer(options[, secureConnectionListener])

創(chuàng)建一個新的tls.Server。參數(shù)connectionListener會自動設(shè)置為secureConnection事件的監(jiān)聽器。參數(shù)options對象有以下可能性:

  • pfx: 包含私鑰,證書和服務(wù)器的CA證書(PFX或PKCS12 格式)字符串或緩存Buffer。(keycertca互斥)。

  • key: 包含服務(wù)器私鑰(PEM格式)字符串或緩存Buffer。(可以是keys的數(shù)組)(必傳)。

  • passphrase: 私鑰或pfx的密碼字符串

  • cert: 包含服務(wù)器證書key(PEM格式)字符串或緩存Buffer。(可以是certs的數(shù)組)(必傳)。

  • ca: 信任的證書(PEM格式)的字符串/緩存數(shù)組。如果忽略這個參數(shù),將會使用"root" CAs ,比如VeriSign。用來授權(quán)連接。

  • crl : 不是PEM編碼CRLs (證書撤銷列表 Certificate Revocation List)的字符串就是字符串列表.

  • ciphers: 要使用或排除的密碼(cipher)字符串

    為了減輕BEAST attacks ,推薦使用這個參數(shù)和之后會提到的honorCipherOrder參數(shù)來優(yōu)化non-CBC密碼(cipher)

    默認:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL。格式上更多細節(jié)參見OpenSSL cipher list format documentation

    ECDHE-RSA-AES128-SHA256, DHE-RSA-AES128-SHA256AES128-GCM-SHA256都是TLS v1.2密碼(cipher),當(dāng)node.js連接OpenSSL 1.0.1或更早版本(比如)時使用。注意,honorCipherOrder設(shè)置為enabled后,現(xiàn)在仍然可以和TLS v1.2客戶端協(xié)商弱密碼(cipher),

    RC4可作為客戶端和老版本TLS協(xié)議通訊的備用方法。RC4這些年受到懷疑,任何對信任敏感的對象都會考慮其威脅性。國家級別(state-level)的參與者擁有中斷它的能力。

    注意: 早些版本的修訂建議,AES256-SHA作為可以接受的密碼(cipher).Unfortunately,AES256-SHA是一個CBC密碼(cipher),容易受到BEAST attacks 攻擊,不要使用它。

  • ecdhCurve: 包含用來ECDH秘鑰交換弧形(curve)名字符串,或者false禁用ECDH。

    默認prime256v1。更多細節(jié)參考RFC 4492 。

  • dhparam: DH參數(shù)文件,用于DHE秘鑰協(xié)商。使用openssl dhparam命令來創(chuàng)建。如果加載文件失敗,會悄悄的拋棄它。

  • handshakeTimeout: 如果SSL/TLS握手事件超過這個參數(shù),會放棄里連接。默認是120秒.

    握手超時后,tls.Server對象會觸發(fā)'clientError'事件。

  • honorCipherOrder: 當(dāng)選擇一個密碼(cipher)時,使用服務(wù)器配置,而不是客戶端的。

    雖然這個參數(shù)默認不可用,還是推薦你用這個參數(shù),和ciphers參數(shù)連接使用,減輕BEAST攻擊。

    注意,如果使用了SSLv2,服務(wù)器會發(fā)送自己的配置列表給客戶端,客戶端會挑選密碼(cipher)。默認不支持SSLv2,除非node.js配置了./configure --with-sslv2

  • requestCert: 如果設(shè)為true,服務(wù)器會要求連接的客戶端發(fā)送證書,并嘗試驗證證書。默認:false。

  • rejectUnauthorized: 如果為true,服務(wù)器將會拒絕任何不被CAs列表授權(quán)的連接。僅requestCert參數(shù)為true時這個參數(shù)才有效。默認:false。

  • checkServerIdentity(servername, cert): 提供一個重寫的方法來檢查證書對應(yīng)的主機名。如果驗證失敗,返回error。如果驗證通過,返回undefined。

  • NPNProtocols: NPN協(xié)議的Buffer數(shù)組(協(xié)議需按優(yōu)先級排序)。

  • SNICallback(servername, cb): 如果客戶端支持SNI TLS擴展會調(diào)用這個函數(shù)。會傳入2個參數(shù):servernamecb。SNICallback必須調(diào)用 cb(null, ctx),其中ctx是SecureContext實例。(你可以用tls.createSecureContext(...)來獲取相應(yīng)的SecureContext上下文)。如果 SNICallback沒有提供,將會使用高級的API(參見下文).

  • sessionTimeout: 整數(shù),設(shè)定了服務(wù)器創(chuàng)建TLS會話標(biāo)示符(TLS session identifiers)和TLS會話票據(jù)(TLS session tickets)后的超時時間(單位:秒)。更多細節(jié)參見:SSL_CTX_set_timeout。

  • ticketKeys: 一個48字節(jié)的Buffer實例,由16字節(jié)的前綴,16字節(jié)的hmac key,16字節(jié)的AES key組成??捎糜盟鼇斫邮躷ls服務(wù)器實例上的tls會話票據(jù)(tls session tickets)。

    注意: 自動在集群模塊( cluster module)工作進程間共享。

  • sessionIdContext: 會話恢復(fù)(session resumption)的標(biāo)示符字符串。如果requestCerttrue。默認值為命令行生成的MD5哈希值。否則不提供默認值。

  • secureProtocol: SSL使用的方法,例如,SSLv3_method強制SSL版本為3??赡艿闹刀x于你所安裝的OpenSSL中的常量SSL_METHODS

  • secureOptions: 設(shè)置服務(wù)器配置。例如設(shè)置SSL_OP_NO_SSLv3可用禁用SSLv3協(xié)議。所有可用的參數(shù)見SSL_CTX_set_options

響應(yīng)服務(wù)器的簡單例子:

var tls = require('tls');
var fs = require('fs');

var 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') ]
};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

或者:

var tls = require('tls');
var fs = require('fs');

var options = {
  pfx: fs.readFileSync('server.pfx'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

你可以通過openssl s_client連接服務(wù)器來測試:

openssl s_client -connect 127.0.0.1:8000

tls.connect(options[, callback])

tls.connect(port[, host][, options][, callback])

創(chuàng)建一個新的客戶端連接到指定的端口和主機(port and host)(老版本API),或者options.portoptions.host(如果忽略host,默認為 localhost)。options是一個包含以下值得對象:

  • host: 客戶端需要連接到的主機。

  • port: 客戶端需要連接到的端口。

  • socket: 在指定的socket(而非新建)上建立安全連接。如果這個參數(shù)有值,將忽略hostport參數(shù)。

  • path: 創(chuàng)建 到參數(shù)path的unix socket連接。如果這個參數(shù)有值,將忽略hostport參數(shù)。

  • pfx: 包含私鑰,證書和客戶端(PFX或PKCS12格式)的CA證書的字符串或Buffer緩存。

  • key: 包含客戶端(PEM格式)的 私鑰的字符串或Buffer緩存??梢允莐eys數(shù)組。

  • passphrase: 私鑰或pfx的密碼字符串。

  • cert: 包含客戶端證書key(PEM格式)字符串或緩存Buffer。(可以是certs的數(shù)組)。

  • ca: 信任的證書(PEM格式)的字符串/緩存數(shù)組。如果忽略這個參數(shù),將會使用"root" CAs ,比如VeriSign。用來授權(quán)連接。

  • rejectUnauthorized: 如果為true,服務(wù)器證書根據(jù)CAs列表授權(quán)列表驗證。如果驗證失敗,觸發(fā)'error'事件;err.code包含OpenSSL錯誤代碼。默認:true

  • NPNProtocols: NPN協(xié)議的字符串或Buffer數(shù)組。Buffer必須有以下格式0x05hello0x05world,第一個字節(jié)是下一個協(xié)議名字的長度。(傳的數(shù)組通常非常簡單,比如:['hello', 'world'])。

  • servername: SNI(域名指示 Server Name Indication) TLS擴展的服務(wù)器名。

  • secureProtocol: SSL使用的方法,例如,SSLv3_method強制SSL版本為3??赡艿闹刀x于你所安裝的OpenSSL中的常量SSL_METHODS。

  • session: 一個Buffer實例,包含TLS會話.

將參數(shù)callback添加到'secureConnect'事件上,其效果如同監(jiān)聽器。

tls.connect()返回一個tls.TLSSocket對象。

這是一個簡單的客戶端應(yīng)答服務(wù)器例子:

var tls = require('tls');
var fs = require('fs');

var options = {
  // These are necessary only if using the client certificate authentication
  key: fs.readFileSync('client-key.pem'),
  cert: fs.readFileSync('client-cert.pem'),

  // This is necessary only if the server uses the self-signed certificate
  ca: [ fs.readFileSync('server-cert.pem') ]
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

或者:

var tls = require('tls');
var fs = require('fs');

var options = {
  pfx: fs.readFileSync('client.pfx')
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

類: tls.TLSSocket

net.Socket實例的封裝,取代內(nèi)部socket讀寫程序,執(zhí)行透明的輸入/輸出數(shù)據(jù)的加密/解密。

new tls.TLSSocket(socket, options)

從現(xiàn)有的TCP socket里構(gòu)造一個新的TLSSocket對象。

socket一個net.Socket的實例

options一個包含以下屬性的對象:

  • secureContext: 來自tls.createSecureContext( ... )的可選TLS上下文對象。

  • isServer: 如果為true, TLS socket將會在服務(wù)器模式(server-mode)初始化。

  • server: 一個可選的net.Server實例

  • requestCert: 可選的,參見tls.createSecurePair

  • rejectUnauthorized: 可選的,參見tls.createSecurePair

  • NPNProtocols: 可選的,參見tls.createServer

  • SNICallback: 可選的,參見tls.createServer

  • session: 可選的,一個Buffer實例,包含TLS會話

  • requestOCSP: 可選的,如果為true- OCSP狀態(tài)請求擴展將會被添加到客戶端hello,并且OCSPResponse事件將會在socket上建立安全通訊前觸發(fā)。

tls.createSecureContext(details)

創(chuàng)建一個憑證(credentials)對象,包含字典有以下的key:

  • pfx : 包含PFX或PKCS12加密的私鑰,證書和服務(wù)器的CA證書(PFX或PKCS12格式)字符串或緩存Buffer。(key,certca互斥)。
  • key : 包含PEM加密過的私鑰的字符串。
  • passphrase : 私鑰或pfx的密碼字符串。
  • cert : 包含PEM加密過的證書的字符串。
  • ca : 信任的PEM加密過的可信任的證書(PEM格式)字符串/緩存數(shù)組。
  • crl :PEM加密過的CRLs(證書撤銷列表)
  • ciphers: 要使用或排除的密碼(cipher)字符串。更多格式上的細節(jié)參見http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
  • honorCipherOrder : 當(dāng)選擇一個密碼(cipher) 時, 使用服務(wù)器配置,而不是客戶端的。 更多細節(jié)參見tls模塊文檔。

如果沒給 'ca' 細節(jié),node.js 將會使用默認的公開信任的 CAs 列表(參見http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt)。

tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])

創(chuàng)建一個新的安全對(secure pair)對象,包含2個流,其中一個讀/寫加密過的數(shù)據(jù),另外一個讀/寫明文數(shù)據(jù)。通常加密端數(shù)據(jù)來自是從輸入的加密數(shù)據(jù)流,另一端被當(dāng)做初始加密流。

  • credentials: 來自tls.createSecureContext( ... )的安全上下文對象。

  • isServer: 是否以服務(wù)器/客戶端模式打開這個tls連接。

  • requestCert: 是否服務(wù)器需要連接的客戶端發(fā)送證書。僅適用于服務(wù)端連接。

  • rejectUnauthorized:非法證書時,是否服務(wù)器需要自動拒絕客戶端。啟用requestCert后,才適用于服務(wù)器。

tls.createSecurePair()返回一個安全對(SecurePair)對象,包含明文cleartext和密文encrypted流 。

注意: cleartexttls.TLSSocket擁有相同的 API。

類: SecurePair

通過tls.createSecurePair返回。

事件: 'secure'

一旦安全對(SecurePair)成功建立一個安全連接,安全對(SecurePair)將會觸發(fā)這個事件。

和檢查服務(wù)器'secureConnection'事件一樣,pair.cleartext.authorized必須檢查確認是否適用的證書是授權(quán)過的。

類: tls.Server

這是net.Server的子類,擁有相同的方法。這個類接受適用TLS或SSL的加密連接,而不是接受原始TCP連接。

事件: 'secureConnection'

function (tlsSocket) {}

新的連接握手成功后回觸發(fā)這個事件。參數(shù)是tls.TLSSocket實例。它擁有常用的流方法和事件。

socket.authorized是否客戶端被證書(服務(wù)器提供)授權(quán)。如果socket.authorized為false,socket.authorizationError是如何授權(quán)失敗。值得一提的是,依賴于TLS服務(wù)器的設(shè)置,你的未授權(quán)連接可能也會被接受。socket.authorizationError如何授權(quán)失敗。值得一提的是,依賴于TLS服務(wù)器的設(shè)置,你的未授權(quán)連接可能也會被接受。socket.npnProtocol包含選擇的NPN協(xié)議的字符串。socket.servername包含SNI請求的服務(wù)器名的字符串。

事件: 'clientError'

function (exception, tlsSocket) { }

在安全連接建立前,客戶端連接觸發(fā)'error'事件會轉(zhuǎn)發(fā)到這里來。

tlsSockettls.TLSSocket,錯誤是從這里觸發(fā)的。

事件: 'newSession'

function (sessionId, sessionData, callback) { }

創(chuàng)建TLS會話的時候會觸發(fā)??赡苡脕碓谕獠看鎯ζ骼锎鎯?。callback必須最后調(diào)用,否則沒法從安全連接發(fā)送/接收數(shù)據(jù)。

注意: 添加這個事件監(jiān)聽器僅會在連接連接時有效果。

事件: 'resumeSession'

function (sessionId, callback) { }

當(dāng)客戶端想恢復(fù)之前的TLS會話時會觸發(fā)。事件監(jiān)聽器可能會使用sessionId到外部存儲器里查找,一旦結(jié)束會觸發(fā)callback(null, sessionData)。如果會話不能恢復(fù)(比如不存在這個會話),可能會調(diào)用callback(null, null)。調(diào)用callback(err)將會終止連接,并銷毀socket。

注意: 添加這個事件監(jiān)聽器僅會在連接連接時有效果。

事件: 'OCSPRequest'

function (certificate, issuer, callback) { }

當(dāng)客戶端發(fā)送證書狀態(tài)請求時會觸發(fā)。你可以解析服務(wù)器當(dāng)前的證書,來獲取OCSP網(wǎng)址和證書id,獲取OCSP響應(yīng)調(diào)用callback(null, resp),其中respBuffer實例。證書(certificate)和發(fā)行者(issuer)都是初級表達式緩存(BufferDER-representations of the primary)和證書的發(fā)行者。它可以用來獲取OCSP證書和OCSP終點網(wǎng)址。

可以調(diào)用callback(null, null),表示沒有OCSP響應(yīng)。

調(diào)用callback(err)可能會導(dǎo)致調(diào)用socket.destroy(err)。

典型流程:

  1. 客戶端連接服務(wù)器,并發(fā)送OCSPRequest(通過 ClientHello 里的狀態(tài)信息擴展)。
  2. 服務(wù)器收到請求,調(diào)用OCSPRequest事件監(jiān)聽器。
  3. 服務(wù)器從certificateissuer獲取OCSP網(wǎng)址,并執(zhí)行OCSP request到CA
  4. 服務(wù)器CA收到OCSPResponse, 并通過callback參數(shù)送回到客戶端
  5. 客戶端驗證響應(yīng),并銷毀socket或執(zhí)行握手

注意: 如果證書是自簽名的,或者如果發(fā)行者不再根證書列表里(你可以通過參數(shù)提供一個發(fā)行者)。issuer就可能為null。

注意:添加這個事件監(jiān)聽器僅會在連接連接時有效果。

注意:你可以能想要使用npm模塊(比如asn1.js)來解析證書。

server.listen(port[, host][, callback])

在指定的端口和主機上開始接收連接。如果host參數(shù)沒傳,服務(wù)接受通過IPv4地址(INADDR_ANY)的直連。

這是異步函數(shù)。當(dāng)服務(wù)器已經(jīng)綁定后回調(diào)用最后一個參數(shù)callback。

更多信息參見net.Server。

server.close()

停止服務(wù)器,不再接收新連接。這是異步函數(shù),當(dāng)服務(wù)器觸發(fā)'close'事件后回最終關(guān)閉。

server.address()

返回綁定的地址,地址家族名和服務(wù)器端口。更多信息參見net.Server.address()

server.addContext(hostname, context)

如果客戶端請求SNI主機名和傳入的hostname相匹配,將會用到安全上下文(secure context)。context可以包含key,certca和/或tls.createSecureContextoptions參數(shù)的其他任何屬性。

server.maxConnections

設(shè)置這個屬性可以在服務(wù)器的連接數(shù)達到最大值時拒絕連接。

server.connections

當(dāng)前服務(wù)器連接數(shù)。

類: CryptoStream

穩(wěn)定性: 0 - 拋棄. 使用 tls.TLSSocket 替代.

這是一個加密的流

cryptoStream.bytesWritten

底層socket寫字節(jié)訪問器(bytesWritten accessor)的代理,將會返回寫到socket的全部字節(jié)數(shù)。包括 TLS 的開銷。

類: tls.TLSSocket

net.Socket實例的封裝,透明的加密寫數(shù)據(jù)和所有必須的TLS協(xié)商。

這個接口實現(xiàn)了一個雙工流接口。它包含所有常用的流方法和事件。

事件: 'secureConnect'

新的連接成功握手后回觸發(fā)這個事件。無論服務(wù)器證書是否授權(quán),都會調(diào)用監(jiān)聽器。用于用戶測試tlsSocket.authorized看看如果服務(wù)器證書已經(jīng)被指定的CAs簽名。如果tlsSocket.authorized === false ,可以在tlsSocket.authorizationError里找到錯誤。如果使用了NPN,你可以檢tlsSocket.npnProtocol獲取協(xié)商協(xié)議(negotiated protocol)。

事件: 'OCSPResponse'

function (response) { }

如果啟用requestOCSP參賽會觸發(fā)這個事件。response是緩存對象,包含服務(wù)器的OCSP響應(yīng)。

一般來說,response是服務(wù)器CA簽名的對象,它包含服務(wù)器撤銷證書狀態(tài)的信息。

tlsSocket.encrypted

靜態(tài)boolean變量,一直是true??梢杂脕韰^(qū)別TLS socket和常規(guī)對象。

tlsSocket.authorized

boolean變量,如果對等實體證書(peer's certificate)被指定的某個CAs簽名,返回true,否則false。

tlsSocket.authorizationError

對等實體證書(peer's certificate)沒有驗證通過的原因。當(dāng)tlsSocket.authorized === false時,這個屬性才可用。

tlsSocket.getPeerCertificate([ detailed ])

返回一個代表對等實體證書( peer's certificate)的對象。這個返回對象有一些屬性和證書內(nèi)容相對應(yīng)。如果參數(shù)detailedtrue,將會返回包含發(fā)行者issuer完整鏈。如果false,僅有頂級證書沒有發(fā)行者issuer屬性。

例子:

{ subject:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuerInfo:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuer:
   { ... another certificate ... },
  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' }

如果peer沒有提供證書,返回null或空對象。

tlsSocket.getCipher()

返回一個對象,它代表了密碼名和當(dāng)前連接的SSL/TLS協(xié)議的版本。

例子:{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }

更多信息參見http://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS里的SSL_CIPHER_get_name()和SSL_CIPHER_get_version() 。

tlsSocket.renegotiate(options, callback)

初始化 TLS 重新協(xié)商進程。參數(shù)options可能包含以下內(nèi)容:rejectUnauthorized,requestCert(細節(jié)參見tls.createServer)。一旦重新協(xié)商成(renegotiation)功完成,將會執(zhí)行callback(err),其中errnull。

注意:當(dāng)安全連接建立后,可以用這來請求對等實體證書(peer's certificate)。

注意:作為服務(wù)器運行時,handshakeTimeout超時后,socket將會被銷毀。

tlsSocket.setMaxSendFragment(size)

設(shè)置最大的TLS碎片大?。J最大值為:16384,最小值為:512)。成功的話,返回true,否則返回false。

小的碎片包會減少客戶端的緩存延遲:大的碎片直到接收完畢后才能被TLS層完全緩存,并且驗證過完整性;大的碎片可能會有多次往返,并且可能會因為丟包或重新排序?qū)е卵舆t。而小的碎片會增加額外的TLS幀字節(jié)和CPU負載,這會減少CPU的吞吐量。

tlsSocket.getSession()

返回ASN.1編碼的TLS會話,如果沒有協(xié)商,會返回。連接到服務(wù)器時,可以用來加速握手的建立。

tlsSocket.getTLSTicket()

注意:僅和客戶端TLS socket打交道。僅在調(diào)試時有用,會話重用是,提供session參數(shù)給tls.connect

返回TLS會話票據(jù)(ticket),或如果沒有協(xié)商(negotiated),返回undefined。

tlsSocket.address()

返回綁定的地址,地址家族名和服務(wù)器端口。更多信息參見net.Server.address()。返回三個屬性, 比如:{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.remoteAddress

表示遠程IP地址(字符串表示),例如:'74.125.127.100''2001:4860:a005::68'.

tlsSocket.remoteFamily

表示遠程 IP 家族,'IPv4''IPv6'。

tlsSocket.remotePort

遠程端口(數(shù)字表示),例如,443。

tlsSocket.localAddress

本地IP地址(字符串表示)。

tlsSocket.localPort

本地端口號(數(shù)字表示)。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號