Crypto#

穩定性:2 - 穩定

node:crypto 模組提供了加密功能,包括用於 OpenSSL 的雜湊、HMAC、加密、解密、簽名和驗證功能的一組包裝器。

const { createHmac } = await import('node:crypto');

const secret = 'abcdefg';
const hash = createHmac('sha256', secret)
               .update('I love cupcakes')
               .digest('hex');
console.log(hash);
// Prints:
//   c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
const { createHmac } = require('node:crypto');

const secret = 'abcdefg';
const hash = createHmac('sha256', secret)
               .update('I love cupcakes')
               .digest('hex');
console.log(hash);
// Prints:
//   c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e

確定加密支援是否不可用#

Node.js 可能會在構建時未包含對 node:crypto 模組的支援。在這種情況下,嘗試從 crypto 匯入或呼叫 require('node:crypto') 將導致丟擲錯誤。

使用 CommonJS 時,丟擲的錯誤可以使用 try/catch 捕獲。

let crypto;
try {
  crypto = require('node:crypto');
} catch (err) {
  console.error('crypto support is disabled!');
}

當使用詞法 ESM import 關鍵字時,只有在嘗試載入模組*之前*註冊了 process.on('uncaughtException') 的處理程式(例如,使用預載入模組),才能捕獲該錯誤。

使用 ESM 時,如果程式碼有可能在未啟用加密支援的 Node.js 版本上執行,請考慮使用 import() 函式,而不是詞法 import 關鍵字。

let crypto;
try {
  crypto = await import('node:crypto');
} catch (err) {
  console.error('crypto support is disabled!');
}

非對稱金鑰型別#

下表列出了 KeyObject API 識別的非對稱金鑰型別,以及每種金鑰型別支援的匯出/匯入格式。

金鑰型別 描述 OID 'pem' 'der' 'jwk' 'raw-public' 'raw-private' 'raw-seed'
'dh' Diffie-Hellman 1.2.840.113549.1.3.1
'dsa' DSA 1.2.840.10040.4.1
'ec' 橢圓曲線 1.2.840.10045.2.1
'ed25519' Ed25519 1.3.101.112
'ed448' Ed448 1.3.101.113
'ml-dsa-44'1 ML-DSA-44 2.16.840.1.101.3.4.3.17
'ml-dsa-65'1 ML-DSA-65 2.16.840.1.101.3.4.3.18
'ml-dsa-87'1 ML-DSA-87 2.16.840.1.101.3.4.3.19
'ml-kem-512'1 ML-KEM-512 2.16.840.1.101.3.4.4.1
'ml-kem-768'1 ML-KEM-768 2.16.840.1.101.3.4.4.2
'ml-kem-1024'1 ML-KEM-1024 2.16.840.1.101.3.4.4.3
'rsa-pss' RSA PSS 1.2.840.113549.1.1.10
'rsa' RSA 1.2.840.113549.1.1.1
'slh-dsa-sha2-128f'1 SLH-DSA-SHA2-128f 2.16.840.1.101.3.4.3.21
'slh-dsa-sha2-128s'1 SLH-DSA-SHA2-128s 2.16.840.1.101.3.4.3.20
'slh-dsa-sha2-192f'1 SLH-DSA-SHA2-192f 2.16.840.1.101.3.4.3.23
'slh-dsa-sha2-192s'1 SLH-DSA-SHA2-192s 2.16.840.1.101.3.4.3.22
'slh-dsa-sha2-256f'1 SLH-DSA-SHA2-256f 2.16.840.1.101.3.4.3.25
'slh-dsa-sha2-256s'1 SLH-DSA-SHA2-256s 2.16.840.1.101.3.4.3.24
'slh-dsa-shake-128f'1 SLH-DSA-SHAKE-128f 2.16.840.1.101.3.4.3.27
'slh-dsa-shake-128s'1 SLH-DSA-SHAKE-128s 2.16.840.1.101.3.4.3.26
'slh-dsa-shake-192f'1 SLH-DSA-SHAKE-192f 2.16.840.1.101.3.4.3.29
'slh-dsa-shake-192s'1 SLH-DSA-SHAKE-192s 2.16.840.1.101.3.4.3.28
'slh-dsa-shake-256f'1 SLH-DSA-SHAKE-256f 2.16.840.1.101.3.4.3.31
'slh-dsa-shake-256s'1 SLH-DSA-SHAKE-256s 2.16.840.1.101.3.4.3.30
'x25519' X25519 1.3.101.110
'x448' X448 1.3.101.111

金鑰格式#

非對稱金鑰可以用多種格式表示。建議的方法是將金鑰材料匯入 KeyObject 一次,並將其重用於所有後續操作,因為這可以避免重複解析並提供最佳效能。

KeyObject 不切實際時(例如,當金鑰材料出現在協議訊息中且僅使用一次時),大多數加密函式也接受 PEM 字串或直接指定格式和金鑰材料的物件。有關每種格式接受的完整選項,請參見 crypto.createPublicKey()crypto.createPrivateKey()keyObject.export()

KeyObject#

KeyObject 是解析金鑰的記憶體中表示形式。它由 crypto.createPublicKey()crypto.createPrivateKey()crypto.createSecretKey() 或金鑰生成函式(例如 crypto.generateKeyPair())建立。使用給定 KeyObject 的第一次加密操作可能比後續操作慢,因為 OpenSSL 在首次使用時會延遲初始化內部快取。

PEM 和 DER#

PEM 和 DER 是基於 ASN.1 結構的非對稱金鑰的傳統編碼格式。

  • PEM 是一種文字編碼,它將 Base64 編碼的 DER 資料包裝在頁首和頁尾行之間(例如 -----BEGIN PUBLIC KEY-----)。PEM 字串可以直接傳遞給大多數加密操作。
  • DER 是相同 ASN.1 結構的二進位制編碼。提供 DER 輸入時,必須明確指定 type(通常為 'spki''pkcs8')。
JSON Web 金鑰 (JWK)#

JSON Web 金鑰 (JWK) 是一種基於 JSON 的金鑰表示法,在 RFC 7517 中定義。JWK 將每個金鑰元件編碼為 JSON 物件中的單個 Base64url 編碼值。對於 RSA 金鑰,JWK 避免了 ASN.1 解析開銷,是速度最快的序列化匯入格式。

原始金鑰格式#

穩定性:1.1 - 活躍開發中

'raw-public''raw-private''raw-seed' 金鑰格式允許匯入和匯出原始金鑰材料,無需任何編碼包裝。有關用法詳情,請參閱 keyObject.export()crypto.createPublicKey()crypto.createPrivateKey()

'raw-public' 通常是匯入公鑰的最快方式。'raw-private''raw-seed' 並不總是比其他格式快,因為它們只包含私有標量或種子——匯入它們需要匯出公鑰元件(例如橢圓曲線點乘或種子擴充套件),這可能會很昂貴。其他格式同時包含私鑰和公鑰元件,避免了該計算。

選擇金鑰格式#

始終優先選擇 KeyObject——從你擁有的任何格式建立一個並重用它。以下指導僅適用於在序列化格式之間進行選擇時,無論是為了匯入 KeyObject 還是在 KeyObject 不切實際時內聯傳遞金鑰材料。

匯入金鑰#

當建立 KeyObject 以供重複使用時,匯入成本只支付一次,因此選擇更快的格式可以減少啟動延遲。

匯入成本分為兩部分:解析開銷(解碼序列化包裝)和 金鑰計算(重建完整金鑰所需的任何數學工作,例如從私有標量推導公鑰或擴充套件種子)。哪部分佔主導地位取決於金鑰型別。例如:

  • 公鑰 - 'raw-public' 是最快的序列化格式,因為原始格式跳過了所有 ASN.1 和 Base64 解碼。
  • EC 私鑰 - 'raw-private' 比 PEM 或 DER 快,因為它避免了 ASN.1 解析。然而,對於較大的曲線(例如 P-384、P-521),從私有標量匯出公點的必要計算變得昂貴,從而降低了優勢。
  • RSA 金鑰 - 'jwk' 是最快的序列化格式。JWK 將 RSA 金鑰元件表示為單獨的 Base64url 編碼整數,完全避免了 ASN.1 解析的開銷。
操作中的內聯金鑰材料#

KeyObject 無法重用時(例如,金鑰作為協議訊息中的原始位元組到達且僅使用一次),大多數加密函式也接受 PEM 字串或直接指定格式和金鑰材料的物件。在這種情況下,總成本是金鑰匯入成本與加密計算成本之和。

對於加密計算占主導地位的操作(例如使用 RSA 簽名或使用 P-384 或 P-521 進行 ECDH 金鑰協商),序列化格式對總體吞吐量的影響微乎其微,因此請選擇最方便的格式。對於像 Ed25519 簽名或驗證這樣的輕量級操作,匯入成本佔總成本的比例較大,因此更快的格式(如 'raw-public''raw-private')可以顯著提高吞吐量。

即使相同的金鑰材料僅使用幾次,將其匯入 KeyObject 也比反覆傳遞原始或 PEM 表示形式更值得。

示例#

示例:在簽名和驗證操作中重用 KeyObject

import { promisify } from 'node:util';
const { generateKeyPair, sign, verify } = await import('node:crypto');

const { publicKey, privateKey } = await promisify(generateKeyPair)('ed25519');

// A KeyObject holds the parsed key in memory and can be reused
// across multiple operations without re-parsing.
const data = new TextEncoder().encode('message to sign');
const signature = sign(null, data, privateKey);
verify(null, data, publicKey, signature);

示例:將各種格式的金鑰匯入 KeyObject

import { promisify } from 'node:util';
const {
  createPrivateKey, createPublicKey, generateKeyPair,
} = await import('node:crypto');

const generated = await promisify(generateKeyPair)('ed25519');

// PEM
const privatePem = generated.privateKey.export({ format: 'pem', type: 'pkcs8' });
const publicPem = generated.publicKey.export({ format: 'pem', type: 'spki' });
createPrivateKey(privatePem);
createPublicKey(publicPem);

// DER - requires explicit type
const privateDer = generated.privateKey.export({ format: 'der', type: 'pkcs8' });
const publicDer = generated.publicKey.export({ format: 'der', type: 'spki' });
createPrivateKey({ key: privateDer, format: 'der', type: 'pkcs8' });
createPublicKey({ key: publicDer, format: 'der', type: 'spki' });

// JWK
const privateJwk = generated.privateKey.export({ format: 'jwk' });
const publicJwk = generated.publicKey.export({ format: 'jwk' });
createPrivateKey({ key: privateJwk, format: 'jwk' });
createPublicKey({ key: publicJwk, format: 'jwk' });

// Raw
const rawPriv = generated.privateKey.export({ format: 'raw-private' });
const rawPub = generated.publicKey.export({ format: 'raw-public' });
createPrivateKey({ key: rawPriv, format: 'raw-private', asymmetricKeyType: 'ed25519' });
createPublicKey({ key: rawPub, format: 'raw-public', asymmetricKeyType: 'ed25519' });

示例:將金鑰材料直接傳遞給 crypto.sign()crypto.verify(),而不先建立 KeyObject

import { promisify } from 'node:util';
const { generateKeyPair, sign, verify } = await import('node:crypto');

const generated = await promisify(generateKeyPair)('ed25519');

const data = new TextEncoder().encode('message to sign');

// PEM strings
const privatePem = generated.privateKey.export({ format: 'pem', type: 'pkcs8' });
const publicPem = generated.publicKey.export({ format: 'pem', type: 'spki' });
const sig1 = sign(null, data, privatePem);
verify(null, data, publicPem, sig1);

// JWK objects
const privateJwk = generated.privateKey.export({ format: 'jwk' });
const publicJwk = generated.publicKey.export({ format: 'jwk' });
const sig2 = sign(null, data, { key: privateJwk, format: 'jwk' });
verify(null, data, { key: publicJwk, format: 'jwk' }, sig2);

// Raw key bytes
const rawPriv = generated.privateKey.export({ format: 'raw-private' });
const rawPub = generated.publicKey.export({ format: 'raw-public' });
const sig3 = sign(null, data, {
  key: rawPriv, format: 'raw-private', asymmetricKeyType: 'ed25519',
});
verify(null, data, {
  key: rawPub, format: 'raw-public', asymmetricKeyType: 'ed25519',
}, sig3);

示例:對於 EC 金鑰,匯入原始金鑰時需要 namedCurve 選項

import { promisify } from 'node:util';
const {
  createPrivateKey, createPublicKey, generateKeyPair, sign, verify,
} = await import('node:crypto');

const generated = await promisify(generateKeyPair)('ec', {
  namedCurve: 'P-256',
});

// Export the raw EC public key (uncompressed by default).
const rawPublicKey = generated.publicKey.export({ format: 'raw-public' });

// The following is equivalent.
const rawPublicKeyUncompressed = generated.publicKey.export({
  format: 'raw-public',
  type: 'uncompressed',
});

// Export compressed point format.
const rawPublicKeyCompressed = generated.publicKey.export({
  format: 'raw-public',
  type: 'compressed',
});

// Export the raw EC private key.
const rawPrivateKey = generated.privateKey.export({ format: 'raw-private' });

// Import the raw EC keys.
// Both compressed and uncompressed point formats are accepted.
const publicKey = createPublicKey({
  key: rawPublicKey,
  format: 'raw-public',
  asymmetricKeyType: 'ec',
  namedCurve: 'P-256',
});
const privateKey = createPrivateKey({
  key: rawPrivateKey,
  format: 'raw-private',
  asymmetricKeyType: 'ec',
  namedCurve: 'P-256',
});

const data = new TextEncoder().encode('message to sign');
const signature = sign('sha256', data, privateKey);
verify('sha256', data, publicKey, signature);

示例:匯出原始種子並匯入它們

import { promisify } from 'node:util';
const {
  createPrivateKey, decapsulate, encapsulate, generateKeyPair,
} = await import('node:crypto');

const generated = await promisify(generateKeyPair)('ml-kem-768');

// Export the raw seed (64 bytes for ML-KEM).
const seed = generated.privateKey.export({ format: 'raw-seed' });

// Import the raw seed.
const privateKey = createPrivateKey({
  key: seed,
  format: 'raw-seed',
  asymmetricKeyType: 'ml-kem-768',
});

const { ciphertext } = encapsulate(generated.publicKey);
decapsulate(privateKey, ciphertext);

類:Certificate#

SPKAC 是 Netscape 最初實現的證書籤名請求機制,並被正式指定為 HTML5 keygen 元素的一部分。

<keygen>HTML 5.2 起已被棄用,新專案不應再使用此元素。

node:crypto 模組提供了 Certificate 類來處理 SPKAC 資料。最常見的用法是處理由 HTML5 <keygen> 元素生成的輸出。Node.js 內部使用 OpenSSL 的 SPKAC 實現

靜態方法:Certificate.exportChallenge(spkac[, encoding])#

const { Certificate } = await import('node:crypto');
const spkac = getSpkacSomehow();
const challenge = Certificate.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints: the challenge as a UTF8 string
const { Certificate } = require('node:crypto');
const spkac = getSpkacSomehow();
const challenge = Certificate.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints: the challenge as a UTF8 string

靜態方法:Certificate.exportPublicKey(spkac[, encoding])#

const { Certificate } = await import('node:crypto');
const spkac = getSpkacSomehow();
const publicKey = Certificate.exportPublicKey(spkac);
console.log(publicKey);
// Prints: the public key as <Buffer ...>
const { Certificate } = require('node:crypto');
const spkac = getSpkacSomehow();
const publicKey = Certificate.exportPublicKey(spkac);
console.log(publicKey);
// Prints: the public key as <Buffer ...>

靜態方法:Certificate.verifySpkac(spkac[, encoding])#

import { Buffer } from 'node:buffer';
const { Certificate } = await import('node:crypto');

const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Prints: true or false
const { Buffer } = require('node:buffer');
const { Certificate } = require('node:crypto');

const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Prints: true or false

遺留 API#

穩定性:0 - 已棄用

作為遺留介面,可以按照以下示例所示建立 crypto.Certificate 類的新例項。

new crypto.Certificate()#

可以使用 new 關鍵字或透過將 crypto.Certificate() 作為函式呼叫來建立 Certificate 類的例項。

const { Certificate } = await import('node:crypto');

const cert1 = new Certificate();
const cert2 = Certificate();
const { Certificate } = require('node:crypto');

