Skip to content

HTTPS

[Stabil: 2 - Stabil]

Stabil: 2 Stabilität: 2 - Stabil

Quellcode: lib/https.js

HTTPS ist das HTTP-Protokoll über TLS/SSL. In Node.js wird dies als separates Modul implementiert.

Feststellen, ob Krypto-Unterstützung nicht verfügbar ist

Es ist möglich, Node.js ohne Unterstützung für das Modul node:crypto zu erstellen. In solchen Fällen führt der Versuch, aus https zu importieren oder require('node:https') aufzurufen, zu einem Fehler.

Bei Verwendung von CommonJS kann der ausgegebene Fehler mit try/catch abgefangen werden:

js
let https
try {
  https = require('node:https')
} catch (err) {
  console.error('https-Unterstützung ist deaktiviert!')
}

Bei Verwendung des lexikalischen ESM import-Schlüsselworts kann der Fehler nur abgefangen werden, wenn ein Handler für process.on('uncaughtException') vor jedem Versuch, das Modul zu laden, registriert wird (z. B. mit einem Preload-Modul).

Bei Verwendung von ESM, wenn die Möglichkeit besteht, dass der Code auf einem Build von Node.js ausgeführt wird, bei dem die Krypto-Unterstützung nicht aktiviert ist, sollten Sie die Funktion import() anstelle des lexikalischen import-Schlüsselworts verwenden:

js
let https
try {
  https = await import('node:https')
} catch (err) {
  console.error('https-Unterstützung ist deaktiviert!')
}

Klasse: https.Agent

[Verlauf]

VersionÄnderungen
v5.3.0Unterstützung für 0 maxCachedSessions zum Deaktivieren der TLS-Session-Caching.
v2.5.0Parameter maxCachedSessions zu options für die Wiederverwendung von TLS-Sessions hinzugefügt.
v0.4.5Hinzugefügt in: v0.4.5

Ein Agent-Objekt für HTTPS, ähnlich zu http.Agent. Siehe https.request() für weitere Informationen.

new Agent([options])

[Verlauf]

VersionÄnderungen
v12.5.0Setzt den Servernamen nicht automatisch, wenn der Zielhost über eine IP-Adresse angegeben wurde.
  • options <Objekt> Satz von konfigurierbaren Optionen, die für den Agenten festgelegt werden sollen. Kann die gleichen Felder wie für http.Agent(options) haben, und
    • maxCachedSessions <Zahl> maximale Anzahl von zwischengespeicherten TLS-Sitzungen. Verwenden Sie 0, um das Zwischenspeichern von TLS-Sitzungen zu deaktivieren. Standardwert: 100.
    • servername <Zeichenkette> der Wert der Server Name Indication-Erweiterung, die an den Server gesendet werden soll. Verwenden Sie eine leere Zeichenkette '', um das Senden der Erweiterung zu deaktivieren. Standardwert: Hostname des Zielservers, es sei denn, der Zielserver wird über eine IP-Adresse angegeben, in diesem Fall ist der Standardwert '' (keine Erweiterung). Siehe Sitzungsfortsetzung für Informationen zur Wiederverwendung von TLS-Sitzungen.

Ereignis: 'keylog'

Hinzugefügt in: v13.2.0, v12.16.0

  • line <Buffer> Zeile mit ASCII-Text im NSS SSLKEYLOGFILE-Format.
  • tlsSocket <tls.TLSSocket> Die tls.TLSSocket-Instanz, auf der es generiert wurde.

Das Ereignis keylog wird ausgelöst, wenn Schlüsselmaterial von einer von diesem Agenten verwalteten Verbindung generiert oder empfangen wird (normalerweise vor Abschluss des Handshakes, aber nicht unbedingt). Dieses Schlüsselmaterial kann zum Debuggen gespeichert werden, da es das Entschlüsseln des erfassten TLS-Verkehrs ermöglicht. Es kann mehrmals für jede Socket ausgelöst werden.

Ein typischer Anwendungsfall besteht darin, empfangene Zeilen an eine gemeinsame Textdatei anzuhängen, die später von Software (wie Wireshark) zum Entschlüsseln des Datenverkehrs verwendet wird:

js
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
  fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 })
})

Klasse: https.Server

Hinzugefügt in: v0.3.4

Weitere Informationen finden Sie unter http.Server.

server.close([callback])

Hinzugefügt in: v0.1.90

Siehe server.close() im Modul node:http.

server[Symbol.asyncDispose]()

Hinzugefügt in: v20.4.0