const cert1 = new Certificate();
const cert2 = Certificate();
certificate.exportChallenge(spkac[, encoding])#
const { Certificate } = await import('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints: the challenge as a UTF8 string
const { Certificate } = require('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints: the challenge as a UTF8 string
certificate.exportPublicKey(spkac[, encoding])#
const { Certificate } = await import('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Prints: the public key as <Buffer ...>
const { Certificate } = require('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Prints: the public key as <Buffer ...>
certificate.verifySpkac(spkac[, encoding])#
import { Buffer } from 'node:buffer';
const { Certificate } = await import('node:crypto');

const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// Prints: true or false
const { Buffer } = require('node:buffer');
const { Certificate } = require('node:crypto');

const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// Prints: true or false

類:Cipheriv#

Cipheriv 類的例項用於加密資料。該類可以透過以下兩種方式之一使用

  • 作為既可讀又可寫的 ,將普通未加密資料寫入,在可讀端產生加密資料,或者
  • 使用 cipher.update()cipher.final() 方法來產生加密資料。

crypto.createCipheriv() 方法用於建立 Cipheriv 例項。Cipheriv 物件不應使用 new 關鍵字直接建立。

示例:將 Cipheriv 物件用作流

const {
  scrypt,
  randomFill,
  createCipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    // Once we have the key and iv, we can create and use the cipher...
    const cipher = createCipheriv(algorithm, key, iv);

    let encrypted = '';
    cipher.setEncoding('hex');

    cipher.on('data', (chunk) => encrypted += chunk);
    cipher.on('end', () => console.log(encrypted));

    cipher.write('some clear text data');
    cipher.end();
  });
});
const {
  scrypt,
  randomFill,
  createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    // Once we have the key and iv, we can create and use the cipher...
    const cipher = createCipheriv(algorithm, key, iv);

    let encrypted = '';
    cipher.setEncoding('hex');

    cipher.on('data', (chunk) => encrypted += chunk);
    cipher.on('end', () => console.log(encrypted));

    cipher.write('some clear text data');
    cipher.end();
  });
});

示例:使用 Cipheriv 和管道流

import {
  createReadStream,
  createWriteStream,
} from 'node:fs';

import {
  pipeline,
} from 'node:stream';

const {
  scrypt,
  randomFill,
  createCipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    const cipher = createCipheriv(algorithm, key, iv);

    const input = createReadStream('test.js');
    const output = createWriteStream('test.enc');

    pipeline(input, cipher, output, (err) => {
      if (err) throw err;
    });
  });
});
const {
  createReadStream,
  createWriteStream,
} = require('node:fs');

const {
  pipeline,
} = require('node:stream');

const {
  scrypt,
  randomFill,
  createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    const cipher = createCipheriv(algorithm, key, iv);

    const input = createReadStream('test.js');
    const output = createWriteStream('test.enc');

    pipeline(input, cipher, output, (err) => {
      if (err) throw err;
    });
  });
});

示例:使用 cipher.update()cipher.final() 方法

const {
  scrypt,
  randomFill,
  createCipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    const cipher = createCipheriv(algorithm, key, iv);

    let encrypted = cipher.update('some clear text data', 'utf8', 'hex');
    encrypted += cipher.final('hex');
    console.log(encrypted);
  });
});
const {
  scrypt,
  randomFill,
  createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
  if (err) throw err;
  // Then, we'll generate a random initialization vector
  randomFill(new Uint8Array(16), (err, iv) => {
    if (err) throw err;

    const cipher = createCipheriv(algorithm, key, iv);

    let encrypted = cipher.update('some clear text data', 'utf8', 'hex');
    encrypted += cipher.final('hex');
    console.log(encrypted);
  });
});

cipher.final([outputEncoding])#

  • outputEncoding <string> 返回值的編碼
  • 返回:<Buffer> | <string> 任何剩餘的已加密內容。如果指定了 outputEncoding,則返回字串。如果未提供 outputEncoding,則返回 Buffer

一旦呼叫了 cipher.final() 方法,Cipheriv 物件就不能再用於加密資料。嘗試多次呼叫 cipher.final() 將導致丟擲錯誤。

cipher.getAuthTag()#

  • 返回:<Buffer> 使用認證加密模式時(目前支援 GCMCCMOCBchacha20-poly1305),cipher.getAuthTag() 方法返回一個 Buffer,其中包含從給定資料計算出的認證標籤

cipher.getAuthTag() 方法僅應在使用 cipher.final() 方法完成加密後呼叫。

如果建立 cipher 例項時設定了 authTagLength 選項,則此函式將精確返回 authTagLength 位元組。

cipher.setAAD(buffer[, options])#

使用認證加密模式時(目前支援 GCMCCMOCBchacha20-poly1305),cipher.setAAD() 方法設定用於附加認證資料 (AAD) 輸入引數的值。

對於 GCMOCBplaintextLength 選項是可選的。使用 CCM 時,必須指定 plaintextLength 選項,並且其值必須與明文的位元組長度相匹配。請參閱 CCM 模式

cipher.setAAD() 方法必須在 cipher.update() 之前呼叫。

cipher.setAutoPadding([autoPadding])#

  • autoPadding <boolean> 預設: true
  • 返回:<Cipheriv> 用於方法鏈的同一個 Cipheriv 例項。

使用分組加密演算法時,Cipheriv 類會自動將填充新增到輸入資料中,以達到適當的分組大小。要停用預設填充,請呼叫 cipher.setAutoPadding(false)

autoPaddingfalse 時,整個輸入資料的長度必須是加密演算法分組大小的倍數,否則 cipher.final() 將丟擲錯誤。停用自動填充對於非標準填充很有用,例如使用 0x0 代替 PKCS 填充。

cipher.setAutoPadding() 方法必須在 cipher.final() 之前呼叫。

cipher.update(data[, inputEncoding][, outputEncoding])#

使用 data 更新加密演算法。如果給定了 inputEncoding 引數,則 data 引數是使用指定編碼的字串。如果未給定 inputEncoding 引數,則 data 必須是 BufferTypedArrayDataView。如果 dataBufferTypedArrayDataView,則忽略 inputEncoding

outputEncoding 指定已加密資料的輸出格式。如果指定了 outputEncoding,則返回使用指定編碼的字串。如果未提供 outputEncoding,則返回 Buffer

cipher.update() 方法可以多次呼叫新資料,直到呼叫 cipher.final() 為止。在 cipher.final() 之後呼叫 cipher.update() 將導致丟擲錯誤。

類:Decipheriv#

Decipheriv 類的例項用於解密資料。該類可以透過以下兩種方式之一使用

  • 作為既可讀又可寫的 ,將普通加密資料寫入,在可讀端產生未加密資料,或者
  • 使用 decipher.update()decipher.final() 方法來產生未加密資料。

crypto.createDecipheriv() 方法用於建立 Decipheriv 例項。Decipheriv 物件不應使用 new 關鍵字直接建立。

示例:將 Decipheriv 物件用作流

import { Buffer } from 'node:buffer';
const {
  scryptSync,
  createDecipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Key length is dependent on the algorithm. In this case for aes192, it is
// 24 bytes (192 bits).
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

let decrypted = '';
decipher.on('readable', () => {
  let chunk;
  while (null !== (chunk = decipher.read())) {
    decrypted += chunk.toString('utf8');
  }
});
decipher.on('end', () => {
  console.log(decrypted);
  // Prints: some clear text data
});

// Encrypted with same algorithm, key and iv.
const encrypted =
  'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
decipher.write(encrypted, 'hex');
decipher.end();
const {
  scryptSync,
  createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Key length is dependent on the algorithm. In this case for aes192, it is
// 24 bytes (192 bits).
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

let decrypted = '';
decipher.on('readable', () => {
  let chunk;
  while (null !== (chunk = decipher.read())) {
    decrypted += chunk.toString('utf8');
  }
});
decipher.on('end', () => {
  console.log(decrypted);
  // Prints: some clear text data
});

// Encrypted with same algorithm, key and iv.
const encrypted =
  'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
decipher.write(encrypted, 'hex');
decipher.end();

示例:使用 Decipheriv 和管道流

import {
  createReadStream,
  createWriteStream,
} from 'node:fs';
import { Buffer } from 'node:buffer';
const {
  scryptSync,
  createDecipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

const input = createReadStream('test.enc');
const output = createWriteStream('test.js');

input.pipe(decipher).pipe(output);
const {
  createReadStream,
  createWriteStream,
} = require('node:fs');
const {
  scryptSync,
  createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

const input = createReadStream('test.enc');
const output = createWriteStream('test.js');

input.pipe(decipher).pipe(output);

示例:使用 decipher.update()decipher.final() 方法

import { Buffer } from 'node:buffer';
const {
  scryptSync,
  createDecipheriv,
} = await import('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

// Encrypted using same algorithm, key and iv.
const encrypted =
  'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data
const {
  scryptSync,
  createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

// Encrypted using same algorithm, key and iv.
const encrypted =
  'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data

decipher.final([outputEncoding])#

  • outputEncoding <string> 返回值的編碼
  • 返回:<Buffer> | <string> 任何剩餘的已解密內容。如果指定了 outputEncoding,則返回字串。如果未提供 outputEncoding,則返回 Buffer

一旦呼叫了 decipher.final() 方法,Decipheriv 物件就不能再用於解密資料。嘗試多次呼叫 decipher.final() 將導致丟擲錯誤。

decipher.setAAD(buffer[, options])#

使用認證加密模式時(目前支援 GCMCCMOCBchacha20-poly1305),decipher.setAAD() 方法設定用於附加認證資料 (AAD) 輸入引數的值。

對於 GCMoptions 引數是可選的。使用 CCM 時,必須指定 plaintextLength 選項,並且其值必須與密文的位元組長度相匹配。請參閱 CCM 模式

decipher.setAAD() 方法必須在 decipher.update() 之前呼叫。

將字串作為 buffer 傳遞時,請考慮將字串用作加密 API 輸入時的注意事項

decipher.setAuthTag(buffer[, encoding])#

使用認證加密模式時(目前支援 GCMCCMOCBchacha20-poly1305),decipher.setAuthTag() 方法用於傳入接收到的認證標籤。如果沒有提供標籤,或者密文被篡改,decipher.final() 將丟擲錯誤,表示由於認證失敗應丟棄密文。如果標籤長度根據 NIST SP 800-38D 無效,或者與 authTagLength 選項的值不匹配,decipher.setAuthTag() 將丟擲錯誤。

對於 CCM 模式,decipher.setAuthTag() 方法必須在 decipher.update() 之前呼叫;對於 GCMOCB 模式以及 chacha20-poly1305,必須在 decipher.final() 之前呼叫。decipher.setAuthTag() 只能呼叫一次。

將字串作為認證標籤傳遞時,請考慮將字串用作加密 API 輸入時的注意事項

decipher.setAutoPadding([autoPadding])#

當資料在沒有標準分組填充的情況下加密時,呼叫 decipher.setAutoPadding(false) 將停用自動填充,以防止 decipher.final() 檢查並刪除填充。

關閉自動填充僅在輸入資料的長度是加密演算法分組大小的倍數時才有效。

decipher.setAutoPadding() 方法必須在 decipher.final() 之前呼叫。

decipher.update(data[, inputEncoding][, outputEncoding])#

使用 data 更新解密演算法。如果給定了 inputEncoding 引數,則 data 引數是使用指定編碼的字串。如果未給定 inputEncoding 引數,則 data 必須是 Buffer。如果 dataBuffer,則忽略 inputEncoding

outputEncoding 指定已加密資料的輸出格式。如果指定了 outputEncoding,則返回使用指定編碼的字串。如果未提供 outputEncoding,則返回 Buffer

decipher.update() 方法可以多次呼叫新資料,直到呼叫 decipher.final() 為止。在 decipher.final() 之後呼叫 decipher.update() 將導致丟擲錯誤。

即使底層加密演算法實現了認證,從此函式返回的明文的真實性和完整性此時也可能不確定。對於認證加密演算法,真實性通常僅在應用程式呼叫 decipher.final() 時確立。

類:DiffieHellman#

DiffieHellman 類是用於建立 Diffie-Hellman 金鑰交換的工具。

可以使用 crypto.createDiffieHellman() 函式建立 DiffieHellman 類的例項。

import assert from 'node:assert';

const {
  createDiffieHellman,
} = await import('node:crypto');

// Generate Alice's keys...
const alice = createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
const assert = require('node:assert');

const {
  createDiffieHellman,
} = require('node:crypto');

// Generate Alice's keys...
const alice = createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));

diffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])#

使用 otherPublicKey 作為對方的公鑰計算共享金鑰,並返回計算出的共享金鑰。所提供的金鑰使用指定的 inputEncoding 進行解釋,並且金鑰使用指定的 outputEncoding 進行編碼。如果未提供 inputEncoding,則期望 otherPublicKeyBufferTypedArrayDataView

如果給定了 outputEncoding,則返回字串;否則,返回 Buffer

diffieHellman.generateKeys([encoding])#

生成私有和公共 Diffie-Hellman 金鑰值(除非它們已經生成或計算過),並以指定的 encoding 返回公鑰。此金鑰應傳輸給對方。如果提供了 encoding,則返回字串;否則返回 Buffer

此函式是 DH_generate_key() 的一個精簡包裝器。特別是,一旦生成或設定了私鑰,呼叫此函式僅更新公鑰,但不會生成新的私鑰。

diffieHellman.getGenerator([encoding])#

以指定的 encoding 返回 Diffie-Hellman 生成器。如果提供了 encoding,則返回字串;否則返回 Buffer

diffieHellman.getPrime([encoding])#

以指定的 encoding 返回 Diffie-Hellman 素數。如果提供了 encoding,則返回字串;否則返回 Buffer

diffieHellman.getPrivateKey([encoding])#

以指定的 encoding 返回 Diffie-Hellman 私鑰。如果提供了 encoding,則返回字串;否則返回 Buffer

diffieHellman.getPublicKey([encoding])#

以指定的 encoding 返回 Diffie-Hellman 公鑰。如果提供了 encoding,則返回字串;否則返回 Buffer

diffieHellman.setPrivateKey(privateKey[, encoding])#

設定 Diffie-Hellman 私鑰。如果提供了 encoding 引數,則期望 privateKey 為字串。如果沒有提供 encoding,則期望 privateKeyBufferTypedArrayDataView

此函式不會自動計算關聯的公鑰。可以使用 diffieHellman.setPublicKey()diffieHellman.generateKeys() 來手動提供公鑰或自動推導它。

diffieHellman.setPublicKey(publicKey[, encoding])#

設定 Diffie-Hellman 公鑰。如果提供了 encoding 引數,則期望 publicKey 為字串。如果沒有提供 encoding,則期望 publicKeyBufferTypedArrayDataView

diffieHellman.verifyError#

一個位域,包含在初始化 DiffieHellman 物件期間執行的檢查所導致的任何警告和/或錯誤。

以下值對於此屬性有效(定義在 node:constants 模組中)

  • DH_CHECK_P_NOT_SAFE_PRIME
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

類:DiffieHellmanGroup#

DiffieHellmanGroup 類將眾所周知的 modp 組作為其引數。它的工作方式與 DiffieHellman 相同,不同之處在於它不允許在建立後更改其金鑰。換句話說,它不實現 setPublicKey()setPrivateKey() 方法。

const { createDiffieHellmanGroup } = await import('node:crypto');
const dh = createDiffieHellmanGroup('modp16');
const { createDiffieHellmanGroup } = require('node:crypto');
const dh = createDiffieHellmanGroup('modp16');

支援以下組

  • 'modp14' (2048 位,RFC 3526 第 3 節)
  • 'modp15' (3072 位,RFC 3526 第 4 節)
  • 'modp16' (4096 位,RFC 3526 第 5 節)
  • 'modp17' (6144 位,RFC 3526 第 6 節)
  • 'modp18' (8192 位,RFC 3526 第 7 節)

以下組仍受支援但已棄用(請參閱注意事項

  • 'modp1' (768 位,RFC 2409 第 6.1 節)
  • 'modp2' (1024 位,RFC 2409 第 6.2 節)
  • 'modp5' (1536 位,RFC 3526 第 2 節)

這些已棄用的組可能會在 Node.js 的未來版本中刪除。

類:ECDH#

ECDH 類是用於建立橢圓曲線 Diffie-Hellman (ECDH) 金鑰交換的工具。

可以使用 crypto.createECDH() 函式建立 ECDH 類的例項。

import assert from 'node:assert';

const {
  createECDH,
} = await import('node:crypto');

// Generate Alice's keys...
const alice = createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
const bob = createECDH('secp521r1');
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
// OK
const assert = require('node:assert');

const {
  createECDH,
} = require('node:crypto');

// Generate Alice's keys...
const alice = createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
const bob = createECDH('secp521r1');
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
// OK

靜態方法:ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]])#

將由 keycurve 指定的 EC Diffie-Hellman 公鑰轉換為由 format 指定的格式。format 引數指定點編碼,可以是 'compressed''uncompressed''hybrid'。所提供的金鑰使用指定的 inputEncoding 進行解釋,並且返回的金鑰使用指定的 outputEncoding 進行編碼。

使用 crypto.getCurves() 獲取可用曲線名稱列表。在較新的 OpenSSL 發行版中,openssl ecparam -list_curves 也會顯示每條可用橢圓曲線的名稱和描述。

如果未指定 format,則點將以 'uncompressed' 格式返回。

如果未提供 inputEncoding,則期望 keyBufferTypedArrayDataView

示例(解壓縮金鑰)

const {
  createECDH,
  ECDH,
} = await import('node:crypto');

const ecdh = createECDH('secp256k1');
ecdh.generateKeys();

const compressedKey = ecdh.getPublicKey('hex', 'compressed');

const uncompressedKey = ECDH.convertKey(compressedKey,
                                        'secp256k1',
                                        'hex',
                                        'hex',
                                        'uncompressed');

// The converted key and the uncompressed public key should be the same
console.log(uncompressedKey === ecdh.getPublicKey('hex'));
const {
  createECDH,
  ECDH,
} = require('node:crypto');

const ecdh = createECDH('secp256k1');
ecdh.generateKeys();

const compressedKey = ecdh.getPublicKey('hex', 'compressed');

const uncompressedKey = ECDH.convertKey(compressedKey,
                                        'secp256k1',
                                        'hex',
                                        'hex',
                                        'uncompressed');

// The converted key and the uncompressed public key should be the same
console.log(uncompressedKey === ecdh.getPublicKey('hex'));

ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])#

使用 otherPublicKey 作為對方的公鑰計算共享金鑰,並返回計算出的共享金鑰。所提供的金鑰使用指定的 inputEncoding 進行解釋,並且返回的金鑰使用指定的 outputEncoding 進行編碼。如果未提供 inputEncoding,則期望 otherPublicKeyBufferTypedArrayDataView

如果給定了 outputEncoding,則返回字串;否則返回 Buffer

otherPublicKey 位於橢圓曲線之外時,ecdh.computeSecret 將丟擲 ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY 錯誤。由於 otherPublicKey 通常是從遠端使用者透過不安全網路提供的,請務必相應地處理此異常。

ecdh.generateKeys([encoding[, format]])#

生成私有和公共 EC Diffie-Hellman 金鑰值,並以指定的 formatencoding 返回公鑰。此金鑰應傳輸給對方。

format 引數指定點編碼,可以是 'compressed''uncompressed'。如果未指定 format,則點將以 'uncompressed' 格式返回。

如果提供了 encoding,則返回字串;否則返回 Buffer

ecdh.getPrivateKey([encoding])#

如果指定了 encoding,則返回字串;否則返回 Buffer

ecdh.getPublicKey([encoding][, format])#

format 引數指定點編碼,可以是 'compressed''uncompressed'。如果未指定 format,則點將以 'uncompressed' 格式返回。

如果指定了 encoding,則返回字串;否則返回 Buffer

ecdh.setPrivateKey(privateKey[, encoding])#

設定 EC Diffie-Hellman 私鑰。如果提供了 encoding,則期望 privateKey 為字串;否則期望 privateKeyBufferTypedArrayDataView

如果 privateKey 對於建立 ECDH 物件時指定的曲線無效,則丟擲錯誤。設定私鑰後,關聯的公點(金鑰)也會生成並設定在 ECDH 物件中。

ecdh.setPublicKey(publicKey[, encoding])#

類:Hash#

Hash 類是用於建立資料雜湊摘要的工具。它可以透過以下兩種方式之一使用

  • 作為既可讀又可寫的 ,將資料寫入,在可讀端產生計算出的雜湊摘要,或者
  • 使用 hash.update()hash.digest() 方法來產生計算出的雜湊。

crypto.createHash() 方法用於建立 Hash 例項。Hash 物件不應使用 new 關鍵字直接建立。

示例:將 Hash 物件用作流

const {
  createHash,
} = await import('node:crypto');

const hash = createHash('sha256');

hash.on('readable', () => {
  // Only one element is going to be produced by the
  // hash stream.
  const data = hash.read();
  if (data) {
    console.log(data.toString('hex'));
    // Prints:
    //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
  }
});

hash.write('some data to hash');
hash.end();
const {
  createHash,
} = require('node:crypto');

const hash = createHash('sha256');

hash.on('readable', () => {
  // Only one element is going to be produced by the
  // hash stream.
  const data = hash.read();
  if (data) {
    console.log(data.toString('hex'));
    // Prints:
    //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
  }
});

hash.write('some data to hash');
hash.end();

示例:使用 Hash 和管道流

import { createReadStream } from 'node:fs';
import { stdout } from 'node:process';
const { createHash } = await import('node:crypto');

const hash = createHash('sha256');

const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(stdout);
const { createReadStream } = require('node:fs');
const { createHash } = require('node:crypto');
const { stdout } = require('node:process');

const hash = createHash('sha256');

const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(stdout);

示例:使用 hash.update()hash.digest() 方法

const {
  createHash,
} = await import('node:crypto');

const hash = createHash('sha256');

hash.update('some data to hash');
console.log(hash.digest('hex'));
// Prints:
//   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
const {
  createHash,
} = require('node:crypto');

const hash = createHash('sha256');

hash.update('some data to hash');
console.log(hash.digest('hex'));
// Prints:
//   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50

hash.copy([options])#

建立一個包含當前 Hash 物件內部狀態深複製的新 Hash 物件。

可選的 options 引數控制流行為。對於 XOF 雜湊函式(例如 'shake256'),可以使用 outputLength 選項指定所需的位元組輸出長度。

當在呼叫 Hash 物件的 hash.digest() 方法後嘗試複製它時,會丟擲錯誤。

// Calculate a rolling hash.
const {
  createHash,
} = await import('node:crypto');

const hash = createHash('sha256');

hash.update('one');
console.log(hash.copy().digest('hex'));

hash.update('two');
console.log(hash.copy().digest('hex'));

hash.update('three');
console.log(hash.copy().digest('hex'));

// Etc.
// Calculate a rolling hash.
const {
  createHash,
} = require('node:crypto');

const hash = createHash('sha256');

hash.update('one');
console.log(hash.copy().digest('hex'));

hash.update('two');
console.log(hash.copy().digest('hex'));

hash.update('three');
console.log(hash.copy().digest('hex'));

// Etc.

hash.digest([encoding])#

計算所有已透過(使用 hash.update() 方法)傳遞的雜湊資料的摘要。如果提供了 encoding,則返回字串;否則返回 Buffer

在呼叫 hash.digest() 方法後,Hash 物件不能再使用。多次呼叫將導致丟擲錯誤。

hash.update(data[, inputEncoding])#

使用給定的 data 更新雜湊內容,其編碼在 inputEncoding 中給出。如果未提供 encodingdata 為字串,則強制使用 'utf8' 編碼。如果 dataBufferTypedArrayDataView,則忽略 inputEncoding

這可以隨著資料的流式傳輸多次呼叫新資料。

類:Hmac#

Hmac 類是用於建立加密 HMAC 摘要的工具。它可以透過以下兩種方式之一使用

  • 作為既可讀又可寫的 ,將資料寫入,在可讀端產生計算出的 HMAC 摘要,或者
  • 使用 hmac.update()hmac.digest() 方法來產生計算出的 HMAC 摘要。

crypto.createHmac() 方法用於建立 Hmac 例項。Hmac 物件不應使用 new 關鍵字直接建立。

示例:將 Hmac 物件用作流

const {
  createHmac,
} = await import('node:crypto');

const hmac = createHmac('sha256', 'a secret');

hmac.on('readable', () => {
  // Only one element is going to be produced by the
  // hash stream.
  const data = hmac.read();
  if (data) {
    console.log(data.toString('hex'));
    // Prints:
    //   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
  }
});

hmac.write('some data to hash');
hmac.end();
const {
  createHmac,
} = require('node:crypto');

const hmac = createHmac('sha256', 'a secret');

hmac.on('readable', () => {
  // Only one element is going to be produced by the
  // hash stream.
  const data = hmac.read();
  if (data) {
    console.log(data.toString('hex'));
    // Prints:
    //   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
  }
});

hmac.write('some data to hash');
hmac.end();

示例:使用 Hmac 和管道流

import { createReadStream } from 'node:fs';
import { stdout } from 'node:process';
const {
  createHmac,
} = await import('node:crypto');

const hmac = createHmac('sha256', 'a secret');

const input = createReadStream('test.js');
input.pipe(hmac).pipe(stdout);
const {
  createReadStream,
} = require('node:fs');
const {
  createHmac,
} = require('node:crypto');
const { stdout } = require('node:process');

const hmac = createHmac('sha256', 'a secret');

const input = createReadStream('test.js');
input.pipe(hmac).pipe(stdout);

示例:使用 hmac.update()hmac.digest() 方法

const {
  createHmac,
} = await import('node:crypto');

const hmac = createHmac('sha256', 'a secret');

hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// Prints:
//   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
const {
  createHmac,
} = require('node:crypto');

const hmac = createHmac('sha256', 'a secret');

hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// Prints:
//   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e

hmac.digest([encoding])#

計算所有已透過 hmac.update() 傳遞的資料的 HMAC 摘要。如果提供了 encoding,則返回字串;否則返回 Buffer

在呼叫 hmac.digest() 後,Hmac 物件不能再使用。多次呼叫 hmac.digest() 將導致丟擲錯誤。

hmac.update(data[, inputEncoding])#

使用給定的 data 更新 Hmac 內容,其編碼在 inputEncoding 中給出。如果未提供 encodingdata 為字串,則強制使用 'utf8' 編碼。如果 dataBufferTypedArrayDataView,則忽略 inputEncoding

這可以隨著資料的流式傳輸多次呼叫新資料。

類:KeyObject#

Node.js 使用 KeyObject 類來表示對稱或非對稱金鑰,每種型別的金鑰都會公開不同的功能。crypto.createSecretKey()crypto.createPublicKey()crypto.createPrivateKey() 方法用於建立 KeyObject 例項。KeyObject 物件不應使用 new 關鍵字直接建立。

由於改進的安全功能,大多數應用程式應考慮使用新的 KeyObject API,而不是將金鑰作為字串或 Buffer 傳遞。

KeyObject 例項可以透過 postMessage() 傳遞給其他執行緒。接收方將獲得一個克隆的 KeyObject,並且不需要在 transferList 引數中列出 KeyObject

靜態方法:KeyObject.from(key)#

返回 <CryptoKey> 的底層 <KeyObject>。返回的 <KeyObject> 不保留 Web Crypto API 對原始 <CryptoKey> 施加的任何限制,例如允許的金鑰用法、演算法或雜湊演算法繫結以及可提取性標誌。特別是,返回的 <KeyObject> 的底層金鑰材料始終可以匯出。

const { KeyObject } = await import('node:crypto');
const { subtle } = globalThis.crypto;

const key = await subtle.generateKey({
  name: 'HMAC',
  hash: 'SHA-256',
  length: 256,
}, true, ['sign', 'verify']);

const keyObject = KeyObject.from(key);
console.log(keyObject.symmetricKeySize);
// Prints: 32 (symmetric key size in bytes)
const { KeyObject } = require('node:crypto');
const { subtle } = globalThis.crypto;

(async function() {
  const key = await subtle.generateKey({
    name: 'HMAC',
    hash: 'SHA-256',
    length: 256,
  }, true, ['sign', 'verify']);

  const keyObject = KeyObject.from(key);
  console.log(keyObject.symmetricKeySize);
  // Prints: 32 (symmetric key size in bytes)
})();

keyObject.asymmetricKeyDetails#

  • 型別:<Object>
  • modulusLength <number> 位為單位的金鑰大小 (RSA, DSA)。
  • publicExponent <bigint> 公共指數 (RSA)。
  • hashAlgorithm <string> 訊息摘要的名稱 (RSA-PSS)。
  • mgf1HashAlgorithm <string> MGF1 使用的訊息摘要的名稱 (RSA-PSS)。
  • saltLength <number> 最小鹽長度(位元組)(RSA-PSS)。
  • divisorLength <number> 位為單位的 q 大小 (DSA)。
  • namedCurve <string> 曲線名稱 (EC)。

此屬性僅存在於非對稱金鑰上。根據金鑰型別的不同,此物件包含有關金鑰的資訊。透過此屬性獲得的任何資訊都不能用於唯一識別金鑰或損害金鑰的安全性。

對於 RSA-PSS 金鑰,如果金鑰材料包含 RSASSA-PSS-params 序列,則將設定 hashAlgorithmmgf1HashAlgorithmsaltLength 屬性。

其他金鑰詳細資訊可能會透過使用額外屬性的此 API 公開。

keyObject.asymmetricKeyType#

對於非對稱金鑰,此屬性表示金鑰的型別。請參閱支援的非對稱金鑰型別

此屬性對於不可識別的 KeyObject 型別和對稱金鑰為 undefined

keyObject.equals(otherKeyObject)#

返回 truefalse,具體取決於金鑰是否具有完全相同的型別、值和引數。此方法不是恆定時間的。

keyObject.export([options])#

對於對稱金鑰,可以使用以下編碼選項

  • format <string> 必須為 'buffer'(預設)或 'jwk'

對於公鑰,可以使用以下編碼選項

  • format <string> 必須為 'pem''der''jwk''raw-public'。有關格式支援,請參閱非對稱金鑰型別
  • type <string>format'pem''der' 時,必須為 'pkcs1'(僅限 RSA)或 'spki'。對於採用 'raw-public' 格式的 EC 金鑰,可以是 'uncompressed'(預設)或 'compressed'。當 format'jwk' 時忽略。

對於私鑰,可以使用以下編碼選項

  • format <string> 必須為 'pem''der''jwk''raw-private''raw-seed'。有關格式支援,請參閱非對稱金鑰型別
  • type <string>format'pem''der' 時,必須為 'pkcs1'(僅限 RSA)、'pkcs8''sec1'(僅限 EC)。當 format'jwk''raw-private''raw-seed' 時忽略。
  • cipher <string> 如果指定,私鑰將使用指定的 cipherpassphrase 透過 PKCS#5 v2.0 基於密碼的加密進行加密。當 format'jwk''raw-private''raw-seed' 時忽略。
  • passphrase <string> | <Buffer> 用於加密的密碼。當指定了 cipher 時是必須的。

結果型別取決於所選的編碼格式,當為 PEM 時結果為字串,當為 DER 時它將是一個包含編碼為 DER 的資料的緩衝區,當為 JWK 時它將是一個物件。原始格式返回一個包含原始金鑰材料的 <Buffer>

私鑰可以透過指定 cipherpassphrase 進行加密。PKCS#8 type 支援對任何金鑰演算法的 PEM 和 DER format 進行加密。PKCS#1 和 SEC1 僅在使用 PEM format 時才能加密。為了獲得最大的相容性,請對加密的私鑰使用 PKCS#8。由於 PKCS#8 定義了自己的加密機制,因此在加密 PKCS#8 金鑰時不支援 PEM 級別的加密。請參閱 RFC 5208 獲取 PKCS#8 加密,以及 RFC 1421 獲取 PKCS#1 和 SEC1 加密。

keyObject.symmetricKeySize#

對於金鑰,此屬性表示以位元組為單位的金鑰大小。對於非對稱金鑰,此屬性為 undefined

keyObject.toCryptoKey(algorithm, extractable, keyUsages)#

KeyObject 例項轉換為 CryptoKey

keyObject.type#

根據此 KeyObject 的型別,此屬性要麼是用於秘密(對稱)金鑰的 'secret',用於公鑰(非對稱)金鑰的 'public',要麼是用於私鑰(非對稱)金鑰的 'private'

類:Sign#

Sign 類是用於生成簽名的工具。它可以透過以下兩種方式之一使用

crypto.createSign() 方法用於建立 Sign 例項。引數是要使用的雜湊函式的字串名稱。Sign 物件不應使用 new 關鍵字直接建立。

示例:將 SignVerify 物件用作流

const {
  generateKeyPairSync,
  createSign,
  createVerify,
} = await import('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
});

const sign = createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex'));
// Prints: true
const {
  generateKeyPairSync,
  createSign,
  createVerify,
} = require('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
});

const sign = createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex'));
// Prints: true

示例:使用 sign.update()verify.update() 方法