[Stabil: 1 - Experimentell]

Stabil: 1 Stabilität: 1 - Experimentell

Ruft server.close() auf und gibt ein Promise zurück, das erfüllt wird, wenn der Server geschlossen wurde.

server.closeAllConnections()

Hinzugefügt in: v18.2.0

Siehe server.closeAllConnections() im Modul node:http.

server.closeIdleConnections()

Hinzugefügt in: v18.2.0

Siehe server.closeIdleConnections() im Modul node:http.

server.headersTimeout

Hinzugefügt in: v11.3.0

Siehe server.headersTimeout im node:http-Modul.

server.listen()

Startet den HTTPS-Server und lauscht auf verschlüsselte Verbindungen. Diese Methode ist identisch mit server.listen() von net.Server.

server.maxHeadersCount

Siehe server.maxHeadersCount im node:http-Modul.

server.requestTimeout

[Verlauf]

VersionÄnderungen
v18.0.0Das Standard-Request-Timeout wurde von keinem Timeout auf 300 Sekunden (5 Minuten) geändert.
v14.11.0Hinzugefügt in: v14.11.0

Siehe server.requestTimeout im node:http-Modul.

server.setTimeout([msecs][, callback])

Hinzugefügt in: v0.11.2

Siehe server.setTimeout() im node:http-Modul.

server.timeout

[Verlauf]

VersionÄnderungen
v13.0.0Das Standard-Timeout wurde von 120 Sekunden auf 0 (kein Timeout) geändert.
v0.11.2Hinzugefügt in: v0.11.2

Siehe server.timeout im node:http-Modul.

server.keepAliveTimeout

Hinzugefügt in: v8.0.0

Siehe server.keepAliveTimeout im Modul node:http.

https.createServer([options][, requestListener])

Hinzugefügt in: v0.3.4

js
// curl -k https://localhost:8000/
import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const options = {
  key: readFileSync('private-key.pem'),
  cert: readFileSync('certificate.pem'),
}

createServer(options, (req, res) => {
  res.writeHead(200)
  res.end('hello world\n')
}).listen(8000)
js
// curl -k https://localhost:8000/
const https = require('node:https')
const fs = require('node:fs')

const options = {
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
}

https
  .createServer(options, (req, res) => {
    res.writeHead(200)
    res.end('hello world\n')
  })
  .listen(8000)

Oder

js
import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const options = {
  pfx: readFileSync('test_cert.pfx'),
  passphrase: 'sample',
}

createServer(options, (req, res) => {
  res.writeHead(200)
  res.end('hello world\n')
}).listen(8000)
js
const https = require('node:https')
const fs = require('node:fs')

const options = {
  pfx: fs.readFileSync('test_cert.pfx'),
  passphrase: 'sample',
}

https
  .createServer(options, (req, res) => {
    res.writeHead(200)
    res.end('hello world\n')
  })
  .listen(8000)

Um das Zertifikat und den Schlüssel für dieses Beispiel zu generieren, führen Sie aus:

bash
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout private-key.pem -out certificate.pem

Um dann das pfx-Zertifikat für dieses Beispiel zu generieren, führen Sie aus:

bash
openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \
  -inkey private-key.pem -in certificate.pem -passout pass:sample

https.get(options[, callback])

https.get(url[, options][, callback])

[Versionsgeschichte]

VersionÄnderungen
v10.9.0Der Parameter url kann nun zusammen mit einem separaten options-Objekt übergeben werden.
v7.5.0Der Parameter options kann ein WHATWG URL-Objekt sein.
v0.3.6Hinzugefügt in: v0.3.6

Ähnlich wie http.get(), aber für HTTPS.

options kann ein Objekt, eine Zeichenkette oder ein URL-Objekt sein. Wenn options eine Zeichenkette ist, wird sie automatisch mit new URL() analysiert. Wenn es sich um ein URL-Objekt handelt, wird es automatisch in ein gewöhnliches options-Objekt konvertiert.

js
import { get } from 'node:https'
import process from 'node:process'

get('https://encrypted.google.com/', res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
}).on('error', e => {
  console.error(e)
})
js
const https = require('node:https')

https
  .get('https://encrypted.google.com/', res => {
    console.log('statusCode:', res.statusCode)
    console.log('headers:', res.headers)

    res.on('data', d => {
      process.stdout.write(d)
    })
  })
  .on('error', e => {
    console.error(e)
  })

https.globalAgent

[Verlauf]