const {
  generateKeyPairSync,
  createSign,
  createVerify,
} = await import('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

const sign = createSign('SHA256');
sign.update('some data to sign');
sign.end();
const signature = sign.sign(privateKey);

const verify = createVerify('SHA256');
verify.update('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature));
// Prints: true
const {
  generateKeyPairSync,
  createSign,
  createVerify,
} = require('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

const sign = createSign('SHA256');
sign.update('some data to sign');
sign.end();
const signature = sign.sign(privateKey);

const verify = createVerify('SHA256');
verify.update('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature));
// Prints: true

sign.sign(privateKey[, outputEncoding])#

  • outputEncoding <string> 返回值的編碼
  • 返回:<Buffer> | <string>
  • 計算所有透過 sign.update()sign.write() 傳遞的資料的簽名。

    如果 privateKey 不是 KeyObject,則此函式的行為就像將 privateKey 傳遞給了 crypto.createPrivateKey() 一樣。如果它是一個物件,則可以傳遞以下附加屬性

    • dsaEncoding <string> 對於 DSA 和 ECDSA,此選項指定生成的簽名的格式。它可以是以下之一

      • 'der'(預設):對 (r, s) 進行編碼的 DER 編碼 ASN.1 簽名結構。
      • 'ieee-p1363':IEEE-P1363 中提出的簽名格式 r || s
    • padding <integer> RSA 的可選填充值,為以下之一

      • crypto.constants.RSA_PKCS1_PADDING(預設)
      • crypto.constants.RSA_PKCS1_PSS_PADDING

      RSA_PKCS1_PSS_PADDING 將使用 MGF1 以及與簽名訊息時所使用的相同的雜湊函式(如 RFC 4055 第 3.1 節所述),除非作為金鑰的一部分明確指定了 MGF1 雜湊函式(符合 RFC 4055 第 3.3 節的規定)。

    • saltLength <integer> 當填充方式為 RSA_PKCS1_PSS_PADDING 時的鹽值長度。特殊值 crypto.constants.RSA_PSS_SALTLEN_DIGEST 將鹽值長度設定為摘要大小,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(預設值)將其設定為允許的最大值。

    如果提供了 outputEncoding,則返回一個字串;否則返回一個 Buffer

    Sign 物件在呼叫 sign.sign() 方法後不能再次使用。多次呼叫 sign.sign() 將導致丟擲錯誤。

    sign.update(data[, inputEncoding])#

    使用給定的 data 更新 Sign 內容,其編碼方式由 inputEncoding 指定。如果未提供 encodingdata 為字串,則強制使用 'utf8' 編碼。如果 dataBufferTypedArrayDataView,則忽略 inputEncoding

    這可以隨著資料的流式傳輸多次呼叫新資料。

    類:Verify#

    Verify 類是用於驗證簽名的工具。它可以透過以下兩種方式之一使用:

    crypto.createVerify() 方法用於建立 Verify 例項。不應直接使用 new 關鍵字建立 Verify 物件。

    示例請參見 Sign

    verify.update(data[, inputEncoding])#

    使用給定的 data 更新 Verify 內容,其編碼方式由 inputEncoding 指定。如果未提供 inputEncodingdata 為字串,則強制使用 'utf8' 編碼。如果 dataBufferTypedArrayDataView,則忽略 inputEncoding

    這可以隨著資料的流式傳輸多次呼叫新資料。

    verify.verify(object, signature[, signatureEncoding])#

    使用給定的 objectsignature 驗證提供的資料。

    如果 object 不是 KeyObject,則此函式行為如同將 object 傳遞給 crypto.createPublicKey() 一樣。如果是物件,則可以傳遞以下附加屬性:

    • dsaEncoding <string> 對於 DSA 和 ECDSA,此選項指定簽名的格式。它可以是以下值之一:

      • 'der'(預設):對 (r, s) 進行編碼的 DER 編碼 ASN.1 簽名結構。
      • 'ieee-p1363':IEEE-P1363 中提出的簽名格式 r || s
    • padding <integer> RSA 的可選填充值,為以下之一

      • crypto.constants.RSA_PKCS1_PADDING(預設)
      • crypto.constants.RSA_PKCS1_PSS_PADDING

      RSA_PKCS1_PSS_PADDING 將使用 MGF1 以及與驗證訊息時所使用的相同的雜湊函式(如 RFC 4055 第 3.1 節所述),除非作為金鑰的一部分明確指定了 MGF1 雜湊函式(符合 RFC 4055 第 3.3 節的規定)。

    • saltLength <integer> 當填充方式為 RSA_PKCS1_PSS_PADDING 時的鹽值長度。特殊值 crypto.constants.RSA_PSS_SALTLEN_DIGEST 將鹽值長度設定為摘要大小,crypto.constants.RSA_PSS_SALTLEN_AUTO(預設值)使其自動確定。

    signature 引數是之前針對資料計算出的簽名,採用 signatureEncoding 編碼。如果指定了 signatureEncoding,則預期 signature 為字串;否則預期 signatureBufferTypedArrayDataView

    verify 物件在呼叫 verify.verify() 後不能再次使用。多次呼叫 verify.verify() 將導致丟擲錯誤。

    因為公鑰可以從私鑰匯出,所以可以使用私鑰代替公鑰。

    類:X509Certificate#

    封裝 X509 證書並提供對其資訊的只讀訪問許可權。

    const { X509Certificate } = await import('node:crypto');
    
    const x509 = new X509Certificate('{... pem encoded cert ...}');
    
    console.log(x509.subject);
    const { X509Certificate } = require('node:crypto');
    
    const x509 = new X509Certificate('{... pem encoded cert ...}');
    
    console.log(x509.subject);
    

    new X509Certificate(buffer)#

    x509.ca#

    • 型別:<boolean> 如果這是證書頒發機構 (CA) 證書,則為 true

    x509.checkEmail(email[, options])#

  • 返回:<string> | <undefined> 如果證書匹配,則返回 email;如果不匹配,則返回 undefined
  • 檢查證書是否與給定的電子郵件地址匹配。

    如果 'subject' 選項未定義或設定為 'default',則僅在主體備用名稱擴充套件不存在或不包含任何電子郵件地址時,才會考慮證書主體。

    如果 'subject' 選項設定為 'always',且主體備用名稱擴充套件不存在或不包含匹配的電子郵件地址,則會考慮證書主體。

    如果 'subject' 選項設定為 'never',則即使證書不包含主體備用名稱,也不會考慮證書主體。

    x509.checkHost(name[, options])#

    • name <string>
    • options <Object>
    • subject <string> 'default''always''never'預設值: 'default'
    • wildcards <boolean> 預設值: true
    • partialWildcards <boolean> 預設值: true
    • multiLabelWildcards <boolean> 預設值: false
    • singleLabelSubdomains <boolean> 預設值: false
  • 返回:<string> | <undefined> 返回與 name 匹配的主體名稱,如果沒有匹配的主體名稱,則返回 undefined
  • 檢查證書是否與給定的主機名匹配。

    如果證書與給定的主機名匹配,則返回匹配的主體名稱。返回的名稱可能是精確匹配(例如 foo.example.com),也可能包含萬用字元(例如 *.example.com)。由於主機名比較不區分大小寫,返回的主體名稱在大小寫上可能與給定的 name 不同。

    如果 'subject' 選項未定義或設定為 'default',則僅在主體備用名稱擴充套件不存在或不包含任何 DNS 名稱時,才會考慮證書主體。此行為與 RFC 2818(“HTTP Over TLS”)一致。

    如果 'subject' 選項設定為 'always',且主體備用名稱擴充套件不存在或不包含匹配的 DNS 名稱,則會考慮證書主體。

    如果 'subject' 選項設定為 'never',則即使證書不包含主體備用名稱,也不會考慮證書主體。

    x509.checkIP(ip)#

    檢查證書是否與給定的 IP 地址(IPv4 或 IPv6)匹配。

    僅考慮 RFC 5280 iPAddress 主體備用名稱,並且它們必須與給定的 ip 地址完全匹配。其他主體備用名稱以及證書的主體欄位將被忽略。

    x509.checkIssued(otherCert)#

    透過比較證書元資料,檢查該證書是否可能由給定的 otherCert 簽發。

    這對於修剪已使用更基礎過濾程式(即僅基於主體和頒發者名稱)選擇的可能頒發者證書列表很有用。

    最後,要驗證該證書的簽名是否由對應於 otherCert 公鑰的私鑰生成,請使用 x509.verify(publicKey),並將 otherCert 的公鑰表示為 KeyObject,如下所示:

    if (!x509.verify(otherCert.publicKey)) {
      throw new Error('otherCert did not issue x509');
    }
    

    x509.checkPrivateKey(privateKey)#

    檢查該證書的公鑰是否與給定的私鑰一致。

    x509.fingerprint#

    該證書的 SHA-1 指紋。

    由於 SHA-1 在密碼學上已被破解,並且其安全性明顯低於通常用於簽署證書的演算法,請考慮使用 x509.fingerprint256 代替。

    x509.fingerprint256#

    該證書的 SHA-256 指紋。

    x509.fingerprint512#

    該證書的 SHA-512 指紋。

    因為計算 SHA-256 指紋通常更快,並且它只有 SHA-512 指紋大小的一半,所以 x509.fingerprint256 可能是更好的選擇。雖然 SHA-512 總的來說提供了更高的安全性,但 SHA-256 的安全性與大多數常用於簽署證書的演算法相當。

    x509.infoAccess#

    證書授權資訊訪問擴充套件的文字表示。

    這是一個以換行符分隔的訪問描述列表。每一行以訪問方法和訪問位置型別開頭,後跟冒號以及與訪問位置關聯的值。

    在表示訪問方法和訪問位置型別的字首之後,每一行的其餘部分可能會被引號括起來,以指示該值是一個 JSON 字串字面量。為了向後相容,Node.js 僅在必要時才在此屬性中使用 JSON 字串字面量以避免歧義。第三方程式碼應準備好處理兩種可能的條目格式。

    x509.issuer#

    此證書中包含的頒發者標識。

    x509.issuerCertificate#

    頒發者證書;如果頒發者證書不可用,則返回 undefined

    x509.keyUsage#

    詳細說明此證書金鑰擴充套件用法的陣列。

    x509.publicKey#

    此證書的公鑰 <KeyObject>

    x509.raw#

    包含此證書 DER 編碼的 Buffer

    x509.serialNumber#

    此證書的序列號。

    序列號由證書頒發機構分配,不能唯一標識證書。請考慮改用 x509.fingerprint256 作為唯一識別符號。

    x509.subject#

    此證書的完整主體。

    x509.subjectAltName#

    為此證書指定的主體備用名稱。

    這是一個以逗號分隔的主體備用名稱列表。每個條目以標識主體備用名稱型別的字串開頭,後跟冒號以及與該條目關聯的值。

    早期版本的 Node.js 錯誤地認為在雙字元序列 ', ' 處分割此屬性是安全的(參見 CVE-2021-44532)。然而,惡意和合法的證書都可以包含在作為字串表示時包含此序列的主體備用名稱。

    在表示條目型別的字首之後,每個條目的其餘部分可能會被引號括起來,以指示該值是一個 JSON 字串字面量。為了向後相容,Node.js 僅在必要時才在此屬性中使用 JSON 字串字面量以避免歧義。第三方程式碼應準備好處理兩種可能的條目格式。

    x509.toJSON()#

    X509 證書沒有標準的 JSON 編碼。toJSON() 方法返回一個包含 PEM 編碼證書的字串。

    x509.toLegacyObject()#

    使用傳統的 證書物件 編碼返回有關此證書的資訊。

    x509.toString()#

    返回 PEM 編碼的證書。

    x509.validFrom#

    此證書開始有效的日期/時間。

    x509.validFromDate#

    此證書開始有效的日期/時間,封裝在 Date 物件中。

    x509.validTo#

    此證書有效的截止日期/時間。

    x509.validToDate#

    此證書有效的截止日期/時間,封裝在 Date 物件中。

    x509.signatureAlgorithm#

    用於簽署證書的演算法,如果 OpenSSL 不知道該簽名演算法,則為 undefined

    x509.signatureAlgorithmOid#

    用於簽署證書的演算法的 OID。

    x509.verify(publicKey)#

    驗證此證書是否由給定的公鑰簽署。不對證書執行任何其他驗證檢查。

    node:crypto 模組方法和屬性#

    crypto.argon2(algorithm, parameters, callback)#

    穩定性:1.2 - 候選釋出版本

    提供非同步 Argon2 實現。Argon2 是一種基於密碼的金鑰派生函式,旨在在計算和記憶體方面成本高昂,以使暴力破解攻擊變得不值得。

    nonce 應儘可能唯一。建議 nonce 是隨機的且至少 16 位元組長。詳情請參閱 NIST SP 800-132

    當為 messagenoncesecretassociatedData 傳遞字串時,請考慮 將字串用作加密 API 輸入時的注意事項

    callback 函式使用兩個引數呼叫:errderivedKey。當金鑰派生失敗時,err 是一個異常物件,否則 errnullderivedKey 作為 Buffer 傳遞給回撥。

    當任何輸入引數指定無效值或型別時,會丟擲異常。

    const { argon2, randomBytes } = await import('node:crypto');
    
    const parameters = {
      message: 'password',
      nonce: randomBytes(16),
      parallelism: 4,
      tagLength: 64,
      memory: 65536,
      passes: 3,
    };
    
    argon2('argon2id', parameters, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // 'af91dad...9520f15'
    });
    const { argon2, randomBytes } = require('node:crypto');
    
    const parameters = {
      message: 'password',
      nonce: randomBytes(16),
      parallelism: 4,
      tagLength: 64,
      memory: 65536,
      passes: 3,
    };
    
    argon2('argon2id', parameters, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // 'af91dad...9520f15'
    });
    

    crypto.argon2Sync(algorithm, parameters)#

    穩定性:1.2 - 候選釋出版本

    • algorithm <string> Argon2 的變體,為 "argon2d""argon2i""argon2id" 之一。
    • parameters <Object>
      • message <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 必需,這是 Argon2 密碼雜湊應用程式的密碼。
      • nonce <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 必需,必須至少 8 位元組長。這是 Argon2 密碼雜湊應用程式的鹽。
      • parallelism <number> 必需,並行度決定了可以執行多少個計算鏈(lane)。必須大於 1 且小於 2**24-1
      • tagLength <number> 必需,要生成的金鑰長度。必須大於 4 且小於 2**32-1
      • memory <number> 必需,以 1KiB 塊為單位的記憶體成本。必須大於 8 * parallelism 且小於 2**32-1。塊的實際數量向下舍入為 4 * parallelism 的最近倍數。
      • passes <number> 必需,遍歷次數(迭代次數)。必須大於 1 且小於 2**32-1
      • secret <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <undefined> 可選,類似於鹽的隨機附加輸入,不應與派生金鑰一起儲存。這在密碼雜湊應用程式中被稱為 pepper。如果使用,長度不得超過 2**32-1 位元組。
      • associatedData <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <undefined> 可選,要新增到雜湊中的附加資料,功能上等同於鹽或秘密,但用於非隨機資料。如果使用,長度不得超過 2**32-1 位元組。
    • 返回:<Buffer>

    提供同步 Argon2 實現。Argon2 是一種基於密碼的金鑰派生函式,旨在在計算和記憶體方面成本高昂,以使暴力破解攻擊變得不值得。

    nonce 應儘可能唯一。建議 nonce 是隨機的且至少 16 位元組長。詳情請參閱 NIST SP 800-132

    當為 messagenoncesecretassociatedData 傳遞字串時,請考慮 將字串用作加密 API 輸入時的注意事項

    當金鑰派生失敗時會丟擲異常,否則派生金鑰將作為 Buffer 返回。

    當任何輸入引數指定無效值或型別時,會丟擲異常。

    const { argon2Sync, randomBytes } = await import('node:crypto');
    
    const parameters = {
      message: 'password',
      nonce: randomBytes(16),
      parallelism: 4,
      tagLength: 64,
      memory: 65536,
      passes: 3,
    };
    
    const derivedKey = argon2Sync('argon2id', parameters);
    console.log(derivedKey.toString('hex'));  // 'af91dad...9520f15'
    const { argon2Sync, randomBytes } = require('node:crypto');
    
    const parameters = {
      message: 'password',
      nonce: randomBytes(16),
      parallelism: 4,
      tagLength: 64,
      memory: 65536,
      passes: 3,
    };
    
    const derivedKey = argon2Sync('argon2id', parameters);
    console.log(derivedKey.toString('hex'));  // 'af91dad...9520f15'
    

    crypto.checkPrime(candidate[, options], callback)#

  • callback <Function>
    • err <Error> 如果在檢查過程中發生錯誤,則設定為 <Error> 物件。
    • result <boolean> 如果候選數是素數,且錯誤機率小於 0.25 ** options.checks,則為 true
  • 檢查 candidate 的素性。

    crypto.checkPrimeSync(candidate[, options])#

  • 返回:<boolean> 如果候選數是素數,且錯誤機率小於 0.25 ** options.checks,則為 true
  • 檢查 candidate 的素性。

    crypto.constants#

    包含用於加密和安全相關操作的常用常量的物件。當前定義的具體常量在 加密常量 中有描述。

    crypto.createCipheriv(algorithm, key, iv[, options])#

    建立並返回一個 Cipheriv 物件,使用給定的 algorithmkey 和初始化向量 (iv)。

    options 引數控制流行為,並且是可選的,除非使用了 CCM 或 OCB 模式的密碼(例如 'aes-128-ccm')。在這種情況下,authTagLength 選項是必需的,並指定以位元組為單位的身份驗證標籤長度,請參閱 CCM 模式。在 GCM 模式下,authTagLength 選項不是必需的,但可用於設定將由 getAuthTag() 返回的身份驗證標籤長度,預設值為 16 位元組。對於 chacha20-poly1305authTagLength 選項預設為 16 位元組。

    algorithm 取決於 OpenSSL,例如 'aes192' 等。在較新的 OpenSSL 版本中,openssl list -cipher-algorithms 將顯示可用的密碼演算法。

    keyalgorithm 使用的原始金鑰,iv初始化向量。這兩個引數必須是 'utf8' 編碼的字串、BuffersTypedArrayDataViewkey 可選地可以是 secret 型別的 KeyObject。如果密碼不需要初始化向量,iv 可以是 null

    當為 keyiv 傳遞字串時,請考慮 將字串用作加密 API 輸入時的注意事項

    初始化向量應該是不可預測且唯一的;理想情況下,它們應該是加密隨機的。它們不需要是秘密的:IV 通常只是以未加密的方式新增到密文訊息中。某些事物必須不可預測且唯一,但不需要保密,這聽起來可能自相矛盾;請記住,攻擊者絕不能提前預測給定的 IV 是什麼。

    crypto.createDecipheriv(algorithm, key, iv[, options])#

    建立並返回一個 Decipheriv 物件,使用給定的 algorithmkey 和初始化向量 (iv)。

    options 引數控制流行為,並且是可選的,除非使用了 CCM 或 OCB 模式的密碼(例如 'aes-128-ccm')。在這種情況下,authTagLength 選項是必需的,並指定以位元組為單位的身份驗證標籤長度,請參閱 CCM 模式。對於 AES-GCM 和 chacha20-poly1305authTagLength 選項預設為 16 位元組,如果使用不同的長度,則必須將其設定為該值。

    algorithm 取決於 OpenSSL,例如 'aes192' 等。在較新的 OpenSSL 版本中,openssl list -cipher-algorithms 將顯示可用的密碼演算法。

    keyalgorithm 使用的原始金鑰,iv初始化向量。這兩個引數必須是 'utf8' 編碼的字串、BuffersTypedArrayDataViewkey 可選地可以是 secret 型別的 KeyObject。如果密碼不需要初始化向量,iv 可以是 null

    當為 keyiv 傳遞字串時,請考慮 將字串用作加密 API 輸入時的注意事項

    初始化向量應該是不可預測且唯一的;理想情況下,它們應該是加密隨機的。它們不需要是秘密的:IV 通常只是以未加密的方式新增到密文訊息中。某些事物必須不可預測且唯一,但不需要保密,這聽起來可能自相矛盾;請記住,攻擊者絕不能提前預測給定的 IV 是什麼。

    crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])#

    使用提供的 prime 和可選的特定 generator 建立 DiffieHellman 金鑰交換物件。

    generator 引數可以是數字、字串或 Buffer。如果未指定 generator,則使用值 2

    如果指定了 primeEncoding,則預期 prime 為字串;否則預期為 BufferTypedArrayDataView

    如果指定了 generatorEncoding,則預期 generator 為字串;否則預期為數字、BufferTypedArrayDataView

    crypto.createDiffieHellman(primeLength[, generator])#

    建立一個 DiffieHellman 金鑰交換物件,並使用可選的特定數字 generator 生成一個 primeLength 位的素數。如果未指定 generator,則使用值 2

    crypto.createDiffieHellmanGroup(name)#

    crypto.getDiffieHellman() 的別名。

    crypto.createECDH(curveName)#

    建立一個橢圓曲線 Diffie-Hellman (ECDH) 金鑰交換物件,使用由 curveName 字串指定的預定義曲線。使用 crypto.getCurves() 獲取可用曲線名稱的列表。在最近的 OpenSSL 版本中,openssl ecparam -list_curves 也會顯示每條可用橢圓曲線的名稱和描述。

    crypto.createHash(algorithm[, options])#

    建立並返回一個 Hash 物件,可用於使用給定的 algorithm 生成雜湊摘要。可選的 options 引數控制流行為。對於諸如 'shake256' 之類的 XOF 雜湊函式,outputLength 選項可用於指定所需的輸出長度(以位元組為單位)。

    algorithm 取決於平臺上 OpenSSL 版本所支援的可用演算法。例如 'sha256''sha512' 等。在較新的 OpenSSL 版本中,openssl list -digest-algorithms 將顯示可用的摘要演算法。

    示例:生成檔案的 sha256 和。

    import {
      createReadStream,
    } from 'node:fs';
    import { argv } from 'node:process';
    const {
      createHash,
    } = await import('node:crypto');
    
    const filename = argv[2];
    
    const hash = createHash('sha256');
    
    const input = createReadStream(filename);
    input.on('readable', () => {
      // Only one element is going to be produced by the
      // hash stream.
      const data = input.read();
      if (data)
        hash.update(data);
      else {
        console.log(`${hash.digest('hex')} ${filename}`);
      }
    });
    const {
      createReadStream,
    } = require('node:fs');
    const {
      createHash,
    } = require('node:crypto');
    const { argv } = require('node:process');
    
    const filename = argv[2];
    
    const hash = createHash('sha256');
    
    const input = createReadStream(filename);
    input.on('readable', () => {
      // Only one element is going to be produced by the
      // hash stream.
      const data = input.read();
      if (data)
        hash.update(data);
      else {
        console.log(`${hash.digest('hex')} ${filename}`);
      }
    });
    

    crypto.createHmac(algorithm, key[, options])#

    建立並返回一個 Hmac 物件,使用給定的 algorithmkey。可選的 options 引數控制流行為。

    algorithm 取決於平臺上 OpenSSL 版本所支援的可用演算法。例如 'sha256''sha512' 等。在較新的 OpenSSL 版本中,openssl list -digest-algorithms 將顯示可用的摘要演算法。

    key 是用於生成加密 HMAC 雜湊的 HMAC 金鑰。如果是 KeyObject,其型別必須是 secret。如果是字串,請考慮 將字串用作加密 API 輸入時的注意事項。如果它是從加密安全的熵源獲得的(例如 crypto.randomBytes()crypto.generateKey()),則其長度不應超過 algorithm 的塊大小(例如,SHA-256 為 512 位)。

    示例:生成檔案的 sha256 HMAC。

    import {
      createReadStream,
    } from 'node:fs';
    import { argv } from 'node:process';
    const {
      createHmac,
    } = await import('node:crypto');
    
    const filename = argv[2];
    
    const hmac = createHmac('sha256', 'a secret');
    
    const input = createReadStream(filename);
    input.on('readable', () => {
      // Only one element is going to be produced by the
      // hash stream.
      const data = input.read();
      if (data)
        hmac.update(data);
      else {
        console.log(`${hmac.digest('hex')} ${filename}`);
      }
    });
    const {
      createReadStream,
    } = require('node:fs');
    const {
      createHmac,
    } = require('node:crypto');
    const { argv } = require('node:process');
    
    const filename = argv[2];
    
    const hmac = createHmac('sha256', 'a secret');
    
    const input = createReadStream(filename);
    input.on('readable', () => {
      // Only one element is going to be produced by the
      // hash stream.
      const data = input.read();
      if (data)
        hmac.update(data);
      else {
        console.log(`${hmac.digest('hex')} ${filename}`);
      }
    });
    

    crypto.createPrivateKey(key)#

  • 返回:<KeyObject>

    建立並返回一個包含私鑰的新金鑰物件。如果 key 是字串或 Buffer,則假定 format'pem';否則,key 必須是具有上述屬性的物件。

    如果私鑰已加密,則必須指定 passphrase。密碼短語的長度限制為 1024 位元組。

  • crypto.createPublicKey(key)#

  • 返回:<KeyObject>

    建立並返回一個包含公鑰的新金鑰物件。如果 key 是字串或 Buffer,則假定 format'pem';如果 key'private' 型別的 KeyObject,則公鑰從給定的私鑰中派生;否則,key 必須是具有上述屬性的物件。

    如果格式為 'pem',則 'key' 也可以是 X.509 證書。

    因為公鑰可以從私鑰匯出,所以可以使用私鑰代替公鑰。在這種情況下,此函式的行為如同呼叫了 crypto.createPrivateKey() 一樣,只是返回的 KeyObject 型別將為 'public',並且無法從返回的 KeyObject 中提取私鑰。同樣,如果給出了 'private' 型別的 KeyObject,將返回一個型別為 'public' 的新 KeyObject,並且無法從返回的物件中提取私鑰。

  • crypto.createSecretKey(key[, encoding])#

    建立並返回一個包含對稱加密或 Hmac 金鑰的新金鑰物件。

    crypto.createSign(algorithm[, options])#

    建立並返回一個使用給定 algorithmSign 物件。使用 crypto.getHashes() 獲取可用摘要演算法的名稱。可選的 options 引數控制 stream.Writable 的行為。

    在某些情況下,可以使用簽名演算法名稱(例如 'RSA-SHA256')而不是摘要演算法來建立 Sign 例項。這將使用相應的摘要演算法。這並非適用於所有簽名演算法(例如 'ecdsa-with-SHA256'),因此最好始終使用摘要演算法名稱。

    crypto.createVerify(algorithm[, options])#

    建立並返回一個使用給定演算法的 Verify 物件。使用 crypto.getHashes() 獲取可用簽名演算法名稱的陣列。可選的 options 引數控制 stream.Writable 的行為。

    在某些情況下,可以使用簽名演算法名稱(例如 'RSA-SHA256')而不是摘要演算法來建立 Verify 例項。這將使用相應的摘要演算法。這並非適用於所有簽名演算法(例如 'ecdsa-with-SHA256'),因此最好始終使用摘要演算法名稱。

    crypto.decapsulate(key, ciphertext[, callback])#

    穩定性:1.2 - 候選釋出版本

    使用 KEM 演算法和私鑰進行金鑰解封裝。

    支援的金鑰型別及其 KEM 演算法為:

    • 'rsa'2 RSA 秘密值封裝
    • 'ec'3 DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256)
    • 'x25519'3 DHKEM(X25519, HKDF-SHA256)
    • 'x448'3 DHKEM(X448, HKDF-SHA512)
    • 'ml-kem-512'1 ML-KEM
    • 'ml-kem-768'1 ML-KEM
    • 'ml-kem-1024'1 ML-KEM

    如果 key 不是 KeyObject,則此函式行為如同將 key 傳遞給 crypto.createPrivateKey() 一樣。

    如果提供了 callback 函式,則此函式使用 libuv 的執行緒池。

    crypto.diffieHellman(options[, callback])#

  • callback <Function>
  • 返回:如果未提供 callback 函式,則返回 <Buffer>

    根據 privateKeypublicKey 計算 Diffie-Hellman 共享金鑰。兩個金鑰必須具有相同的 asymmetricKeyType,並且必須支援 DH 或 ECDH 操作。

    如果提供了 callback 函式,則此函式使用 libuv 的執行緒池。

  • crypto.encapsulate(key[, callback])#

    穩定性:1.2 - 候選釋出版本

  • 返回:如果未提供 callback 函式,則返回 <Object>
  • sharedKey <Buffer>
  • ciphertext <Buffer>
  • 使用 KEM 演算法和公鑰進行金鑰封裝。

    支援的金鑰型別及其 KEM 演算法為:

    • 'rsa'2 RSA 秘密值封裝
    • 'ec'3 DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256)
    • 'x25519'3 DHKEM(X25519, HKDF-SHA256)
    • 'x448'3 DHKEM(X448, HKDF-SHA512)
    • 'ml-kem-512'1 ML-KEM
    • 'ml-kem-768'1 ML-KEM
    • 'ml-kem-1024'1 ML-KEM

    如果 key 不是 KeyObject,則此函式行為如同將 key 傳遞給 crypto.createPublicKey() 一樣。

    如果提供了 callback 函式,則此函式使用 libuv 的執行緒池。

    crypto.fips#

    crypto.generateKey(type, options, callback)#

    • type <string> 生成的金鑰的預期用途。當前接受的值為 'hmac''aes'
    • options <Object>
    • length <number> 要生成的金鑰的位長度。必須大於 0。
    • 如果 type'hmac',最小值為 8,最大長度為 231-1。如果該值不是 8 的倍數,則生成的金鑰將被截斷為 Math.floor(length / 8)
    • 如果 type'aes',長度必須為 128192256 之一。
  • callback <Function>
  • 非同步生成給定 length 的新隨機金鑰。type 將決定對 length 執行哪些驗證。

    const {
      generateKey,
    } = await import('node:crypto');
    
    generateKey('hmac', { length: 512 }, (err, key) => {
      if (err) throw err;
      console.log(key.export().toString('hex'));  // 46e..........620
    });
    const {
      generateKey,
    } = require('node:crypto');
    
    generateKey('hmac', { length: 512 }, (err, key) => {
      if (err) throw err;
      console.log(key.export().toString('hex'));  // 46e..........620
    });
    

    生成的 HMAC 金鑰的大小不應超過底層雜湊函式的塊大小。有關詳細資訊,請參閱 crypto.createHmac()

    crypto.generateKeyPair(type, options, callback)#

  • callback <Function>
  • 生成給定 type 的新非對稱金鑰對。請參閱支援的 非對稱金鑰型別

    如果指定了 publicKeyEncodingprivateKeyEncoding,則此函式行為如同在其結果上呼叫了 keyObject.export() 一樣。否則,金鑰的相應部分將作為 KeyObject 返回。

    建議將公鑰編碼為 'spki',私鑰編碼為帶有加密的 'pkcs8' 以進行長期儲存。

    const {
      generateKeyPair,
    } = await import('node:crypto');
    
    generateKeyPair('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem',
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret',
      },
    }, (err, publicKey, privateKey) => {
      // Handle errors and use the generated key pair.
    });
    const {
      generateKeyPair,
    } = require('node:crypto');
    
    generateKeyPair('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem',
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret',
      },
    }, (err, publicKey, privateKey) => {
      // Handle errors and use the generated key pair.
    });
    

    完成後,將呼叫 callback,並將 err 設定為 undefinedpublicKey / privateKey 代表生成的金鑰對。

    如果此方法作為其 util.promisify() 版本呼叫,則返回一個 Promise,該 Promise 解析為一個具有 publicKeyprivateKey 屬性的 Object

    crypto.generateKeyPairSync(type, options)#

  • 返回:<Object>
  • publicKey <string> | <Buffer> | <KeyObject>
  • privateKey <string> | <Buffer> | <KeyObject>
  • 生成給定 type 的新非對稱金鑰對。請參閱支援的 非對稱金鑰型別

    如果指定了 publicKeyEncodingprivateKeyEncoding,則此函式行為如同在其結果上呼叫了 keyObject.export() 一樣。否則,金鑰的相應部分將作為 KeyObject 返回。

    編碼公鑰時,建議使用 'spki'。編碼私鑰時,建議使用帶有強密碼短語的 'pkcs8',並確保密碼短語保密。

    const {
      generateKeyPairSync,
    } = await import('node:crypto');
    
    const {
      publicKey,
      privateKey,
    } = generateKeyPairSync('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem',
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret',
      },
    });
    const {
      generateKeyPairSync,
    } = require('node:crypto');
    
    const {
      publicKey,
      privateKey,
    } = generateKeyPairSync('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem',
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: 'top secret',
      },
    });
    

    返回值 { publicKey, privateKey } 表示生成的金鑰對。當選擇 PEM 編碼時,相應的金鑰將為字串;否則它將是一個包含編碼為 DER 資料內容的 buffer。

    crypto.generateKeySync(type, options)#

    • type <string> 生成的金鑰的預期用途。當前接受的值為 'hmac''aes'
    • options <Object>
    • length <number> 要生成的金鑰的位長度。
    • 如果 type'hmac',最小值為 8,最大長度為 231-1。如果該值不是 8 的倍數,則生成的金鑰將被截斷為 Math.floor(length / 8)
    • 如果 type'aes',長度必須為 128192256 之一。
  • 返回:<KeyObject>

    同步生成給定 length 的新隨機金鑰。type 將決定對 length 執行哪些驗證。

    const {
      generateKeySync,
    } = await import('node:crypto');
    
    const key = generateKeySync('hmac', { length: 512 });
    console.log(key.export().toString('hex'));  // e89..........41e
    const {
      generateKeySync,
    } = require('node:crypto');
    
    const key = generateKeySync('hmac', { length: 512 });
    console.log(key.export().toString('hex'));  // e89..........41e
    

    生成的 HMAC 金鑰的大小不應超過底層雜湊函式的塊大小。有關詳細資訊,請參閱 crypto.createHmac()

  • crypto.generatePrime(size[, options], callback)#

  • callback <Function>
  • 生成一個 size 位的偽隨機素數。

    如果 options.safetrue,則素數將是一個安全素數——即 (prime - 1) / 2 也將是一個素數。

    options.addoptions.rem 引數可用於強制執行附加要求,例如用於 Diffie-Hellman。

    • 如果設定了 options.addoptions.rem,則素數將滿足 prime % add = rem 的條件。
    • 如果僅設定了 options.addoptions.safe 不為 true,則素數將滿足 prime % add = 1 的條件。
    • 如果僅設定了 options.addoptions.safe 設定為 true,則素數將滿足 prime % add = 3 的條件。這是必要的,因為 options.add > 2prime % add = 1 會與 options.safe 強制執行的條件相矛盾。
    • 如果未給出 options.add,則忽略 options.rem

    如果以 ArrayBufferSharedArrayBufferTypedArrayBufferDataView 形式給出,則 options.addoptions.rem 必須編碼為大端位元組序序列。

    預設情況下,素數被編碼為 <ArrayBuffer> 中的大端位元組序位元組序列。如果 bigint 選項為 true,則提供 <bigint>

    素數的 size 將直接影響生成素數所需的時間。size 越大,所需時間越長。因為我們使用 OpenSSL 的 BN_generate_prime_ex 函式,它僅提供對我們中斷生成過程能力的最低限度控制,因此不建議生成過大的素數,因為這樣做可能會使該過程無響應。

    crypto.generatePrimeSync(size[, options])#

  • 返回:<ArrayBuffer> | <bigint>

    生成一個 size 位的偽隨機素數。

    如果 options.safetrue,則素數將是一個安全素數——即 (prime - 1) / 2 也將是一個素數。

    options.addoptions.rem 引數可用於強制執行附加要求,例如用於 Diffie-Hellman。

    • 如果設定了 options.addoptions.rem,則素數將滿足 prime % add = rem 的條件。
    • 如果僅設定了 options.addoptions.safe 不為 true,則素數將滿足 prime % add = 1 的條件。
    • 如果僅設定了 options.addoptions.safe 設定為 true,則素數將滿足 prime % add = 3 的條件。這是必要的,因為 options.add > 2prime % add = 1 會與 options.safe 強制執行的條件相矛盾。
    • 如果未給出 options.add,則忽略 options.rem

    如果以 ArrayBufferSharedArrayBufferTypedArrayBufferDataView 形式給出,則 options.addoptions.rem 必須編碼為大端位元組序序列。

    預設情況下,素數被編碼為 <ArrayBuffer> 中的大端位元組序位元組序列。如果 bigint 選項為 true,則提供 <bigint>

    素數的 size 將直接影響生成素數所需的時間。size 越大,所需時間越長。因為我們使用 OpenSSL 的 BN_generate_prime_ex 函式,它僅提供對我們中斷生成過程能力的最低限度控制,因此不建議生成過大的素數,因為這樣做可能會使該過程無響應。

  • crypto.getCipherInfo(nameOrNid[, options])#

  • 返回:<Object>
  • name <string> 密碼名稱。
  • nid <number> 加密演算法的 nid。
  • blockSize <number> 加密演算法的塊大小(以位元組為單位)。當 mode'stream' 時,此屬性被省略。
  • ivLength <number> 預期的或預設的初始化向量長度(以位元組為單位)。如果加密演算法不使用初始化向量,則省略此屬性。
  • keyLength <number> 預期的或預設的金鑰長度(以位元組為單位)。
  • mode <string> 加密模式。為 'cbc''ccm''cfb''ctr''ecb''gcm''ocb''ofb''stream''wrap''xts' 之一。
  • 返回有關給定加密演算法的資訊。

    某些加密演算法接受可變長度的金鑰和初始化向量。預設情況下,crypto.getCipherInfo() 方法將返回這些演算法的預設值。要測試給定的金鑰長度或 iv 長度是否適用於給定的加密演算法,請使用 keyLengthivLength 選項。如果給定值不可接受,則返回 undefined

    crypto.getCiphers()#

    • 返回: <string[]> 一個包含受支援加密演算法名稱的陣列。
    const {
      getCiphers,
    } = await import('node:crypto');
    
    console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
    const {
      getCiphers,
    } = require('node:crypto');
    
    console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
    

    crypto.getCurves()#

    • 返回: <string[]> 一個包含受支援橢圓曲線名稱的陣列。
    const {
      getCurves,
    } = await import('node:crypto');
    
    console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
    const {
      getCurves,
    } = require('node:crypto');
    
    console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
    

    crypto.getDiffieHellman(groupName)#

    建立一個預定義的 DiffieHellmanGroup 金鑰交換物件。支援的組列在 DiffieHellmanGroup 的文件中。

    返回的物件模仿 crypto.createDiffieHellman() 建立的物件的介面,但不允許更改金鑰(例如,使用 diffieHellman.setPublicKey())。使用此方法的優點是雙方無需預先生成或交換組模數,從而節省了處理器和通訊時間。

    示例(獲取共享金鑰)

    const {
      getDiffieHellman,
    } = await import('node:crypto');
    const alice = getDiffieHellman('modp14');
    const bob = getDiffieHellman('modp14');
    
    alice.generateKeys();
    bob.generateKeys();
    
    const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
    const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
    
    /* aliceSecret and bobSecret should be the same */
    console.log(aliceSecret === bobSecret);
    const {
      getDiffieHellman,
    } = require('node:crypto');
    
    const alice = getDiffieHellman('modp14');
    const bob = getDiffieHellman('modp14');
    
    alice.generateKeys();
    bob.generateKeys();
    
    const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
    const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
    
    /* aliceSecret and bobSecret should be the same */
    console.log(aliceSecret === bobSecret);
    

    crypto.getFips()#

    • 返回: <number> 如果當前正在使用符合 FIPS 標準的加密提供程式,則返回 1,否則返回 0。未來的語義化主版本更新可能會將此 API 的返回型別更改為 <boolean>

    crypto.getHashes()#

    • 返回: <string[]> 受支援雜湊演算法名稱的陣列,例如 'RSA-SHA256'。雜湊演算法也稱為“摘要”演算法。
    const {
      getHashes,
    } = await import('node:crypto');
    
    console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
    const {
      getHashes,
    } = require('node:crypto');
    
    console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
    

    crypto.getRandomValues(typedArray)#

    這是 crypto.webcrypto.getRandomValues() 的一個便捷別名。此實現不符合 Web Crypto 規範,若要編寫符合 Web 標準的程式碼,請改用 crypto.webcrypto.getRandomValues()

    crypto.hash(algorithm, data[, options])#

    • algorithm <string> | <undefined>
    • data <string> | <Buffer> | <TypedArray> | <DataView>data 為字串時,它將在被雜湊之前編碼為 UTF-8。如果字串輸入需要不同的編碼,使用者可以使用 TextEncoderBuffer.from() 將字串編碼為 TypedArray,並將編碼後的 TypedArray 傳遞給此 API。
    • options <Object> | <string>
      • outputEncoding <string> 編碼 用於對返回的摘要進行編碼。預設值: 'hex'
      • outputLength <number> 對於像 'shake256' 這樣的 XOF 雜湊函式,outputLength 選項可用於指定所需的輸出長度(以位元組為單位)。
    • 返回: <string> | <Buffer>

    用於建立一次性資料雜湊摘要的工具。在雜湊現成的較小量資料(<= 5MB)時,它可能比基於物件的 crypto.createHash() 更快。如果資料量可能很大或以流的形式處理,仍然建議使用 crypto.createHash()

    algorithm 取決於平臺上 OpenSSL 版本所支援的可用演算法。例如 'sha256''sha512' 等。在較新的 OpenSSL 版本中,openssl list -digest-algorithms 將顯示可用的摘要演算法。

    如果 options 是一個字串,則它指定了 outputEncoding

    示例

    const crypto = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    // Hashing a string and return the result as a hex-encoded string.
    const string = 'Node.js';
    // 10b3493287f831e81a438811a1ffba01f8cec4b7
    console.log(crypto.hash('sha1', string));
    
    // Encode a base64-encoded string into a Buffer, hash it and return
    // the result as a buffer.
    const base64 = 'Tm9kZS5qcw==';
    // <Buffer 10 b3 49 32 87 f8 31 e8 1a 43 88 11 a1 ff ba 01 f8 ce c4 b7>
    console.log(crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'));
    import crypto from 'node:crypto';
    import { Buffer } from 'node:buffer';
    
    // Hashing a string and return the result as a hex-encoded string.
    const string = 'Node.js';
    // 10b3493287f831e81a438811a1ffba01f8cec4b7
    console.log(crypto.hash('sha1', string));
    
    // Encode a base64-encoded string into a Buffer, hash it and return
    // the result as a buffer.
    const base64 = 'Tm9kZS5qcw==';
    // <Buffer 10 b3 49 32 87 f8 31 e8 1a 43 88 11 a1 ff ba 01 f8 ce c4 b7>
    console.log(crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'));
    

    crypto.hkdf(digest, ikm, salt, info, keylen, callback)#

    HKDF 是 RFC 5869 中定義的簡單金鑰派生函式。給定的 ikmsaltinfodigest 一起使用,以派生出一個 keylen 位元組的金鑰。

    提供的 callback 函式將使用兩個引數呼叫:errderivedKey。如果在派生金鑰時發生錯誤,則會設定 err;否則 errnull。成功生成的 derivedKey 將作為 <ArrayBuffer> 傳遞給回撥。如果任何輸入引數指定了無效的值或型別,則會丟擲錯誤。

    import { Buffer } from 'node:buffer';
    const {
      hkdf,
    } = await import('node:crypto');
    
    hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
      if (err) throw err;
      console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
    });
    const {
      hkdf,
    } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
      if (err) throw err;
      console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
    });
    

    crypto.hkdfSync(digest, ikm, salt, info, keylen)#

    提供 RFC 5869 中定義的同步 HKDF 金鑰派生函式。給定的 ikmsaltinfodigest 一起使用,以派生出一個 keylen 位元組的金鑰。

    成功生成的 derivedKey 將作為 <ArrayBuffer> 返回。

    如果任何輸入引數指定了無效的值或型別,或者無法生成派生金鑰,則會丟擲錯誤。

    import { Buffer } from 'node:buffer';
    const {
      hkdfSync,
    } = await import('node:crypto');
    
    const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64);
    console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
    const {
      hkdfSync,
    } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64);
    console.log(Buffer.from(derivedKey).toString('hex'));  // '24156e2...5391653'
    

    crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)#

    提供非同步的基於密碼的金鑰派生函式 2 (PBKDF2) 實現。指定的 HMAC 摘要演算法 digest 應用於從 passwordsaltiterations 中派生出所需位元組長度 (keylen) 的金鑰。

    提供的 callback 函式將使用兩個引數呼叫:errderivedKey。如果在派生金鑰時發生錯誤,則會設定 err;否則 errnull。預設情況下,成功生成的 derivedKey 將作為 Buffer 傳遞給回撥。如果任何輸入引數指定了無效的值或型別,則會丟擲錯誤。

    iterations 引數應該設定得儘可能高。迭代次數越多,派生的金鑰就越安全,但完成所需的時間也就越長。

    salt 應該儘可能唯一。建議使用隨機且至少 16 位元組長的鹽值。詳見 NIST SP 800-132

    當為 passwordsalt 傳遞字串時,請考慮將字串用作加密 API 輸入時的注意事項

    const {
      pbkdf2,
    } = await import('node:crypto');
    
    pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
    });
    const {
      pbkdf2,
    } = require('node:crypto');
    
    pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
    });
    

    支援的摘要函式列表可以使用 crypto.getHashes() 獲取。

    此 API 使用 libuv 的執行緒池,這可能會對某些應用程式產生令人驚訝且負面的效能影響;有關更多資訊,請參閱 UV_THREADPOOL_SIZE 文件。

    crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)#

    提供同步的基於密碼的金鑰派生函式 2 (PBKDF2) 實現。指定的 HMAC 摘要演算法 digest 應用於從 passwordsaltiterations 中派生出所需位元組長度 (keylen) 的金鑰。

    如果發生錯誤,則會丟擲 Error,否則派生的金鑰將作為 Buffer 返回。

    iterations 引數應該設定得儘可能高。迭代次數越多,派生的金鑰就越安全,但完成所需的時間也就越長。

    salt 應該儘可能唯一。建議使用隨機且至少 16 位元組長的鹽值。詳見 NIST SP 800-132

    當為 passwordsalt 傳遞字串時,請考慮將字串用作加密 API 輸入時的注意事項

    const {
      pbkdf2Sync,
    } = await import('node:crypto');
    
    const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512');
    console.log(key.toString('hex'));  // '3745e48...08d59ae'
    const {
      pbkdf2Sync,
    } = require('node:crypto');
    
    const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512');
    console.log(key.toString('hex'));  // '3745e48...08d59ae'
    

    支援的摘要函式列表可以使用 crypto.getHashes() 獲取。

    crypto.privateDecrypt(privateKey, buffer)#

  • buffer <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>
  • 返回: <Buffer> 包含解密內容的新 Buffer
  • privateKey 解密 bufferbuffer 之前是使用相應的公鑰加密的,例如使用 crypto.publicEncrypt()

    如果 privateKey 不是 KeyObject,此函式表現得就像 privateKey 已被傳遞給 crypto.createPrivateKey() 一樣。如果它是一個物件,則可以傳遞 padding 屬性。否則,此函式使用 RSA_PKCS1_OAEP_PADDING

    crypto.privateDecrypt() 中使用 crypto.constants.RSA_PKCS1_PADDING 要求 OpenSSL 支援隱式拒絕 (rsa_pkcs1_implicit_rejection)。如果 Node.js 使用的 OpenSSL 版本不支援此功能,嘗試使用 RSA_PKCS1_PADDING 將會失敗。

    crypto.privateEncrypt(privateKey, buffer)#

  • buffer <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>
  • 返回: <Buffer> 包含加密內容的新 Buffer
  • privateKey 加密 buffer。返回的資料可以使用相應的公鑰進行解密,例如使用 crypto.publicDecrypt()

    如果 privateKey 不是 KeyObject,此函式表現得就像 privateKey 已被傳遞給 crypto.createPrivateKey() 一樣。如果它是一個物件,則可以傳遞 padding 屬性。否則,此函式使用 RSA_PKCS1_PADDING

    crypto.publicDecrypt(key, buffer)#

    key 解密 bufferbuffer 之前是使用相應的私鑰加密的,例如使用 crypto.privateEncrypt()

    如果 key 不是 KeyObject,此函式表現得就像 key 已被傳遞給 crypto.createPublicKey() 一樣。如果它是一個物件,則可以傳遞 padding 屬性。否則,此函式使用 RSA_PKCS1_PADDING

    由於 RSA 公鑰可以從私鑰派生,因此可以傳遞私鑰而不是公鑰。

    crypto.publicEncrypt(key, buffer)#

    key 加密 buffer 的內容,並返回包含加密內容的新 Buffer。返回的資料可以使用相應的私鑰進行解密,例如使用 crypto.privateDecrypt()

    如果 key 不是 KeyObject,此函式表現得就像 key 已被傳遞給 crypto.createPublicKey() 一樣。如果它是一個物件,則可以傳遞 padding 屬性。否則,此函式使用 RSA_PKCS1_OAEP_PADDING

    由於 RSA 公鑰可以從私鑰派生,因此可以傳遞私鑰而不是公鑰。

    crypto.randomBytes(size[, callback])#

    生成密碼學意義上的強偽隨機資料。size 引數是一個數字,指示要生成的位元組數。

    如果提供了 callback 函式,則非同步生成位元組,並使用兩個引數呼叫 callback 函式:errbuf。如果發生錯誤,err 將是一個 Error 物件;否則為 nullbuf 引數是一個包含生成位元組的 Buffer

    // Asynchronous
    const {
      randomBytes,
    } = await import('node:crypto');
    
    randomBytes(256, (err, buf) => {
      if (err) throw err;
      console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
    });
    // Asynchronous
    const {
      randomBytes,
    } = require('node:crypto');
    
    randomBytes(256, (err, buf) => {
      if (err) throw err;
      console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
    });
    

    如果沒有提供 callback 函式,則同步生成隨機位元組並作為 Buffer 返回。如果在生成位元組時出現問題,將會丟擲錯誤。

    // Synchronous
    const {
      randomBytes,
    } = await import('node:crypto');
    
    const buf = randomBytes(256);
    console.log(
      `${buf.length} bytes of random data: ${buf.toString('hex')}`);
    // Synchronous
    const {
      randomBytes,
    } = require('node:crypto');
    
    const buf = randomBytes(256);
    console.log(
      `${buf.length} bytes of random data: ${buf.toString('hex')}`);
    

    crypto.randomBytes() 方法不會完成,直到有足夠的熵可用。這通常絕不會超過幾毫秒。生成隨機位元組可能會長時間阻塞的唯一時間是在引導之後,此時整個系統仍然缺乏熵。

    此 API 使用 libuv 的執行緒池,這可能會對某些應用程式產生令人驚訝且負面的效能影響;有關更多資訊,請參閱 UV_THREADPOOL_SIZE 文件。

    crypto.randomBytes() 的非同步版本在單個執行緒池請求中執行。為了最大限度地減少執行緒池任務長度的變化,在作為履行客戶端請求的一部分執行時,請對大型 randomBytes 請求進行分割槽。

    crypto.randomFill(buffer[, offset][, size], callback)#

    此函式類似於 crypto.randomBytes(),但要求第一個引數是將被填充的 Buffer。它還要求傳遞一個回撥。

    如果沒有提供 callback 函式,則會丟擲錯誤。

    import { Buffer } from 'node:buffer';
    const { randomFill } = await import('node:crypto');
    
    const buf = Buffer.alloc(10);
    randomFill(buf, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    
    randomFill(buf, 5, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    
    // The above is equivalent to the following:
    randomFill(buf, 5, 5, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    const { randomFill } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    const buf = Buffer.alloc(10);
    randomFill(buf, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    
    randomFill(buf, 5, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    
    // The above is equivalent to the following:
    randomFill(buf, 5, 5, (err, buf) => {
      if (err) throw err;
      console.log(buf.toString('hex'));
    });
    

    任何 ArrayBufferTypedArrayDataView 例項都可以作為 buffer 傳遞。

    雖然這包括 Float32ArrayFloat64Array 的例項,但不應使用此函式生成隨機浮點數。結果可能包含 +Infinity-InfinityNaN,即使陣列僅包含有限數,它們也不是從均勻隨機分佈中抽取的,並且沒有有意義的下限或上限。

    import { Buffer } from 'node:buffer';
    const { randomFill } = await import('node:crypto');
    
    const a = new Uint32Array(10);
    randomFill(a, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
        .toString('hex'));
    });
    
    const b = new DataView(new ArrayBuffer(10));
    randomFill(b, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
        .toString('hex'));
    });
    
    const c = new ArrayBuffer(10);
    randomFill(c, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf).toString('hex'));
    });
    const { randomFill } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    const a = new Uint32Array(10);
    randomFill(a, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
        .toString('hex'));
    });
    
    const b = new DataView(new ArrayBuffer(10));
    randomFill(b, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
        .toString('hex'));
    });
    
    const c = new ArrayBuffer(10);
    randomFill(c, (err, buf) => {
      if (err) throw err;
      console.log(Buffer.from(buf).toString('hex'));
    });
    

    此 API 使用 libuv 的執行緒池,這可能會對某些應用程式產生令人驚訝且負面的效能影響;有關更多資訊,請參閱 UV_THREADPOOL_SIZE 文件。

    crypto.randomFill() 的非同步版本在單個執行緒池請求中執行。為了最大限度地減少執行緒池任務長度的變化,在作為履行客戶端請求的一部分執行時,請對大型 randomFill 請求進行分割槽。

    crypto.randomFillSync(buffer[, offset][, size])#

    crypto.randomFill() 的同步版本。

    import { Buffer } from 'node:buffer';
    const { randomFillSync } = await import('node:crypto');
    
    const buf = Buffer.alloc(10);
    console.log(randomFillSync(buf).toString('hex'));
    
    randomFillSync(buf, 5);
    console.log(buf.toString('hex'));
    
    // The above is equivalent to the following:
    randomFillSync(buf, 5, 5);
    console.log(buf.toString('hex'));
    const { randomFillSync } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    const buf = Buffer.alloc(10);
    console.log(randomFillSync(buf).toString('hex'));
    
    randomFillSync(buf, 5);
    console.log(buf.toString('hex'));
    
    // The above is equivalent to the following:
    randomFillSync(buf, 5, 5);
    console.log(buf.toString('hex'));
    

    任何 ArrayBufferTypedArrayDataView 例項都可以作為 buffer 傳遞。

    import { Buffer } from 'node:buffer';
    const { randomFillSync } = await import('node:crypto');
    
    const a = new Uint32Array(10);
    console.log(Buffer.from(randomFillSync(a).buffer,
                            a.byteOffset, a.byteLength).toString('hex'));
    
    const b = new DataView(new ArrayBuffer(10));
    console.log(Buffer.from(randomFillSync(b).buffer,
                            b.byteOffset, b.byteLength).toString('hex'));
    
    const c = new ArrayBuffer(10);
    console.log(Buffer.from(randomFillSync(c)).toString('hex'));
    const { randomFillSync } = require('node:crypto');
    const { Buffer } = require('node:buffer');
    
    const a = new Uint32Array(10);
    console.log(Buffer.from(randomFillSync(a).buffer,
                            a.byteOffset, a.byteLength).toString('hex'));
    
    const b = new DataView(new ArrayBuffer(10));
    console.log(Buffer.from(randomFillSync(b).buffer,
                            b.byteOffset, b.byteLength).toString('hex'));
    
    const c = new ArrayBuffer(10);
    console.log(Buffer.from(randomFillSync(c)).toString('hex'));
    

    crypto.randomInt([min, ]max[, callback])#

    • min <integer> 隨機範圍的開始(包含)。預設值: 0
    • max <integer> 隨機範圍的結束(不包含)。
    • callback <Function> function(err, n) {}

    返回一個隨機整數 n,使得 min <= n < max。此實現避免了 模偏差

    範圍 (max - min) 必須小於 248minmax 必須是 安全整數

    如果沒有提供 callback 函式,則同步生成隨機整數。

    // Asynchronous
    const {
      randomInt,
    } = await import('node:crypto');
    
    randomInt(3, (err, n) => {
      if (err) throw err;
      console.log(`Random number chosen from (0, 1, 2): ${n}`);
    });
    // Asynchronous
    const {
      randomInt,
    } = require('node:crypto');
    
    randomInt(3, (err, n) => {
      if (err) throw err;
      console.log(`Random number chosen from (0, 1, 2): ${n}`);
    });
    
    // Synchronous
    const {
      randomInt,
    } = await import('node:crypto');
    
    const n = randomInt(3);
    console.log(`Random number chosen from (0, 1, 2): ${n}`);
    // Synchronous
    const {
      randomInt,
    } = require('node:crypto');
    
    const n = randomInt(3);
    console.log(`Random number chosen from (0, 1, 2): ${n}`);
    
    // With `min` argument
    const {
      randomInt,
    } = await import('node:crypto');
    
    const n = randomInt(1, 7);
    console.log(`The dice rolled: ${n}`);
    // With `min` argument
    const {
      randomInt,
    } = require('node:crypto');
    
    const n = randomInt(1, 7);
    console.log(`The dice rolled: ${n}`);
    

    crypto.randomUUID([options])#

    • options <Object>
    • disableEntropyCache <boolean> 預設情況下,為了提高效能,Node.js 會生成並快取足夠的隨機資料以生成多達 128 個隨機 UUID。要生成 UUID 而不使用快取,請將 disableEntropyCache 設定為 true預設值: false
  • 返回: <string>
  • 生成一個隨機的 RFC 4122 第 4 版 UUID。UUID 是使用加密偽隨機數生成器生成的。

    crypto.scrypt(password, salt, keylen[, options], callback)#

  • callback <Function>
  • 提供非同步 scrypt 實現。Scrypt 是一種基於密碼的金鑰派生函式,旨在在計算和記憶體方面昂貴,以使暴力破解攻擊無利可圖。

    salt 應該儘可能唯一。建議使用隨機且至少 16 位元組長的鹽值。詳見 NIST SP 800-132

    當為 passwordsalt 傳遞字串時,請考慮將字串用作加密 API 輸入時的注意事項

    callback 函式使用兩個引數呼叫:errderivedKey。當金鑰派生失敗時,err 是一個異常物件,否則 errnullderivedKey 作為 Buffer 傳遞給回撥。

    當任何輸入引數指定無效值或型別時,會丟擲異常。

    const {
      scrypt,
    } = await import('node:crypto');
    
    // Using the factory defaults.
    scrypt('password', 'salt', 64, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
    });
    // Using a custom N parameter. Must be a power of two.
    scrypt('password', 'salt', 64, { N: 1024 }, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
    });
    const {
      scrypt,
    } = require('node:crypto');
    
    // Using the factory defaults.
    scrypt('password', 'salt', 64, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
    });
    // Using a custom N parameter. Must be a power of two.
    scrypt('password', 'salt', 64, { N: 1024 }, (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
    });
    

    crypto.scryptSync(password, salt, keylen[, options])#

  • 返回:<Buffer>
  • 提供同步 scrypt 實現。Scrypt 是一種基於密碼的金鑰派生函式,旨在在計算和記憶體方面昂貴,以使暴力破解攻擊無利可圖。

    salt 應該儘可能唯一。建議使用隨機且至少 16 位元組長的鹽值。詳見 NIST SP 800-132

    當為 passwordsalt 傳遞字串時,請考慮將字串用作加密 API 輸入時的注意事項

    當金鑰派生失敗時會丟擲異常,否則派生金鑰將作為 Buffer 返回。

    當任何輸入引數指定無效值或型別時,會丟擲異常。

    const {
      scryptSync,
    } = await import('node:crypto');
    // Using the factory defaults.
    
    const key1 = scryptSync('password', 'salt', 64);
    console.log(key1.toString('hex'));  // '3745e48...08d59ae'
    // Using a custom N parameter. Must be a power of two.
    const key2 = scryptSync('password', 'salt', 64, { N: 1024 });
    console.log(key2.toString('hex'));  // '3745e48...aa39b34'
    const {
      scryptSync,
    } = require('node:crypto');
    // Using the factory defaults.
    
    const key1 = scryptSync('password', 'salt', 64);
    console.log(key1.toString('hex'));  // '3745e48...08d59ae'
    // Using a custom N parameter. Must be a power of two.
    const key2 = scryptSync('password', 'salt', 64, { N: 1024 });
    console.log(key2.toString('hex'));  // '3745e48...aa39b34'
    

    crypto.secureHeapUsed()#

    • 返回:<Object>
    • total <number> 使用 --secure-heap=n 命令列標誌指定的已分配安全堆總大小。
    • min <number> 使用 --secure-heap-min 命令列標誌指定的安全堆的最小分配量。
    • used <number> 當前從安全堆分配的總位元組數。
    • utilization <number> 計算出的已使用位元組與總分配位元組的比率。

    crypto.setEngine(engine[, flags])#

    為部分或全部 OpenSSL 函式(由標誌選擇)載入並設定 engine。OpenSSL 中對自定義引擎的支援在 OpenSSL 3 中已被棄用。

    engine 可以是 ID,也可以是引擎共享庫的路徑。

    可選的 flags 引數預設使用 ENGINE_METHOD_ALLflags 是一個位欄位,取以下標誌(定義在 crypto.constants 中)之一或組合

    • crypto.constants.ENGINE_METHOD_RSA
    • crypto.constants.ENGINE_METHOD_DSA
    • crypto.constants.ENGINE_METHOD_DH
    • crypto.constants.ENGINE_METHOD_RAND
    • crypto.constants.ENGINE_METHOD_EC
    • crypto.constants.ENGINE_METHOD_CIPHERS
    • crypto.constants.ENGINE_METHOD_DIGESTS
    • crypto.constants.ENGINE_METHOD_PKEY_METHS
    • crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS
    • crypto.constants.ENGINE_METHOD_ALL
    • crypto.constants.ENGINE_METHOD_NONE

    crypto.setFips(bool)#

    在啟用了 FIPS 的 Node.js 構建中啟用符合 FIPS 標準的加密提供程式。如果 FIPS 模式不可用,則丟擲錯誤。

    crypto.sign(algorithm, data, key[, callback])#

    使用給定的私鑰和演算法計算並返回 data 的簽名。如果 algorithmnullundefined,則演算法取決於金鑰型別。

    對於 Ed25519、Ed448 和 ML-DSA,algorithm 要求為 nullundefined

    如果 key 不是 KeyObject,此函式表現得就像 key 已被傳遞給 crypto.createPrivateKey() 一樣。如果它是一個物件,則可以傳遞以下附加屬性

    • dsaEncoding <string> 對於 DSA 和 ECDSA,此選項指定生成的簽名的格式。它可以是以下之一

      • 'der'(預設):對 (r, s) 進行編碼的 DER 編碼 ASN.1 簽名結構。
      • 'ieee-p1363':IEEE-P1363 中提出的簽名格式 r || s
    • padding <integer> RSA 的可選填充值,為以下之一

      • crypto.constants.RSA_PKCS1_PADDING(預設)
      • crypto.constants.RSA_PKCS1_PSS_PADDING

      RSA_PKCS1_PSS_PADDING 將使用與用於簽署訊息的雜湊函式相同的 MGF1,如 RFC 4055 第 3.1 節所指定。

    • saltLength <integer> 當填充方式為 RSA_PKCS1_PSS_PADDING 時的鹽值長度。特殊值 crypto.constants.RSA_PSS_SALTLEN_DIGEST 將鹽值長度設定為摘要大小,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(預設值)將其設定為允許的最大值。

    • context <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 對於 Ed255193(使用 RFC 8032 中的 Ed25519ctx)、Ed448、ML-DSA 和 SLH-DSA,此選項指定可選上下文,以區分使用相同金鑰為不同目的生成的簽名。

    如果提供了 callback 函式,則此函式使用 libuv 的執行緒池。

    crypto.subtle#

    這是 crypto.webcrypto.subtle 的一個便捷別名。

    crypto.timingSafeEqual(a, b)#

    此函式使用恆定時間演算法比較表示給定 ArrayBufferTypedArrayDataView 例項的底層位元組。

    此函式不會洩露允許攻擊者猜測其中一個值的時序資訊。這適用於比較 HMAC 摘要或機密值(如身份驗證 cookie 或 能力 URL)。

    ab 都必須是 BufferTypedArrayDataView,並且它們必須具有相同的位元組長度。如果 ab 的位元組長度不同,則會丟擲錯誤。

    如果 ab 中至少有一個是每個條目超過一個位元組的 TypedArray(例如 Uint16Array),則結果將使用平臺位元組順序進行計算。

    當兩個輸入都是 Float32ArrayFloat64Array 時,由於浮點數的 IEEE 754 編碼,此函式可能會返回意外結果。特別是,x === yObject.is(x, y) 均不意味著兩個浮點數 xy 的位元組表示相等。

    使用 crypto.timingSafeEqual 並不能保證 周圍 的程式碼是時序安全的。應注意確保周圍的程式碼不會引入時序漏洞。

    crypto.verify(algorithm, data, key, signature[, callback])#

    使用給定的金鑰和演算法驗證 data 的給定簽名。如果 algorithmnullundefined,則演算法取決於金鑰型別。

    對於 Ed25519、Ed448 和 ML-DSA,algorithm 要求為 nullundefined

    如果 key 不是 KeyObject,此函式表現得就像 key 已被傳遞給 crypto.createPublicKey() 一樣。如果它是一個物件,則可以傳遞以下附加屬性

    • dsaEncoding <string> 對於 DSA 和 ECDSA,此選項指定簽名的格式。它可以是以下值之一:

      • 'der'(預設):對 (r, s) 進行編碼的 DER 編碼 ASN.1 簽名結構。
      • 'ieee-p1363':IEEE-P1363 中提出的簽名格式 r || s
    • padding <integer> RSA 的可選填充值,為以下之一

      • crypto.constants.RSA_PKCS1_PADDING(預設)
      • crypto.constants.RSA_PKCS1_PSS_PADDING

      RSA_PKCS1_PSS_PADDING 將使用與用於簽署訊息的雜湊函式相同的 MGF1,如 RFC 4055 第 3.1 節所指定。

    • saltLength <integer> 當填充方式為 RSA_PKCS1_PSS_PADDING 時的鹽值長度。特殊值 crypto.constants.RSA_PSS_SALTLEN_DIGEST 將鹽值長度設定為摘要大小,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN(預設值)將其設定為允許的最大值。

    • context <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 對於 Ed255193(使用 RFC 8032 中的 Ed25519ctx)、Ed448、ML-DSA 和 SLH-DSA,此選項指定可選上下文,以區分使用相同金鑰為不同目的生成的簽名。

    signature 引數是之前為 data 計算的簽名。

    由於公鑰可以從私鑰派生,因此可以為 key 傳遞私鑰或公鑰。

    如果提供了 callback 函式,則此函式使用 libuv 的執行緒池。

    crypto.webcrypto#

    型別: <Crypto> Web Crypto API 標準的實現。

    有關詳細資訊,請參閱 Web Crypto API 文件

    注意事項#

    將字串用作加密 API 的輸入#

    出於歷史原因,Node.js 提供的許多加密 API 接受字串作為輸入,而底層加密演算法則處理位元組序列。這些例項包括明文、密文、對稱金鑰、初始化向量、密碼短語、鹽值、身份驗證標籤和附加身份驗證資料。

    將字串傳遞給加密 API 時,請考慮以下因素。

    • 並非所有位元組序列都是有效的 UTF-8 字串。因此,當從字串派生長度為 n 的位元組序列時,其熵通常低於隨機或偽隨機 n 位元組序列的熵。例如,沒有 UTF-8 字串會產生位元組序列 c0 af。金鑰幾乎應該完全是隨機或偽隨機位元組序列。

    • 類似地,當將隨機或偽隨機位元組序列轉換為 UTF-8 字串時,不代表有效程式碼點的子序列可能會被 Unicode 替換字元 (U+FFFD) 替換。因此,結果 Unicode 字串的位元組表示可能不等於建立該字串所依據的位元組序列。

      const original = [0xc0, 0xaf];
      const bytesAsString = Buffer.from(original).toString('utf8');
      const stringAsBytes = Buffer.from(bytesAsString, 'utf8');
      console.log(stringAsBytes);
      // Prints '<Buffer ef bf bd ef bf bd>'.
      

      加密演算法、雜湊函式、簽名演算法和金鑰派生函式的輸出是偽隨機位元組序列,不應作為 Unicode 字串使用。

    • 當字串從使用者輸入中獲取時,某些 Unicode 字元可以用多種等效方式表示,從而導致不同的位元組序列。例如,當將使用者密碼短語傳遞給金鑰派生函式(如 PBKDF2 或 scrypt)時,金鑰派生函式的結果取決於字串使用的是組合字元還是分解字元。Node.js 不會規範化字元表示。開發人員應考慮在將使用者輸入傳遞給加密 API 之前對其使用 String.prototype.normalize()

    舊版流 API(Node.js 0.10 之前)#

    Crypto 模組是在統一流 API 的概念出現之前,以及在用於處理二進位制資料的 Buffer 物件出現之前新增到 Node.js 中的。因此,許多 crypto 類擁有其他實現 API 的 Node.js 類中通常找不到的方法(例如 update()final()digest())。此外,許多方法預設接受並返回 'latin1' 編碼的字串,而不是 Buffer。此預設值已在 Node.js 0.9.3 中更改為預設使用 Buffer 物件。

    對弱演算法或已洩露演算法的支援#

    node:crypto 模組仍然支援一些已經洩露且不建議使用的演算法。該 API 還允許使用金鑰大小較小、對於安全使用而言太弱的加密演算法和雜湊演算法。

    使用者應全權負責根據其安全要求選擇加密演算法和金鑰大小。

    基於 NIST SP 800-131A 的建議

    • 在需要抗碰撞性(如數字簽名)的情況下,MD5 和 SHA-1 不再是可以接受的。
    • 建議 RSA、DSA 和 DH 演算法使用的金鑰至少為 2048 位,ECDSA 和 ECDH 的曲線金鑰至少為 224 位,以便能夠安全使用數年。
    • modp1modp2modp5 的 DH 組金鑰大小小於 2048 位,不建議使用。

    有關其他建議和詳細資訊,請參閱參考資料。

    一些具有已知弱點且在實踐中意義不大的演算法只能透過 legacy provider(舊版提供程式)獲得,該提供程式預設不啟用。

    CCM 模式#

    CCM 是受支援的 AEAD 演算法之一。使用此模式的應用程式在使用加密演算法 API 時必須遵守某些限制

    • 必須透過設定 authTagLength 選項在建立加密演算法時指定身份驗證標籤長度,並且必須為 4、6、8、10、12、14 或 16 位元組之一。
    • 初始化向量 (nonce) N 的長度必須在 7 到 13 位元組之間 (7 ≤ N ≤ 13)。
    • 明文的長度限制為 2 ** (8 * (15 - N)) 位元組。
    • 解密時,必須在呼叫 update() 之前透過 setAuthTag() 設定身份驗證標籤。否則,解密將失敗,並且 final() 將根據 RFC 3610 第 2.6 節丟擲錯誤。
    • 在 CCM 模式下使用 write(data)end(data)pipe() 等流方法可能會失敗,因為 CCM 每個例項無法處理超過一個數據塊。
    • 當傳遞附加身份驗證資料 (AAD) 時,必須透過 plaintextLength 選項將實際訊息的位元組長度傳遞給 setAAD()。許多加密庫將身份驗證標籤包含在密文中,這意味著它們生成的密文長度為 plaintextLength + authTagLength。Node.js 不包含身份驗證標籤,因此密文長度始終為 plaintextLength。如果不使用 AAD,則無需這樣做。
    • 由於 CCM 一次處理整條訊息,因此必須恰好呼叫一次 update()
    • 儘管呼叫 update() 足以加密/解密訊息,但應用程式 必須 呼叫 final() 以計算或驗證身份驗證標籤。
    import { Buffer } from 'node:buffer';
    const {
      createCipheriv,
      createDecipheriv,
      randomBytes,
    } = await import('node:crypto');
    
    const key = 'keykeykeykeykeykeykeykey';
    const nonce = randomBytes(12);
    
    const aad = Buffer.from('0123456789', 'hex');
    
    const cipher = createCipheriv('aes-192-ccm', key, nonce, {
      authTagLength: 16,
    });
    const plaintext = 'Hello world';
    cipher.setAAD(aad, {
      plaintextLength: Buffer.byteLength(plaintext),
    });
    const ciphertext = cipher.update(plaintext, 'utf8');
    cipher.final();
    const tag = cipher.getAuthTag();
    
    // Now transmit { ciphertext, nonce, tag }.
    
    const decipher = createDecipheriv('aes-192-ccm', key, nonce, {
      authTagLength: 16,
    });
    decipher.setAuthTag(tag);
    decipher.setAAD(aad, {
      plaintextLength: ciphertext.length,
    });
    const receivedPlaintext = decipher.update(ciphertext, null, 'utf8');
    
    try {
      decipher.final();
    } catch (err) {
      throw new Error('Authentication failed!', { cause: err });
    }
    
    console.log(receivedPlaintext);
    const { Buffer } = require('node:buffer');
    const {
      createCipheriv,
      createDecipheriv,
      randomBytes,
    } = require('node:crypto');
    
    const key = 'keykeykeykeykeykeykeykey';
    const nonce = randomBytes(12);
    
    const aad = Buffer.from('0123456789', 'hex');
    
    const cipher = createCipheriv('aes-192-ccm', key, nonce, {
      authTagLength: 16,
    });
    const plaintext = 'Hello world';
    cipher.setAAD(aad, {
      plaintextLength: Buffer.byteLength(plaintext),
    });
    const ciphertext = cipher.update(plaintext, 'utf8');
    cipher.final();
    const tag = cipher.getAuthTag();
    
    // Now transmit { ciphertext, nonce, tag }.
    
    const decipher = createDecipheriv('aes-192-ccm', key, nonce, {
      authTagLength: 16,
    });
    decipher.setAuthTag(tag);
    decipher.setAAD(aad, {
      plaintextLength: ciphertext.length,
    });
    const receivedPlaintext = decipher.update(ciphertext, null, 'utf8');
    
    try {
      decipher.final();
    } catch (err) {
      throw new Error('Authentication failed!', { cause: err });
    }
    
    console.log(receivedPlaintext);
    

    FIPS 模式#

    使用 OpenSSL 3 時,當與合適的 OpenSSL 3 提供程式(例如 OpenSSL 3 的 FIPS 提供程式)一起使用時,Node.js 支援 FIPS 140-2,可以透過遵循 OpenSSL 的 FIPS README 檔案中的說明進行安裝。

    對於 Node.js 中的 FIPS 支援,您將需要

    • 正確安裝的 OpenSSL 3 FIPS 提供程式。
    • OpenSSL 3 FIPS 模組配置檔案
    • 引用 FIPS 模組配置檔案的 OpenSSL 3 配置檔案。

    Node.js 需要配置一個指向 FIPS 提供程式的 OpenSSL 配置檔案。示例配置檔案如下所示

    nodejs_conf = nodejs_init
    
    .include /<absolute path>/fipsmodule.cnf
    
    [nodejs_init]
    providers = provider_sect
    
    [provider_sect]
    default = default_sect
    # The fips section name should match the section name inside the
    # included fipsmodule.cnf.
    fips = fips_sect
    
    [default_sect]
    activate = 1
    

    其中 fipsmodule.cnf 是從 FIPS 提供程式安裝步驟生成的 FIPS 模組配置檔案

    openssl fipsinstall
    

    設定 OPENSSL_CONF 環境變數以指向您的配置檔案,並將 OPENSSL_MODULES 設定為 FIPS 提供程式動態庫的位置。例如

    export OPENSSL_CONF=/<path to configuration file>/nodejs.cnf
    export OPENSSL_MODULES=/<path to openssl lib>/ossl-modules
    

    然後可以透過以下方式在 Node.js 中啟用 FIPS 模式

    • 使用 --enable-fips--force-fips 命令列標誌啟動 Node.js。
    • 以程式設計方式呼叫 crypto.setFips(true)

    或者,可以透過 OpenSSL 配置檔案在 Node.js 中啟用 FIPS 模式。例如

    nodejs_conf = nodejs_init
    
    .include /<absolute path>/fipsmodule.cnf
    
    [nodejs_init]
    providers = provider_sect
    alg_section = algorithm_sect
    
    [provider_sect]
    default = default_sect
    # The fips section name should match the section name inside the
    # included fipsmodule.cnf.
    fips = fips_sect
    
    [default_sect]
    activate = 1
    
    [algorithm_sect]
    default_properties = fips=yes
    

    加密常量#

    crypto.constants 匯出的以下常量適用於 node:cryptonode:tlsnode:https 模組的各種用途,並且通常特定於 OpenSSL。

    OpenSSL 選項#

    有關詳細資訊,請參閱 SSL OP 標誌列表

    常量 描述
    SSL_OP_ALL 在 OpenSSL 內應用多種錯誤解決方法。有關詳細資訊,請參閱 https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html
    SSL_OP_ALLOW_NO_DHE_KEX 指示 OpenSSL 允許 TLS v1.3 的非 [EC]DHE 金鑰交換模式
    SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 允許 OpenSSL 與未打補丁的客戶端或伺服器之間進行不安全的舊版重新協商。請參閱 https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html
    SSL_OP_CIPHER_SERVER_PREFERENCE 在選擇加密演算法時嘗試使用伺服器的首選項而不是客戶端的首選項。行為取決於協議版本。請參閱 https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html
    SSL_OP_CISCO_ANYCONNECT 指示 OpenSSL 使用 Cisco 的 DTLS_BAD_VER 版本識別符號。
    SSL_OP_COOKIE_EXCHANGE 指示 OpenSSL 開啟 cookie 交換。
    SSL_OP_CRYPTOPRO_TLSEXT_BUG 指示 OpenSSL 新增來自 cryptopro 草案早期版本的 server-hello 擴充套件。
    SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 指示 OpenSSL 停用在 OpenSSL 0.9.6d 中新增的 SSL 3.0/TLS 1.0 漏洞解決方法。
    SSL_OP_LEGACY_SERVER_CONNECT 允許與不支援 RI 的伺服器進行初始連線。
    SSL_OP_NO_COMPRESSION 指示 OpenSSL 停用對 SSL/TLS 壓縮的支援。
    SSL_OP_NO_ENCRYPT_THEN_MAC 指示 OpenSSL 停用 encrypt-then-MAC。
    SSL_OP_NO_QUERY_MTU
    SSL_OP_NO_RENEGOTIATION 指示 OpenSSL 停用重新協商。
    SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 指示 OpenSSL 在執行重新協商時始終啟動新會話。
    SSL_OP_NO_SSLv2 指示 OpenSSL 關閉 SSL v2
    SSL_OP_NO_SSLv3 指示 OpenSSL 關閉 SSL v3
    SSL_OP_NO_TICKET 指示 OpenSSL 停用對 RFC4507bis 票證的使用。
    SSL_OP_NO_TLSv1 指示 OpenSSL 關閉 TLS v1
    SSL_OP_NO_TLSv1_1 指示 OpenSSL 關閉 TLS v1.1
    SSL_OP_NO_TLSv1_2 指示 OpenSSL 關閉 TLS v1.2
    SSL_OP_NO_TLSv1_3 指示 OpenSSL 關閉 TLS v1.3
    SSL_OP_PRIORITIZE_CHACHA 指示 OpenSSL 伺服器在客戶端也優先考慮 ChaCha20-Poly1305 時優先使用它。如果未啟用 SSL_OP_CIPHER_SERVER_PREFERENCE,則此選項無效。
    SSL_OP_TLS_ROLLBACK_BUG 指示 OpenSSL 停用版本回滾攻擊檢測。

    OpenSSL 引擎常量#

    常量 描述
    ENGINE_METHOD_RSA 將引擎使用限制為 RSA
    ENGINE_METHOD_DSA 將引擎使用限制為 DSA
    ENGINE_METHOD_DH 將引擎使用限制為 DH
    ENGINE_METHOD_RAND 將引擎使用限制為 RAND
    ENGINE_METHOD_EC 將引擎使用限制為 EC
    ENGINE_METHOD_CIPHERS 將引擎使用限制為 CIPHERS
    ENGINE_METHOD_DIGESTS 將引擎使用限制為 DIGESTS
    ENGINE_METHOD_PKEY_METHS 將引擎使用限制為 PKEY_METHS
    ENGINE_METHOD_PKEY_ASN1_METHS 將引擎使用限制為 PKEY_ASN1_METHS
    ENGINE_METHOD_ALL
    ENGINE_METHOD_NONE

    其他 OpenSSL 常量#

    常量 描述
    DH_CHECK_P_NOT_SAFE_PRIME
    DH_CHECK_P_NOT_PRIME
    DH_UNABLE_TO_CHECK_GENERATOR
    DH_NOT_SUITABLE_GENERATOR
    RSA_PKCS1_PADDING
    RSA_SSLV23_PADDING
    RSA_NO_PADDING
    RSA_PKCS1_OAEP_PADDING
    RSA_X931_PADDING
    RSA_PKCS1_PSS_PADDING
    RSA_PSS_SALTLEN_DIGEST 在簽名或驗證時將 RSA_PKCS1_PSS_PADDING 的鹽長度設定為摘要大小。
    RSA_PSS_SALTLEN_MAX_SIGN 在簽署資料時將 RSA_PKCS1_PSS_PADDING 的鹽長度設定為最大允許值。
    RSA_PSS_SALTLEN_AUTO 導致 RSA_PKCS1_PSS_PADDING 的鹽長度在驗證簽名時自動確定。
    POINT_CONVERSION_COMPRESSED
    POINT_CONVERSION_UNCOMPRESSED
    POINT_CONVERSION_HYBRID

    Node.js 加密常量#

    常量 描述
    defaultCoreCipherList 指定 Node.js 使用的內建預設加密列表。
    defaultCipherList 指定當前 Node.js 程序使用的有效預設加密列表。

    腳註

    1. 需要 OpenSSL >= 3.5 ...

    2. 需要 OpenSSL >= 3.0 ...

    3. 需要 OpenSSL >= 3.2 ...