VersionÄnderungen
v19.0.0Der Agent verwendet jetzt standardmäßig HTTP Keep-Alive und ein Timeout von 5 Sekunden.
v0.5.9Hinzugefügt in: v0.5.9

Globale Instanz von https.Agent für alle HTTPS-Client-Anfragen. Weicht von einer Standardkonfiguration von https.Agent ab, indem keepAlive aktiviert ist und ein timeout von 5 Sekunden verwendet wird.

https.request(options[, callback])

https.request(url[, options][, callback])

[Verlauf]

VersionÄnderungen
v22.4.0, v20.16.0Die Option clientCertEngine hängt von der Unterstützung benutzerdefinierter Engines in OpenSSL ab, die in OpenSSL 3 veraltet ist.
v16.7.0, v14.18.0Bei Verwendung eines URL-Objekts werden analysierte Benutzernamen und Passwörter jetzt korrekt URI-decodiert.
v14.1.0, v13.14.0Die Option highWaterMark wird jetzt akzeptiert.
v10.9.0Der Parameter url kann jetzt zusammen mit einem separaten options-Objekt übergeben werden.
v9.3.0Der Parameter options kann jetzt clientCertEngine enthalten.
v7.5.0Der Parameter options kann ein WHATWG URL-Objekt sein.
v0.3.6Hinzugefügt in: v0.3.6

Sendet eine Anfrage an einen sicheren Webserver.

Die folgenden zusätzlichen options von tls.connect() werden ebenfalls akzeptiert: ca, cert, ciphers, clientCertEngine (veraltet), crl, dhparam, ecdhCurve, honorCipherOrder, key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext, highWaterMark.

options kann ein Objekt, eine Zeichenkette oder ein URL-Objekt sein. Wenn options eine Zeichenkette ist, wird sie automatisch mit new URL() analysiert. Wenn es sich um ein URL-Objekt handelt, wird es automatisch in ein gewöhnliches options-Objekt konvertiert.

https.request() gibt eine Instanz der Klasse http.ClientRequest zurück. Die ClientRequest-Instanz ist ein beschreibbarer Stream. Wenn eine Datei mit einer POST-Anfrage hochgeladen werden muss, schreiben Sie in das ClientRequest-Objekt.

js
import { request } from 'node:https'
import process from 'node:process'

const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
}

const req = request(options, res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', e => {
  console.error(e)
})
req.end()
js
const https = require('node:https')

const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
}

const req = https.request(options, res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', e => {
  console.error(e)
})
req.end()

Beispiel mit Optionen von tls.connect():

js
const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
}
options.agent = new https.Agent(options)

const req = https.request(options, res => {
  // ...
})

Alternativ kann man Connection Pooling deaktivieren, indem man keinen Agent verwendet.

js
const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
  agent: false,
}

const req = https.request(options, res => {
  // ...
})

Beispiel mit einem URL als options:

js
const options = new URL('https://abc:')

const req = https.request(options, res => {
  // ...
})

Beispiel für das Anheften an einen Zertifikats-Fingerabdruck oder den öffentlichen Schlüssel (ähnlich wie pin-sha256):

js
import { checkServerIdentity } from 'node:tls'
import { Agent, request } from 'node:https'
import { createHash } from 'node:crypto'

function sha256(s) {
  return createHash('sha256').update(s).digest('base64')
}
const options = {
  hostname: 'github.com',
  port: 443,
  path: '/',
  method: 'GET',
  checkServerIdentity: function (host, cert) {
    // Stellen Sie sicher, dass das Zertifikat für den Host ausgestellt wurde, mit dem wir verbunden sind
    const err = checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Den öffentlichen Schlüssel anheften, ähnlich wie HPKP pin-sha256 Anheften
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Zertifikatüberprüfungsfehler: ' +
        `Der öffentliche Schlüssel von '${cert.subject.CN}' ` +
        'stimmt nicht mit unserem angehefteten Fingerabdruck überein'
      return new Error(msg)
    }

    // Das genaue Zertifikat anheften, anstatt des öffentlichen Schlüssels
    const cert256 =
      'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'
    if (cert.fingerprint256 !== cert256) {
      const msg =
        'Zertifikatüberprüfungsfehler: ' +
        `Das Zertifikat von '${cert.subject.CN}' ` +
        'stimmt nicht mit unserem angehefteten Fingerabdruck überein'
      return new Error(msg)
    }

    // Diese Schleife dient nur zur Information.
    // Geben Sie die Zertifikats- und öffentlichen Schlüssel-Fingerabdrücke aller Zertifikate in der
    // Kette aus. Es ist üblich, den öffentlichen Schlüssel des Ausstellers im öffentlichen
    // Internet anzuheften, während der öffentliche Schlüssel des Dienstes in sensiblen
    // Umgebungen angeheftet wird.
    let lastprint256
    do {
      console.log('Subject Common Name:', cert.subject.CN)
      console.log('  Certificate SHA256 fingerprint:', cert.fingerprint256)

      const hash = createHash('sha256')
      console.log('  Public key ping-sha256:', sha256(cert.pubkey))

      lastprint256 = cert.fingerprint256
      cert = cert.issuerCertificate
    } while (cert.fingerprint256 !== lastprint256)
  },
}

options.agent = new Agent(options)
const req = request(options, res => {
  console.log('Alles in Ordnung. Server stimmt mit unserem angehefteten Zertifikat oder öffentlichen Schlüssel überein')
  console.log('statusCode:', res.statusCode)

  res.on('data', d => {})
})

req.on('error', e => {
  console.error(e.message)
})
req.end()
js
const tls = require('node:tls')
const https = require('node:https')
const crypto = require('node:crypto')

function sha256(s) {
  return crypto.createHash('sha256').update(s).digest('base64')
}
const options = {
  hostname: 'github.com',
  port: 443,
  path: '/',
  method: 'GET',
  checkServerIdentity: function (host, cert) {
    // Stellen Sie sicher, dass das Zertifikat für den Host ausgestellt wurde, mit dem wir verbunden sind
    const err = tls.checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Den öffentlichen Schlüssel anheften, ähnlich wie HPKP pin-sha256 Anheften
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Zertifikatüberprüfungsfehler: ' +
        `Der öffentliche Schlüssel von '${cert.subject.CN}' ` +
        'stimmt nicht mit unserem angehefteten Fingerabdruck überein'
      return new Error(msg)
    }

    // Das genaue Zertifikat anheften, anstatt des öffentlichen Schlüssels
    const cert256 =
      'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'
    if (cert.fingerprint256 !== cert256) {
      const msg =
        'Zertifikatüberprüfungsfehler: ' +
        `Das Zertifikat von '${cert.subject.CN}' ` +
        'stimmt nicht mit unserem angehefteten Fingerabdruck überein'
      return new Error(msg)
    }

    // Diese Schleife dient nur zur Information.
    // Geben Sie die Zertifikats- und öffentlichen Schlüssel-Fingerabdrücke aller Zertifikate in der
    // Kette aus. Es ist üblich, den öffentlichen Schlüssel des Ausstellers im öffentlichen
    // Internet anzuheften, während der öffentliche Schlüssel des Dienstes in sensiblen
    // Umgebungen angeheftet wird.
    do {
      console.log('Subject Common Name:', cert.subject.CN)
      console.log('  Certificate SHA256 fingerprint:', cert.fingerprint256)

      hash = crypto.createHash('sha256')
      console.log('  Public key ping-sha256:', sha256(cert.pubkey))

      lastprint256 = cert.fingerprint256
      cert = cert.issuerCertificate
    } while (cert.fingerprint256 !== lastprint256)
  },
}

options.agent = new https.Agent(options)
const req = https.request(options, res => {
  console.log('Alles in Ordnung. Server stimmt mit unserem angehefteten Zertifikat oder öffentlichen Schlüssel überein')
  console.log('statusCode:', res.statusCode)

  res.on('data', d => {})
})

req.on('error', e => {
  console.error(e.message)
})
req.end()

Beispielausgabe:

text
Subject Common Name: github.com
  Certificate SHA256 fingerprint: FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65
  Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
  Certificate SHA256 fingerprint: 61:E9:73:75:E9:F6:DA:98:2F:F5:C1:9E:2F:94:E6:6C:4E:35:B6:83:7C:E3:B9:14:D2:24:5C:7F:5F:65:82:5F
  Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Subject Common Name: USERTrust ECC Certification Authority
  Certificate SHA256 fingerprint: A6:CF:64:DB:B4:C8:D5:FD:19:CE:48:89:60:68:DB:03:B5:33:A8:D1:33:6C:62:56:A8:7D:00:CB:B3:DE:F3:EA
  Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Subject Common Name: AAA Certificate Services
  Certificate SHA256 fingerprint: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
  Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
Alles in Ordnung. Server stimmt mit unserem angehefteten Zertifikat oder öffentlichen Schlüssel überein
statusCode: 200