Node.js v21.7.2 文件
- Node.js v21.7.2
-
► 目錄
- Crypto
- 判斷 crypto 支援是否不可用
- 類別:
Certificate
- 類別:
Cipher
- 類別:
Decipher
- 類別:
DiffieHellman
diffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])
diffieHellman.generateKeys([encoding])
diffieHellman.getGenerator([encoding])
diffieHellman.getPrime([encoding])
diffieHellman.getPrivateKey([encoding])
diffieHellman.getPublicKey([encoding])
diffieHellman.setPrivateKey(privateKey[, encoding])
diffieHellman.setPublicKey(publicKey[, encoding])
diffieHellman.verifyError
- 類別:
DiffieHellmanGroup
- 類別:
ECDH
- 靜態方法:
ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]])
ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])
ecdh.generateKeys([encoding[, format]])
ecdh.getPrivateKey([encoding])
ecdh.getPublicKey([encoding][, format])
ecdh.setPrivateKey(privateKey[, encoding])
ecdh.setPublicKey(publicKey[, encoding])
- 靜態方法:
- 類別:
Hash
- 類別:
Hmac
- 類別:
KeyObject
- 類別:
Sign
- 類別:
Verify
- 類別:
X509Certificate
new X509Certificate(buffer)
x509.ca
x509.checkEmail(email[, options])
x509.checkHost(name[, options])
x509.checkIP(ip)
x509.checkIssued(otherCert)
x509.checkPrivateKey(privateKey)
x509.fingerprint
x509.fingerprint256
x509.fingerprint512
x509.infoAccess
x509.issuer
x509.issuerCertificate
x509.extKeyUsage
x509.publicKey
x509.raw
x509.serialNumber
x509.subject
x509.subjectAltName
x509.toJSON()
x509.toLegacyObject()
x509.toString()
x509.validFrom
x509.validTo
x509.verify(publicKey)
node:crypto
模組方法與屬性crypto.constants
crypto.fips
crypto.checkPrime(candidate[, options], callback)
crypto.checkPrimeSync(candidate[, options])
crypto.createCipher(algorithm, password[, options])
crypto.createCipheriv(algorithm, key, iv[, options])
crypto.createDecipher(algorithm, password[, options])
crypto.createDecipheriv(algorithm, key, iv[, options])
crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])
crypto.createDiffieHellman(primeLength[, generator])
crypto.createDiffieHellmanGroup(name)
crypto.createECDH(curveName)
crypto.createHash(algorithm[, options])
crypto.createHmac(algorithm, key[, options])
crypto.createPrivateKey(key)
crypto.createPublicKey(key)
crypto.createSecretKey(key[, encoding])
crypto.createSign(algorithm[, options])
crypto.createVerify(algorithm[, options])
crypto.diffieHellman(options)
crypto.hash(algorith, data[, outputEncoding])
crypto.generateKey(type, options, callback)
crypto.generateKeyPair(type, options, callback)
crypto.generateKeyPairSync(type, options)
crypto.generateKeySync(type, options)
crypto.generatePrime(size[, options[, callback]])
crypto.generatePrimeSync(size[, options])
crypto.getCipherInfo(nameOrNid[, options])
crypto.getCiphers()
crypto.getCurves()
crypto.getDiffieHellman(groupName)
crypto.getFips()
crypto.getHashes()
crypto.getRandomValues(typedArray)
crypto.hkdf(digest, ikm, salt, info, keylen, callback)
crypto.hkdfSync(digest, ikm, salt, info, keylen)
crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)
crypto.privateDecrypt(privateKey, buffer)
crypto.privateEncrypt(privateKey, buffer)
crypto.publicDecrypt(key, buffer)
crypto.publicEncrypt(key, buffer)
crypto.randomBytes(size[, callback])
crypto.randomFillSync(buffer[, offset][, size])
crypto.randomFill(buffer[, offset][, size], callback)
crypto.randomInt([min, ]max[, callback])
crypto.randomUUID([options])
crypto.scrypt(password, salt, keylen[, options], callback)
crypto.scryptSync(password, salt, keylen[, options])
crypto.secureHeapUsed()
crypto.setEngine(engine[, flags])
crypto.setFips(bool)
crypto.sign(algorithm, data, key[, callback])
crypto.subtle
crypto.timingSafeEqual(a, b)
crypto.verify(algorithm, data, key, signature[, callback])
crypto.webcrypto
- 備註
- 加密常數
- Crypto
-
► 索引
- 斷言測試
- 非同步內容追蹤
- 非同步掛鉤
- 緩衝區
- C++ 外掛程式
- 使用 Node-API 的 C/C++ 外掛程式
- C++ 嵌入式 API
- 子程序
- 叢集
- 命令列選項
- 主控台
- Corepack
- Crypto
- 偵錯程式
- 已棄用的 API
- 診斷頻道
- DNS
- 網域
- 錯誤
- 事件
- 檔案系統
- 全域變數
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:module
API - 模組:套件
- 網路
- 作業系統
- 路徑
- 效能掛鉤
- 權限
- 程序
- Punycode
- 查詢字串
- 讀取命令列
- REPL
- 報告
- 單一可執行應用程式
- 串流
- 字串解碼器
- 測試執行器
- 計時器
- TLS/SSL
- 追蹤事件
- TTY
- UDP/資料報
- URL
- 公用程式
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- 工作執行緒
- Zlib
- ► 其他版本
- ► 選項
Crypto#
原始碼: lib/crypto.js
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
import
或呼叫 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!');
}
類別:Certificate
#
SPKAC 是一種由 Netscape 最初實作的憑證簽署要求機制,並在 HTML5 的 keygen
元素中正式指定。
<keygen>
已自 HTML 5.2 起標示為已棄用,新專案不應再使用此元素。
node:crypto
模組提供 Certificate
類別,用於處理 SPKAC 資料。最常見的用法是處理由 HTML5 <keygen>
元素產生的輸出。Node.js 在內部使用 OpenSSL 的 SPKAC 實作。
靜態方法:Certificate.exportChallenge(spkac[, encoding])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<Buffer>
spkac
資料結構的挑戰元件,其中包括公開金鑰和挑戰。
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])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<Buffer>
spkac
資料結構的公開金鑰元件,其中包括公開金鑰和挑戰。
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])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<boolean> 如果指定的
spkac
資料結構有效,則傳回true
,否則傳回false
。
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#
作為舊版介面,可以建立 crypto.Certificate
類別的新執行個體,如下面的範例所示。
new crypto.Certificate()
#
Certificate
類別的執行個體可以使用 new
關鍵字建立,或以函數方式呼叫 crypto.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])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<Buffer>
spkac
資料結構的挑戰元件,其中包括公開金鑰和挑戰。
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])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<Buffer>
spkac
資料結構的公開金鑰元件,其中包括公開金鑰和挑戰。
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])
#
spkac
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>spkac
字串的 編碼。- 傳回:<boolean> 如果指定的
spkac
資料結構有效,則傳回true
,否則傳回false
。
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
類別:Cipher
#
Cipher
類別的執行個體用於加密資料。此類別可以用兩種方式之一使用
- 作為可讀寫的 串流,其中將未加密的純文字資料寫入以在可讀取端產生已加密的資料,或
- 使用
cipher.update()
和cipher.final()
方法來產生已加密的資料。
crypto.createCipher()
或 crypto.createCipheriv()
方法用於建立 Cipher
執行個體。Cipher
物件不能使用 new
關鍵字直接建立。
範例:將 Cipher
物件用作串流
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();
});
});
範例:使用 Cipher
和管道串流
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
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串> 任何剩餘的加密內容。如果指定
outputEncoding
,會傳回字串。如果未提供outputEncoding
,會傳回Buffer
。
呼叫 cipher.final()
方法後,Cipher
物件便無法再用於加密資料。嘗試呼叫 cipher.final()
超過一次將會導致擲回錯誤。
cipher.getAuthTag()
#
- 傳回:<Buffer> 當使用經過驗證的加密模式(目前支援
GCM
、CCM
、OCB
和chacha20-poly1305
)時,cipher.getAuthTag()
方法會傳回包含從給定資料計算而來的驗證標記的Buffer
。
僅應在使用 cipher.final()
方法完成加密後,才呼叫 cipher.getAuthTag()
方法。
如果在建立 cipher
執行個體時設定了 authTagLength
選項,此函式將會傳回剛好 authTagLength
個位元組。
cipher.setAAD(buffer[, options])
#
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>options
<物件>stream.transform
選項- 傳回:<Cipher> 相同的
Cipher
實例,用於方法串接。
使用經過驗證的加密模式時(目前支援 GCM
、CCM
、OCB
和 chacha20-poly1305
),cipher.setAAD()
方法會設定用於 其他驗證資料 (AAD) 輸入參數的值。
plaintextLength
選項對 GCM
和 OCB
為選用。使用 CCM
時,必須指定 plaintextLength
選項,其值必須與純文字的長度(以位元組為單位)相符。請參閱 CCM 模式。
必須在 cipher.update()
之前呼叫 cipher.setAAD()
方法。
cipher.setAutoPadding([autoPadding])
#
使用區塊加密演算法時,Cipher
類別會自動將輸入資料加上適當區塊大小的填補。若要停用預設填補,請呼叫 cipher.setAutoPadding(false)
。
當 autoPadding
為 false
時,整個輸入資料的長度必須為密碼區塊大小的倍數,否則 cipher.final()
會擲回錯誤。停用自動填補對非標準填補很有用,例如使用 0x0
取代 PKCS 填補。
必須在 cipher.final()
之前呼叫 cipher.setAutoPadding()
方法。
cipher.update(data[, inputEncoding][, outputEncoding])
#
data
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<字串> 資料的 編碼。outputEncoding
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串>
使用 data
更新密碼。如果提供了 inputEncoding
參數,data
參數會使用指定的編碼作為字串。如果未提供 inputEncoding
參數,data
必須是 Buffer
、TypedArray
或 DataView
。如果 data
是 Buffer
、TypedArray
或 DataView
,則會忽略 inputEncoding
。
outputEncoding
指定加密資料的輸出格式。如果指定了 outputEncoding
,會傳回使用指定編碼的字串。如果未提供 outputEncoding
,會傳回 Buffer
。
cipher.update()
方法可以在呼叫 cipher.final()
之前,使用新資料呼叫多次。在 cipher.final()
之後呼叫 cipher.update()
會導致發生錯誤。
類別:Decipher
#
Decipher
類別的執行個體用於解密資料。類別可以用兩種方式之一使用
- 作為可讀寫的 串流,其中會將純文字加密資料寫入,以在可讀取端產生未加密的資料,或
- 使用
decipher.update()
和decipher.final()
方法來產生未加密的資料。
方法 crypto.createDecipher()
或 crypto.createDecipheriv()
用於建立 Decipher
實例。Decipher
物件不能使用 new
關鍵字直接建立。
範例:將 Decipher
物件用作串流
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();
範例:使用 Decipher
和管線串流
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
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <string> 任何剩餘的解密內容。如果指定
outputEncoding
,傳回字串。如果未提供outputEncoding
,傳回Buffer
。
呼叫 decipher.final()
方法後,Decipher
物件就無法再用於解密資料。嘗試呼叫 decipher.final()
超過一次會導致擲回錯誤。
decipher.setAAD(buffer[, options])
#
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>options
<物件>stream.transform
選項- 傳回:<Decipher> 相同的 Decipher,用於方法串連。
使用經過驗證的加密模式(目前支援 GCM
、CCM
、OCB
和 chacha20-poly1305
)時,decipher.setAAD()
方法會設定用於附加驗證資料 (AAD) 輸入參數的值。
options
參數對 GCM
而言是可選的。使用 CCM
時,必須指定 plaintextLength
選項,且其值必須與密文長度(以位元組為單位)相符。請參閱 CCM 模式。
必須在 decipher.update()
之前呼叫 decipher.setAAD()
方法。
傳遞字串作為 buffer
時,請考慮 將字串作為輸入傳遞給加密 API 時的注意事項。
decipher.setAuthTag(buffer[, encoding])
#
buffer
<string> | <Buffer> | <ArrayBuffer> | <TypedArray> | <DataView>encoding
<string> 當buffer
為字串時使用的字串編碼。- 傳回:<Decipher> 相同的 Decipher,用於方法串連。
使用經過驗證的加密模式(目前支援 GCM
、CCM
、OCB
和 chacha20-poly1305
)時,decipher.setAuthTag()
方法用於傳入接收到的驗證標籤。如果未提供標籤,或密文文字遭到竄改,decipher.final()
會擲回例外,表示應捨棄密文文字,因為驗證失敗。如果標籤長度根據 NIST SP 800-38D 無效,或與 authTagLength
選項的值不符,decipher.setAuthTag()
會擲回錯誤。
對於 CCM
模式,必須在 decipher.update()
之前呼叫 decipher.setAuthTag()
方法;對於 GCM
和 OCB
模式以及 chacha20-poly1305
,則必須在 decipher.final()
之前呼叫。decipher.setAuthTag()
只能呼叫一次。
傳遞字串作為驗證標籤時,請考慮 將字串作為輸入傳遞給加密 API 時的注意事項。
decipher.setAutoPadding([autoPadding])
#
autoPadding
<布林值> 預設:true
- 傳回:<Decipher> 相同的 Decipher,用於方法串連。
當資料在沒有標準區塊填充的情況下加密時,呼叫 decipher.setAutoPadding(false)
會停用自動填充,以防止 decipher.final()
檢查和移除填充。
關閉自動填充僅在輸入資料長度為密碼區塊大小的倍數時才會運作。
decipher.setAutoPadding()
方法必須在 decipher.final()
之前呼叫。
decipher.update(data[, inputEncoding][, outputEncoding])
#
data
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>data
字串的 編碼。outputEncoding
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串>
使用 data
更新解碼器。如果給定 inputEncoding
參數,則 data
參數會使用指定的編碼作為字串。如果未給定 inputEncoding
參數,則 data
必須是 Buffer
。如果 data
是 Buffer
,則會忽略 inputEncoding
。
outputEncoding
指定加密資料的輸出格式。如果指定了 outputEncoding
,會傳回使用指定編碼的字串。如果未提供 outputEncoding
,會傳回 Buffer
。
decipher.update()
方法可以在呼叫 decipher.final()
之前使用新資料呼叫多次。在 decipher.final()
之後呼叫 decipher.update()
會導致擲回錯誤。
類別: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
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>otherPublicKey
字串的 編碼。outputEncoding
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串>
使用 otherPublicKey
作為另一方的公開金鑰來計算共享金鑰,並傳回計算出的共享金鑰。提供的金鑰會使用指定的 inputEncoding
來詮釋,而金鑰則會使用指定的 outputEncoding
來編碼。如果未提供 inputEncoding
,則預期 otherPublicKey
是 Buffer
、TypedArray
或 DataView
。
如果 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])
#
privateKey
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>privateKey
字串的 編碼。
設定 Diffie-Hellman 私密金鑰。如果提供 encoding
參數,則預期 privateKey
為字串。如果未提供 encoding
,則預期 privateKey
為 Buffer
、TypedArray
或 DataView
。
此函式不會自動計算相關的公開金鑰。可以使用 diffieHellman.setPublicKey()
或 diffieHellman.generateKeys()
手動提供公開金鑰或自動衍生公開金鑰。
diffieHellman.setPublicKey(publicKey[, encoding])
#
publicKey
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>publicKey
字串的 編碼。
設定 Diffie-Hellman 公開金鑰。如果提供 encoding
參數,則預期 publicKey
為字串。如果未提供 encoding
,則預期 publicKey
為 Buffer
、TypedArray
或 DataView
。
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]]])
#
金鑰
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>曲線
<字串>輸入編碼
<字串>金鑰
字串的 編碼。outputEncoding
<字串> 回傳值的 編碼。格式
<字串> 預設:'uncompressed'
- 傳回:<Buffer> | <字串>
將 金鑰
和 曲線
指定的 EC Diffie-Hellman 公開金鑰轉換成 格式
指定的格式。格式
參數指定點編碼,可以是 'compressed'
、'uncompressed'
或 'hybrid'
。提供的金鑰會使用指定的 輸入編碼
進行詮釋,而傳回的金鑰會使用指定的 輸出編碼
進行編碼。
使用 crypto.getCurves()
取得可用的曲線名稱清單。在最近的 OpenSSL 版本中,openssl ecparam -list_curves
也會顯示每個可用的橢圓曲線的名稱和說明。
如果未指定 格式
,點會以 'uncompressed'
格式傳回。
如果未提供 輸入編碼
,則預期 金鑰
為 Buffer
、TypedArray
或 DataView
。
範例(解壓縮金鑰)
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
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>otherPublicKey
字串的 編碼。outputEncoding
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串>
使用 otherPublicKey
作為另一方的公開金鑰來計算共用密鑰,並傳回計算出的共用密鑰。提供的金鑰會使用指定的 inputEncoding
來詮釋,而傳回的密鑰會使用指定的 outputEncoding
來編碼。如果未提供 inputEncoding
,則預期 otherPublicKey
是 Buffer
、TypedArray
或 DataView
。
如果 outputEncoding
給定字串,則會傳回字串;否則會傳回 Buffer
。
當 otherPublicKey
位於橢圓曲線之外時,ecdh.computeSecret
會擲出 ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY
錯誤。由於 otherPublicKey
通常是由遠端使用者透過不安全的網路提供,請務必適當地處理此例外狀況。
ecdh.generateKeys([encoding[, format]])
#
產生私密和公開 EC Diffie-Hellman 金鑰值,並以指定的 format
和 encoding
傳回公開金鑰。此金鑰應傳輸給另一方。
format
參數指定點編碼,可以是 'compressed'
或 'uncompressed'
。如果未指定 format
,則點會以 'uncompressed'
格式傳回。
如果提供 encoding
,則會傳回字串;否則會傳回 Buffer
。
ecdh.getPrivateKey([encoding])
#
如果指定 編碼
,會傳回字串;否則會傳回 Buffer
。
ecdh.getPublicKey([編碼][, 格式])
#
encoding
<string> 傳回值的 編碼。格式
<字串> 預設:'uncompressed'
- 傳回:<Buffer> | <string> 指定
編碼
和格式
中的 EC Diffie-Hellman 公開金鑰。
格式
參數指定點編碼,可以是 'compressed'
或 'uncompressed'
。如果未指定 格式
,點會以 'uncompressed'
格式傳回。
如果指定 編碼
,會傳回字串;否則會傳回 Buffer
。
ecdh.setPrivateKey(privateKey[, 編碼])
#
privateKey
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>privateKey
字串的 編碼。
設定 EC Diffie-Hellman 私密金鑰。如果提供 編碼
,privateKey
預期為字串;否則 privateKey
預期為 Buffer
、TypedArray
或 DataView
。
如果 privateKey
對建立 ECDH
物件時指定的曲線無效,會擲回錯誤。設定私密金鑰後,相關的公開點 (金鑰) 也會產生並設定在 ECDH
物件中。
ecdh.setPublicKey(publicKey[, 編碼])
#
publicKey
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string>publicKey
字串的 編碼。
設定 EC Diffie-Hellman 公開金鑰。如果提供 編碼
,publicKey
預期為字串;否則預期為 Buffer
、TypedArray
或 DataView
。
通常沒有理由呼叫這個方法,因為 ECDH
只需要私密金鑰和另一方的公開金鑰來計算共享的秘密。通常會呼叫 ecdh.generateKeys()
或 ecdh.setPrivateKey()
。ecdh.setPrivateKey()
方法會嘗試產生與正在設定的私密金鑰相關聯的公開點/金鑰。
範例 (取得共享的秘密)
const {
createECDH,
createHash,
} = await import('node:crypto');
const alice = createECDH('secp256k1');
const bob = createECDH('secp256k1');
// This is a shortcut way of specifying one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
createHash('sha256').update('alice', 'utf8').digest(),
);
// Bob uses a newly generated cryptographically strong
// pseudorandom key pair
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 shared secret value
console.log(aliceSecret === bobSecret);
const {
createECDH,
createHash,
} = require('node:crypto');
const alice = createECDH('secp256k1');
const bob = createECDH('secp256k1');
// This is a shortcut way of specifying one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
createHash('sha256').update('alice', 'utf8').digest(),
);
// Bob uses a newly generated cryptographically strong
// pseudorandom key pair
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 shared secret value
console.log(aliceSecret === bobSecret);
類別: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])
#
options
<物件>stream.transform
選項- 傳回:<Hash>
建立新的 Hash
物件,其中包含目前 Hash
物件內部狀態的深度拷貝。
選用的 options
參數控制串流行為。對於 XOF 雜湊函數(例如 'shake256'
),outputLength
選項可用於指定所需的輸出長度(以位元組為單位)。
在呼叫 Hash
物件的 hash.digest()
方法後,嘗試拷貝 Hash
物件時會擲回錯誤。
// 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
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>data
字串的 編碼。
使用給定的 data
更新雜湊內容,其編碼在 inputEncoding
中給出。如果未提供 encoding
,且 data
為字串,則強制使用 'utf8'
編碼。如果 data
為 Buffer
、TypedArray
或 DataView
,則會忽略 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([編碼])
#
計算使用 hmac.update()
傳遞的所有資料的 HMAC 摘要。如果提供 編碼
,則會傳回字串;否則會傳回 Buffer
;
在呼叫 hmac.digest()
之後,Hmac
物件無法再次使用。多次呼叫 hmac.digest()
會導致擲回錯誤。
hmac.update(資料[, 輸入編碼])
#
data
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>data
字串的 編碼。
使用給定的 資料
更新 Hmac
內容,其編碼在 輸入編碼
中給出。如果未提供 編碼
,且 資料
為字串,則強制執行 'utf8'
編碼。如果 資料
為 Buffer
、TypedArray
或 DataView
,則會忽略 輸入編碼
。
當資料串流時,可以使用新資料呼叫此方法多次。
類別:KeyObject
#
Node.js 使用 KeyObject
類別來表示對稱或非對稱金鑰,且每種類型的金鑰都會公開不同的函式。crypto.createSecretKey()
、crypto.createPublicKey()
和 crypto.createPrivateKey()
方法用於建立 KeyObject
執行個體。KeyObject
物件不得使用 new
關鍵字直接建立。
由於改進的安全功能,大多數應用程式應考慮使用新的 KeyObject
API,而不是傳遞金鑰作為字串或 Buffer
。
KeyObject
執行個體可透過 postMessage()
傳遞給其他執行緒。接收者會取得複製的 KeyObject
,且 KeyObject
不需要列在 transferList
參數中。
靜態方法:KeyObject.from(金鑰)
#
key
<CryptoKey>- 傳回:<KeyObject>
範例:將 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
#
此屬性僅存在於非對稱金鑰中。此物件會根據金鑰類型包含金鑰相關資訊。透過此屬性取得的資訊無法用於唯一識別金鑰或危害金鑰安全性。
對於 RSA-PSS 金鑰,如果金鑰資料包含 RSASSA-PSS-params
序列,則會設定 hashAlgorithm
、mgf1HashAlgorithm
和 saltLength
屬性。
其他金鑰詳細資訊可能會透過此 API 使用其他屬性公開。
keyObject.asymmetricKeyType
#
對於非對稱金鑰,此屬性代表金鑰的類型。支援的金鑰類型為
'rsa'
(OID 1.2.840.113549.1.1.1)'rsa-pss'
(OID 1.2.840.113549.1.1.10)'dsa'
(OID 1.2.840.10040.4.1)'ec'
(OID 1.2.840.10045.2.1)'x25519'
(OID 1.3.101.110)'x448'
(OID 1.3.101.111)'ed25519'
(OID 1.3.101.112)'ed448'
(OID 1.3.101.113)'dh'
(OID 1.2.840.113549.1.3.1)
此屬性對於無法辨識的 KeyObject
類型和對稱金鑰為 undefined
。
keyObject.export([options])
#
對於對稱金鑰,可以使用下列編碼選項
格式
:<字串> 必須為'buffer'
(預設) 或'jwk'
。
對於公開金鑰,可以使用下列編碼選項
對於私鑰,可以使用下列編碼選項
類型
:<字串> 必須為'pkcs1'
(僅 RSA)、'pkcs8'
或'sec1'
(僅 EC) 之一。格式
:<字串> 必須為'pem'
、'der'
或'jwk'
。密碼
:<字串> 如果有指定,私鑰將會使用指定的密碼
和通行碼
透過 PKCS#5 v2.0 基於密碼的加密進行加密。通行碼
:<字串> | <Buffer> 用於加密的通行碼,請參閱密碼
。
結果類型取決於所選的編碼格式,如果是 PEM,結果會是字串;如果是 DER,結果會是包含 DER 編碼資料的緩衝區;如果是 JWK,結果會是物件。
如果選取 JWK 編碼格式,所有其他編碼選項都會被忽略。
PKCS#1、SEC1 和 PKCS#8 類型的金鑰可以使用 cipher
和 format
選項組合進行加密。PKCS#8 type
可與任何 format
搭配使用,透過指定 cipher
來加密任何金鑰演算法 (RSA、EC 或 DH)。僅當使用 PEM format
時,PKCS#1 和 SEC1 才能透過指定 cipher
來加密。為了達到最大的相容性,請對加密的私密金鑰使用 PKCS#8。由於 PKCS#8 定義了自己的加密機制,因此在加密 PKCS#8 金鑰時不支援 PEM 層級加密。請參閱 RFC 5208 以取得 PKCS#8 加密資訊,以及 RFC 1421 以取得 PKCS#1 和 SEC1 加密資訊。
keyObject.equals(otherKeyObject)
#
otherKeyObject
:<KeyObject> 要與keyObject
比較的KeyObject
。- 傳回:<boolean>
傳回 true
或 false
,視金鑰的類型、值和參數是否完全相同而定。此方法並非 定時攻擊。
keyObject.symmetricKeySize
#
對於機密金鑰,此屬性代表金鑰的大小(以位元組為單位)。此屬性對非對稱金鑰而言為 undefined
。
keyObject.type
#
根據此 KeyObject
的類型,此屬性對機密(對稱)金鑰而言為 'secret'
,對公開(非對稱)金鑰而言為 'public'
,對私密(非對稱)金鑰而言為 'private'
。
類別:Sign
#
Sign
類別是產生簽章的工具程式。它可以透過兩種方式使用
- 作為可寫入的 串流,其中會寫入要簽署的資料,而
sign.sign()
方法用於產生並傳回簽章,或 - 使用
sign.update()
和sign.sign()
方法來產生簽章。
使用 crypto.createSign()
方法來建立 Sign
執行個體。引數是雜湊函數的字串名稱。不得使用 new
關鍵字直接建立 Sign
物件。
範例:使用 Sign
和 Verify
物件作為串流
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])
#
privateKey
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>outputEncoding
<字串> 回傳值的 編碼。- 傳回:<Buffer> | <字串>
計算透過 sign.update()
或 sign.write()
傳遞所有資料的簽章。
如果 privateKey
不是 KeyObject
,這個函式會像 privateKey
已傳遞至 crypto.createPrivateKey()
一樣運作。如果它是一個物件,可以傳遞下列額外屬性
-
dsaEncoding
<字串> 對於 DSA 和 ECDSA,這個選項會指定已產生簽章的格式。它可以是下列其中之一'der'
(預設):DER 編碼 ASN.1 簽章結構編碼(r, s)
。'ieee-p1363'
:簽章格式r || s
,如 IEEE-P1363 中所建議。
-
padding
<整數> 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
<整數> 當填充是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
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>data
字串的 編碼。
使用提供的 data
更新 Sign
內容,其編碼在 inputEncoding
中提供。如果未提供 encoding
,且 data
為字串,則強制執行 'utf8'
編碼。如果 data
為 Buffer
、TypedArray
或 DataView
,則會忽略 inputEncoding
。
當資料串流時,可以使用新資料呼叫此方法多次。
類別:Verify
#
Verify
類別是驗證簽章的工具程式。它可以用兩種方式之一使用
- 作為可寫入 串流,其中寫入的資料用於驗證提供的簽章,或
- 使用
verify.update()
和verify.verify()
方法驗證簽章。
crypto.createVerify()
方法用於建立 Verify
執行個體。Verify
物件不得使用 new
關鍵字直接建立。
請參閱 Sign
以取得範例。
verify.update(data[, inputEncoding])
#
data
<字串> | <Buffer> | <TypedArray> | <DataView>inputEncoding
<string>data
字串的 編碼。
使用給定的 data
更新 Verify
內容,編碼在 inputEncoding
中給出。如果未提供 inputEncoding
,且 data
為字串,則強制執行 'utf8'
編碼。如果 data
是 Buffer
、TypedArray
或 DataView
,則會忽略 inputEncoding
。
當資料串流時,可以使用新資料呼叫此方法多次。
verify.verify(object, signature[, signatureEncoding])
#
object
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>signature
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>signatureEncoding
<string>signature
字串的 編碼。- 傳回:<boolean>
true
或false
,視簽章對資料和公開金鑰的有效性而定。
使用指定的 object
和 signature
驗證提供的資料。
如果 object
不是 KeyObject
,此函式會像將 object
傳遞給 crypto.createPublicKey()
一樣運作。如果它是一個物件,可以傳遞下列額外的屬性
-
dsaEncoding
<string> 對於 DSA 和 ECDSA,此選項會指定簽章的格式。它可以是下列其中一個'der'
(預設):DER 編碼 ASN.1 簽章結構編碼(r, s)
。'ieee-p1363'
:簽章格式r || s
,如 IEEE-P1363 中所建議。
-
padding
<整數> 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
會是一個字串;否則預期 signature
會是一個 Buffer
、TypedArray
或 DataView
。
在呼叫 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)
#
buffer
<字串> | <TypedArray> | <Buffer> | <DataView> PEM 或 DER 編碼的 X509 憑證。
x509.ca
#
- 類型:<布林值>如果這是憑證授權 (CA) 憑證,將會是
true
。
x509.checkEmail(email[, options])
#
email
<字串>options
<Object>subject
<string>'default'
、'always'
或'never'
。預設:'default'
。
- 傳回:<string> | <undefined> 如果憑證與電子郵件地址相符,傳回
email
;如果不相符,傳回undefined
。
檢查憑證是否與指定的電子郵件地址相符。
如果 'subject'
選項未定義或設定為 'default'
,則只有在主旨備用名稱延伸模組不存在或不包含任何電子郵件地址時,才會考慮憑證主旨。
如果 'subject'
選項設定為 'always'
,且主旨備用名稱延伸模組不存在或不包含相符的電子郵件地址,則會考慮憑證主旨。
如果 'subject'
選項設定為 'never'
,則永遠不會考慮憑證主旨,即使憑證不包含任何主旨備用名稱。
x509.checkHost(name[, options])
#
檢查憑證是否與指定的網域名稱相符。
如果憑證與指定的網域名稱相符,則傳回相符的主體名稱。傳回的名稱可能是完全相符(例如 foo.example.com
),或可能包含萬用字元(例如 *.example.com
)。由於網域名稱比對不區分大小寫,因此傳回的主體名稱可能也會與指定的 name
在大小寫上有所不同。
如果 'subject'
選項未定義或設為 'default'
,則只有在主體備用名稱延伸模組不存在或不包含任何 DNS 名稱時,才會考慮憑證主體。此行為與 RFC 2818(「透過 TLS 的 HTTP」)一致。
如果 'subject'
選項設為 'always'
,且主體備用名稱延伸模組不存在或不包含相符的 DNS 名稱,則會考慮憑證主體。
如果 'subject'
選項設定為 'never'
,則永遠不會考慮憑證主旨,即使憑證不包含任何主旨備用名稱。
x509.checkIP(ip)
#
檢查憑證是否與指定的 IP 位址(IPv4 或 IPv6)相符。
只考慮 RFC 5280 iPAddress
主旨備用名稱,且它們必須與指定的 ip
位址完全相符。其他主旨備用名稱以及憑證的主旨欄位將會被忽略。
x509.checkIssued(otherCert)
#
otherCert
<X509Certificate>- 傳回:<boolean>
檢查此憑證是否由指定的 otherCert
簽發。
x509.checkPrivateKey(privateKey)
#
privateKey
<KeyObject> 私密金鑰。- 傳回:<boolean>
檢查此憑證的公開金鑰是否與指定的私密金鑰一致。
x509.fingerprint
#
- 類型:<string>
此憑證的 SHA-1 指紋。
由於 SHA-1 在密碼學上已遭破解,且 SHA-1 的安全性明顯低於一般用於簽署憑證的演算法,因此請考慮改用 x509.fingerprint256
。
x509.fingerprint256
#
- 類型:<string>
此憑證的 SHA-256 指紋。
x509.fingerprint512
#
- 類型:<string>
此憑證的 SHA-512 指紋。
由於計算 SHA-256 指紋通常較快,且其大小僅為 SHA-512 指紋的一半,因此 x509.fingerprint256
可能會是較好的選擇。雖然 SHA-512 通常會提供較高層級的安全性,但 SHA-256 的安全性與一般用於簽署憑證的大多數演算法相符。
x509.infoAccess
#
- 類型:<string>
憑證的授權資訊存取延伸模組的文字表示形式。
這是一個以換行符號分隔的存取說明清單。每一行都以存取方法和存取位置的種類開頭,後面接著冒號和與存取位置相關聯的值。
在表示存取方法和存取位置種類的前置詞之後,每一行的剩餘部分可能會用引號括起來,以表示該值是 JSON 字串文字。為了向後相容,Node.js 只有在必要時才會在此屬性中使用 JSON 字串文字,以避免產生歧義。第三方程式碼應準備好處理兩種可能的輸入格式。
x509.issuer
#
- 類型:<string>
此憑證中包含的發行者識別。
x509.issuerCertificate
#
發行者憑證,如果發行者憑證不可用,則為 undefined
。
x509.extKeyUsage
#
- 類型:<string[]>
詳細說明此憑證的主要延伸用法的陣列。
x509.publicKey
#
- 類型:<KeyObject>
此憑證的公開金鑰 <KeyObject>。
x509.raw
#
- 類型:<Buffer>
包含此憑證的 DER 編碼的 Buffer
。
x509.serialNumber
#
- 類型:<string>
此憑證的序號。
序號是由憑證授權機構指派,並不會唯一識別憑證。請考慮使用 x509.fingerprint256
作為唯一的識別碼。
x509.subject
#
- 類型:<string>
此憑證的完整主旨。
x509.subjectAltName
#
- 類型:<string>
為此憑證指定的替代主旨名稱。
這是替代主旨名稱的逗號分隔清單。每個項目都從識別替代主旨名稱類型的字串開始,後接冒號和與項目關聯的值。
早期版本的 Node.js 錯誤地假設在兩個字元序列 ', '
處拆分此屬性是安全的(請參閱 CVE-2021-44532)。然而,惡意和合法的憑證都可能包含在表示為字串時包含此序列的替代主旨名稱。
在表示條目類型的字首之後,每個條目的其餘部分可能會用引號括起來,以表示值是 JSON 字串文字。為了向後相容,Node.js 僅在必要時才會在此屬性中使用 JSON 字串文字,以避免歧義。第三方程式碼應準備好處理兩種可能的條目格式。
x509.toJSON()
#
- 類型:<string>
沒有 X509 憑證的標準 JSON 編碼。toJSON()
方法會傳回包含 PEM 編碼憑證的字串。
x509.toLegacyObject()
#
- 類型:<Object>
使用舊版憑證物件編碼傳回有關此憑證的資訊。
x509.toString()
#
- 類型:<string>
傳回 PEM 編碼的憑證。
x509.validFrom
#
- 類型:<string>
此憑證有效的日期/時間。
x509.validTo
#
- 類型:<string>
此憑證有效的日期/時間。
x509.verify(publicKey)
#
publicKey
<KeyObject> 公開金鑰。- 傳回:<boolean>
驗證此憑證是由指定的公開金鑰簽署。不會對憑證執行任何其他驗證檢查。
node:crypto
模組方法和屬性#
crypto.constants
#
一個包含用於加密和安全相關操作的常用常數的物件。目前定義的特定常數已在 加密常數 中說明。
crypto.fips
#
用於檢查和控制目前是否正在使用符合 FIPS 的加密提供者的屬性。設為 true 需要 Node.js 的 FIPS 組建。
此屬性已棄用。請改用 crypto.setFips()
和 crypto.getFips()
。
crypto.checkPrime(candidate[, options], callback)
#
candidate
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint> 一個可能的質數,編碼為任意長度的 big endian 八位元組序列。options
<Object>checks
<number> 要執行的 Miller-Rabin 機率質數迭代次數。當值為0
(零)時,將使用會產生最多 2-64 的假陽性率的檢查次數,用於隨機輸入。選擇檢查次數時必須小心。請參閱 OpenSSL 文件中的BN_is_prime_ex
函數nchecks
選項,以取得更多詳細資訊。預設值:0
callback
<Function>
檢查 candidate
的質數性。
crypto.checkPrimeSync(candidate[, options])
#
candidate
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint> 一個可能的質數,編碼為任意長度的 big endian 八位元組序列。options
<Object>checks
<number> 要執行的 Miller-Rabin 機率質數迭代次數。當值為0
(零)時,將使用會產生最多 2-64 的假陽性率的檢查次數,用於隨機輸入。選擇檢查次數時必須小心。請參閱 OpenSSL 文件中的BN_is_prime_ex
函數nchecks
選項,以取得更多詳細資訊。預設值:0
- 傳回值:<boolean> 如果候選值是質數,且錯誤機率低於
0.25 ** options.checks
,則為true
。
檢查 candidate
的質數性。
crypto.createCipher(algorithm, password[, options])
#
crypto.createCipheriv()
。algorithm
<string>password
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>options
<物件>stream.transform
選項- 傳回值:<Cipher>
建立並傳回使用指定 algorithm
和 password
的 Cipher
物件。
options
參數控制串流行為,而且是選用的,除非在 CCM 或 OCB 模式(例如 'aes-128-ccm'
)的密碼中使用。在這種情況下,authTagLength
選項是必要的,並以位元組為單位指定驗證標記的長度,請參閱 CCM 模式。在 GCM 模式中,authTagLength
選項不是必要的,但可用於設定 getAuthTag()
將傳回的驗證標記長度,預設為 16 個位元組。對於 chacha20-poly1305
,authTagLength
選項預設為 16 個位元組。
algorithm
依賴於 OpenSSL,範例為 'aes192'
等。在最近的 OpenSSL 版本中,openssl list -cipher-algorithms
會顯示可用的密碼演算法。
password
用於衍生密碼金鑰和初始化向量 (IV)。值必須是 'latin1'
編碼字串、Buffer
、TypedArray
或 DataView
。
此函式在語意上對於所有支援的密碼都是不安全的,而且對於計數器模式(例如 CTR、GCM 或 CCM)的密碼有致命的缺陷。
crypto.createCipher()
的實作使用 OpenSSL 函式 EVP_BytesToKey
衍生金鑰,摘要演算法設定為 MD5,一次反覆運算,而且沒有鹽。由於沒有鹽,因此相同的密碼總是會建立相同的金鑰,這會允許字典攻擊。反覆運算次數少和非密碼安全雜湊演算法允許非常快速的密碼測試。
根據 OpenSSL 的建議,改用較新的演算法,取代 EVP_BytesToKey
,建議開發人員自行使用 crypto.scrypt()
衍生金鑰和 IV,並使用 crypto.createCipheriv()
建立 Cipher
物件。使用者不應在 crypto.createCipher()
中使用計數器模式的密碼(例如 CTR、GCM 或 CCM)。為了避免 IV 重複使用的風險,導致漏洞,因此在使用這些模式時會發出警告。關於 GCM 中 IV 重複使用的情況,請參閱 Nonce-Disrespecting Adversaries 以取得詳細資訊。
crypto.createCipheriv(algorithm, key, iv[, options])
#
algorithm
<string>key
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>iv
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <null>options
<物件>stream.transform
選項- 傳回值:<Cipher>
建立並傳回 Cipher
物件,其中包含指定的 algorithm
、key
和初始化向量 (iv
)。
options
參數控制串流行為,而且是選用的,除非在 CCM 或 OCB 模式(例如 'aes-128-ccm'
)的密碼中使用。在這種情況下,authTagLength
選項是必要的,並以位元組為單位指定驗證標記的長度,請參閱 CCM 模式。在 GCM 模式中,authTagLength
選項不是必要的,但可用於設定 getAuthTag()
將傳回的驗證標記長度,預設為 16 個位元組。對於 chacha20-poly1305
,authTagLength
選項預設為 16 個位元組。
algorithm
依賴於 OpenSSL,範例為 'aes192'
等。在最近的 OpenSSL 版本中,openssl list -cipher-algorithms
會顯示可用的密碼演算法。
key
是 algorithm
使用的原始金鑰,而 iv
是 初始化向量。兩個參數都必須是 'utf8'
編碼字串、緩衝區、TypedArray
或 DataView
。key
可以選擇為類型為 secret
的 KeyObject
。如果密碼不需要初始化向量,iv
可以為 null
。
傳遞字串作為 key
或 iv
時,請考慮 將字串用作密碼編譯 API 輸入時的注意事項。
初始化向量應難以預測且獨一無二;理想情況下,它們會是密碼隨機數。它們不必是機密:IV 通常只會加入未加密的密文訊息。聽起來似乎矛盾,有些東西必須難以預測且獨一無二,但不必是機密;請記住,攻擊者不能提前預測特定 IV 會是什麼。
crypto.createDecipher(algorithm, password[, options])
#
crypto.createDecipheriv()
。algorithm
<string>password
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>options
<物件>stream.transform
選項- 傳回:<Decipher>
建立並傳回一個 Decipher
物件,使用指定的 algorithm
和 password
(金鑰)。
options
參數控制串流行為,而且是選用的,除非使用 CCM 或 OCB 模式(例如 'aes-128-ccm'
)的密碼。在這種情況下,authTagLength
選項是必要的,並以位元組為單位指定驗證標記的長度,請參閱 CCM 模式。對於 chacha20-poly1305
,authTagLength
選項預設為 16 個位元組。
此函式在語意上對於所有支援的密碼都是不安全的,而且對於計數器模式(例如 CTR、GCM 或 CCM)的密碼有致命的缺陷。
crypto.createDecipher()
的實作使用 OpenSSL 函數 EVP_BytesToKey
衍生金鑰,摘要演算法設定為 MD5,一次反覆運算,且沒有鹽值。由於沒有鹽值,因此允許字典攻擊,因為相同的密碼總是會建立相同的金鑰。反覆運算次數少且非密碼編譯安全雜湊演算法允許非常快速地測試密碼。
依據 OpenSSL 建議,使用較現代的演算法取代 EVP_BytesToKey
,建議開發人員使用 crypto.scrypt()
自行衍生金鑰和 IV,並使用 crypto.createDecipheriv()
建立 Decipher
物件。
crypto.createDecipheriv(algorithm, key, iv[, options])
#
algorithm
<string>key
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>iv
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <null>options
<物件>stream.transform
選項- 傳回:<Decipher>
建立並傳回一個 Decipher
物件,使用指定的 algorithm
、key
和初始化向量 (iv
)。
options
引數控制串流行為,並且是選用的,除非在 CCM 或 OCB 模式中使用密碼 (例如 'aes-128-ccm'
)。在這種情況下,authTagLength
選項是必要的,並以位元組為單位指定驗證標記的長度,請參閱 CCM 模式。在 GCM 模式中,authTagLength
選項不是必要的,但可用於將可接受的驗證標記限制為具有指定長度的驗證標記。對於 chacha20-poly1305
,authTagLength
選項預設為 16 位元組。
algorithm
依賴於 OpenSSL,範例為 'aes192'
等。在最近的 OpenSSL 版本中,openssl list -cipher-algorithms
會顯示可用的密碼演算法。
key
是 algorithm
使用的原始金鑰,而 iv
是 初始化向量。兩個參數都必須是 'utf8'
編碼字串、緩衝區、TypedArray
或 DataView
。key
可以選擇為類型為 secret
的 KeyObject
。如果密碼不需要初始化向量,iv
可以為 null
。
傳遞字串作為 key
或 iv
時,請考慮 將字串用作密碼編譯 API 輸入時的注意事項。
初始化向量應難以預測且獨一無二;理想情況下,它們會是密碼隨機數。它們不必是機密:IV 通常只會加入未加密的密文訊息。聽起來似乎矛盾,有些東西必須難以預測且獨一無二,但不必是機密;請記住,攻擊者不能提前預測特定 IV 會是什麼。
crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])
#
prime
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>primeEncoding
<string>prime
字串的 編碼。generator
<number> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 預設值:2
generatorEncoding
<string>generator
字串的 編碼。- 傳回:<DiffieHellman>
使用提供的 prime
和一個特定的選用 generator
建立一個 DiffieHellman
金鑰交換物件。
generator
參數可以是數字、字串或 Buffer
。如果未指定 generator
,則使用值 2
。
如果指定 primeEncoding
,則預期 prime
是字串;否則預期是 Buffer
、TypedArray
或 DataView
。
如果指定了 generatorEncoding
,則預期 generator
為字串;否則預期為數字、Buffer
、TypedArray
或 DataView
。
crypto.createDiffieHellman(primeLength[, generator])
#
primeLength
<number>generator
<number> 預設值:2
- 傳回:<DiffieHellman>
建立 DiffieHellman
金鑰交換物件,並使用選用的特定數字 generator
產生 primeLength
位元的質數。如果未指定 generator
,則使用值 2
。
crypto.createDiffieHellmanGroup(name)
#
name
<string>- 傳回:<DiffieHellmanGroup>
crypto.createECDH(curveName)
#
使用 curveName
字串指定的預先定義曲線,建立橢圓曲線 Diffie-Hellman (ECDH
) 金鑰交換物件。使用 crypto.getCurves()
取得可用曲線名稱清單。在最近的 OpenSSL 版本中,openssl ecparam -list_curves
也會顯示每個可用橢圓曲線的名稱和說明。
crypto.createHash(algorithm[, options])
#
algorithm
<string>options
<物件>stream.transform
選項- 傳回:<Hash>
建立並傳回 Hash
物件,可使用指定的 algorithm
產生雜湊摘要。選用的 options
參數控制串流行為。對於 XOF 雜湊函數,例如 'shake256'
,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])
#
algorithm
<string>key
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>options
<物件>stream.transform
選項encoding
<string> 當key
是字串時要使用的字串編碼。
- 傳回:<Hmac>
建立並傳回 Hmac
物件,其使用指定的 algorithm
和 key
。選用的 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)
#
key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>key
: <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <Object> 金鑰資料,PEM、DER 或 JWK 格式。format
: <string> 必須是'pem'
、'der'
或'jwk'
。預設:'pem'
。type
: <string> 必須是'pkcs1'
、'pkcs8'
或'sec1'
。僅當format
為'der'
時才需要此選項,否則會忽略。passphrase
: <string> | <Buffer> 用於解密的密碼。encoding
: <string> 當key
為字串時要使用的字串編碼。
- 傳回:<KeyObject>
建立並傳回包含私鑰的新金鑰物件。如果 key
是字串或 Buffer
,則假設 format
為 'pem'
;否則,key
必須是具有上述屬性的物件。
如果私鑰已加密,則必須指定 passphrase
。密碼長度限制為 1024 個位元組。
crypto.createPublicKey(key)
#
key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>key
: <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <Object> 金鑰資料,PEM、DER 或 JWK 格式。format
:<string> 必須為'pem'
、'der'
或'jwk'
。預設:'pem'
。type
:<string> 必須為'pkcs1'
或'spki'
。此選項僅在format
為'der'
時才需要,否則會被忽略。encoding
<string> 當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])
#
金鑰
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>encoding
<string> 當key
是字串時的字串編碼。- 傳回:<KeyObject>
建立並傳回一個新的金鑰物件,其中包含用於對稱加密或 Hmac
的秘密金鑰。
crypto.createSign(algorithm[, options])
#
algorithm
<string>options
<Object>stream.Writable
選項- 傳回:<Sign>
建立並傳回一個使用給定 algorithm
的 Sign
物件。使用 crypto.getHashes()
取得可用摘要演算法的名稱。選用的 options
參數控制 stream.Writable
行為。
在某些情況下,可以使用簽章演算法的名稱(例如 'RSA-SHA256'
)而不是摘要演算法來建立 Sign
執行個體。這將使用對應的摘要演算法。這並不適用於所有簽章演算法,例如 'ecdsa-with-SHA256'
,因此最好總是使用摘要演算法名稱。
crypto.createVerify(algorithm[, options])
#
algorithm
<string>options
<Object>stream.Writable
選項- 傳回:<Verify>
建立並傳回一個使用給定演算法的 Verify
物件。使用 crypto.getHashes()
取得可用簽章演算法名稱的陣列。選用的 options
參數控制 stream.Writable
行為。
在某些情況下,可以使用簽章演算法的名稱(例如 'RSA-SHA256'
)而不是摘要演算法來建立 Verify
執行個體。這將使用對應的摘要演算法。這並不適用於所有簽章演算法,例如 'ecdsa-with-SHA256'
,因此最好總是使用摘要演算法名稱。
crypto.diffieHellman(options)
#
options
: <物件>privateKey
: <KeyObject>publicKey
: <KeyObject>
- 傳回: <Buffer>
根據 privateKey
和 publicKey
計算 Diffie-Hellman 祕密。兩個金鑰必須具有相同的 asymmetricKeyType
,而 asymmetricKeyType
必須為下列其中一個:'dh'
(適用於 Diffie-Hellman)、'ec'
(適用於 ECDH)、'x448'
或 'x25519'
(適用於 ECDH-ES)。
crypto.hash(algorith, data[, outputEncoding])
#
algorithm
<string> | <undefined>data
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 當data
為字串時,會在進行雜湊處理之前將其編碼為 UTF-8。如果需要為字串輸入使用不同的輸入編碼,使用者可以透過使用TextEncoder
或Buffer.from()
將字串編碼為TypedArray
,然後將編碼的TypedArray
傳入這個 API 中。outputEncoding
<string> | <undefined> 編碼,用於編碼傳回的摘要。預設值:'hex'
。- 傳回: <string> | <Buffer>
一個用於建立資料一次性雜湊摘要的工具程式。當雜湊較少量的資料 (<= 5MB) 且資料容易取得時,它可能比物件導向的 crypto.createHash()
更快。如果資料量可能很大或資料是串流的,建議改用 crypto.createHash()
。
algorithm
取決於平台上 OpenSSL 版本支援的可用演算法。範例包括 'sha256'
、'sha512'
等。在 OpenSSL 的最新版本中,openssl list -digest-algorithms
會顯示可用的摘要演算法。
範例
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.generateKey(type, options, callback)
#
type
: <字串> 已產生機密金鑰的預定用途。目前可接受的值為'hmac'
和'aes'
。options
: <物件>length
: <數字> 要產生的金鑰的位元長度。此值必須大於 0。- 如果
type
為'hmac'
,最小值為 8,最大長度為 231-1。如果值不是 8 的倍數,產生的金鑰將會被截斷為Math.floor(length / 8)
。 - 如果
type
為'aes'
,長度必須為128
、192
或256
之一。
- 如果
callback
: <函式>
非同步產生一個新的隨機機密金鑰,長度為指定的 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)
#
type
:<字串> 必須為'rsa'
、'rsa-pss'
、'dsa'
、'ec'
、'ed25519'
、'ed448'
、'x25519'
、'x448'
或'dh'
。options
: <物件>modulusLength
:<數字> 金鑰大小(以位元為單位)(RSA、DSA)。publicExponent
:<數字> 公用指數 (RSA)。預設:0x10001
。hashAlgorithm
:<字串> 訊息摘要名稱(RSA-PSS)。mgf1HashAlgorithm
:<字串> MGF1 使用的訊息摘要名稱(RSA-PSS)。saltLength
:<數字> 最小鹽長度(以位元組為單位)(RSA-PSS)。divisorLength
:<數字>q
的大小(以位元為單位)(DSA)。namedCurve
:<字串> 要使用的曲線名稱 (EC)。prime
:<Buffer> 質數參數 (DH)。primeLength
:<數字> 質數長度(以位元為單位)(DH)。generator
:<數字> 自訂產生器 (DH)。預設:2
。groupName
:<字串> Diffie-Hellman 群組名稱 (DH)。請參閱crypto.getDiffieHellman()
。paramEncoding
:<字串> 必須為'named'
或'explicit'
(EC)。預設:'named'
。publicKeyEncoding
:<物件> 請參閱keyObject.export()
。privateKeyEncoding
:<物件> 請參閱keyObject.export()
。
callback
: <函式>err
: <錯誤>publicKey
:<字串> | <Buffer> | <KeyObject>privateKey
:<字串> | <Buffer> | <KeyObject>
產生給定 type
的新的非對稱金鑰對。目前支援 RSA、RSA-PSS、DSA、EC、Ed25519、Ed448、X25519、X448 和 DH。
如果指定了 publicKeyEncoding
或 privateKeyEncoding
,此函式會像對其結果呼叫 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
設為 undefined
,而 publicKey
/ privateKey
則代表產生的金鑰對。
如果此方法以其 util.promisify()
版本呼叫,它會傳回一個 Promise
,其中包含一個具有 publicKey
和 privateKey
屬性的 Object
。
crypto.generateKeyPairSync(type, options)
#
type
:<字串> 必須為'rsa'
、'rsa-pss'
、'dsa'
、'ec'
、'ed25519'
、'ed448'
、'x25519'
、'x448'
或'dh'
。options
: <物件>modulusLength
:<數字> 金鑰大小(以位元為單位)(RSA、DSA)。publicExponent
:<數字> 公用指數 (RSA)。預設:0x10001
。hashAlgorithm
:<字串> 訊息摘要名稱(RSA-PSS)。mgf1HashAlgorithm
:<字串> MGF1 使用的訊息摘要名稱(RSA-PSS)。saltLength
:<數字> 最小鹽長度(以位元組為單位)(RSA-PSS)。divisorLength
:<數字>q
的大小(以位元為單位)(DSA)。namedCurve
:<字串> 要使用的曲線名稱 (EC)。prime
:<Buffer> 質數參數 (DH)。primeLength
:<數字> 質數長度(以位元為單位)(DH)。generator
:<數字> 自訂產生器 (DH)。預設:2
。groupName
:<字串> Diffie-Hellman 群組名稱 (DH)。請參閱crypto.getDiffieHellman()
。paramEncoding
:<字串> 必須為'named'
或'explicit'
(EC)。預設:'named'
。publicKeyEncoding
:<物件> 請參閱keyObject.export()
。privateKeyEncoding
:<物件> 請參閱keyObject.export()
。
- 傳回:<物件>
publicKey
:<字串> | <Buffer> | <KeyObject>privateKey
:<字串> | <Buffer> | <KeyObject>
產生給定 type
的新的非對稱金鑰對。目前支援 RSA、RSA-PSS、DSA、EC、Ed25519、Ed448、X25519、X448 和 DH。
如果指定了 publicKeyEncoding
或 privateKeyEncoding
,此函式會像對其結果呼叫 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 的資料的緩衝區。
crypto.generateKeySync(type, options)
#
type
: <字串> 已產生機密金鑰的預定用途。目前可接受的值為'hmac'
和'aes'
。options
: <物件>length
: <number> 要產生的金鑰的位元長度。- 如果
type
為'hmac'
,最小值為 8,最大長度為 231-1。如果值不是 8 的倍數,產生的金鑰將會被截斷為Math.floor(length / 8)
。 - 如果
type
為'aes'
,長度必須為128
、192
或256
之一。
- 如果
- 傳回:<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]])
#
size
<number> 要產生的質數的大小(以位元為單位)。options
<Object>add
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint>rem
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint>safe
<boolean> 預設值:false
。bigint
<boolean> 為true
時,產生的質數會以bigint
回傳。
callback
<Function>err
<Error>prime
<ArrayBuffer> | <bigint>
產生一個 size
位元的偽亂數質數。
如果 options.safe
為 true
,質數將會是一個安全質數,也就是說 (prime - 1) / 2
也會是一個質數。
options.add
和 options.rem
參數可用於強制執行額外的需求,例如 Diffie-Hellman
- 如果
options.add
和options.rem
都已設定,質數將會符合prime % add = rem
的條件。 - 如果只有設定
options.add
,且options.safe
不是true
,質數將會符合prime % add = 1
的條件。 - 如果只有設定
options.add
,且options.safe
設定為true
,質數將會符合prime % add = 3
的條件。這是必要的,因為options.add > 2
的prime % add = 1
將會與options.safe
強制執行的條件相矛盾。 - 如果未提供
options.add
,將會忽略options.rem
。
如果 options.add
和 options.rem
以 ArrayBuffer
、SharedArrayBuffer
、TypedArray
、Buffer
或 DataView
提供,兩者都必須編碼為大端序序列。
預設情況下,質數會編碼為 <ArrayBuffer> 中的 big-endian 八位元組序列。如果 bigint
選項為 true
,則會提供 <bigint>。
crypto.generatePrimeSync(size[, options])
#
size
<number> 要產生的質數的大小(以位元為單位)。options
<Object>add
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint>rem
<ArrayBuffer> | <SharedArrayBuffer> | <TypedArray> | <Buffer> | <DataView> | <bigint>safe
<boolean> 預設值:false
。bigint
<boolean> 為true
時,產生的質數會以bigint
回傳。
- 傳回值:<ArrayBuffer> | <bigint>
產生一個 size
位元的偽亂數質數。
如果 options.safe
為 true
,質數將會是一個安全質數,也就是說 (prime - 1) / 2
也會是一個質數。
options.add
和 options.rem
參數可用於強制執行額外的需求,例如 Diffie-Hellman
- 如果
options.add
和options.rem
都已設定,質數將會符合prime % add = rem
的條件。 - 如果只有設定
options.add
,且options.safe
不是true
,質數將會符合prime % add = 1
的條件。 - 如果只有設定
options.add
,且options.safe
設定為true
,質數將會符合prime % add = 3
的條件。這是必要的,因為options.add > 2
的prime % add = 1
將會與options.safe
強制執行的條件相矛盾。 - 如果未提供
options.add
,將會忽略options.rem
。
如果 options.add
和 options.rem
以 ArrayBuffer
、SharedArrayBuffer
、TypedArray
、Buffer
或 DataView
提供,兩者都必須編碼為大端序序列。
預設情況下,質數會編碼為 <ArrayBuffer> 中的 big-endian 八位元組序列。如果 bigint
選項為 true
,則會提供 <bigint>。
crypto.getCipherInfo(nameOrNid[, options])
#
nameOrNid
:<string> | <number> 要查詢的密碼名稱或 nid。options
: <物件>- 傳回:<物件>
name
<string> 密碼名稱nid
<number> 密碼的 nidblockSize
<number> 密碼的區塊大小(以位元組為單位)。當mode
為'stream'
時,會省略此屬性。ivLength
<number> 預期的或預設的初始化向量長度(以位元組為單位)。如果密碼不使用初始化向量,則會省略此屬性。keyLength
<number> 預期的或預設的金鑰長度(以位元組為單位)。mode
<string> 密碼模式。其中一個:'cbc'
、'ccm'
、'cfb'
、'ctr'
、'ecb'
、'gcm'
、'ocb'
、'ofb'
、'stream'
、'wrap'
、'xts'
。
傳回有關特定密碼的資訊。
有些密碼接受變長度金鑰和初始化向量。預設情況下,crypto.getCipherInfo()
方法會傳回這些密碼的預設值。若要測試給定的金鑰長度或 iv 長度是否可接受給定的密碼,請使用 keyLength
和 ivLength
選項。如果給定的值不可接受,則會傳回 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)
#
groupName
<string>- 傳回:<DiffieHellmanGroup>
建立預先定義的 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()
#
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)
#
typedArray
<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer>- 傳回:<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> 傳回
typedArray
。
crypto.webcrypto.getRandomValues()
的方便別名。此實作不符合 Web Crypto 規範,若要撰寫相容於 Web 的程式碼,請改用 crypto.webcrypto.getRandomValues()
。
crypto.hkdf(digest, ikm, salt, info, keylen, callback)
#
digest
<字串> 要使用的摘要演算法。ikm
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> 輸入金鑰材料。必須提供,但可以為零長度。salt
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 鹽值。必須提供,但可以為零長度。info
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 其他資訊值。必須提供,但可以為零長度,且不能超過 1024 位元組。keylen
<數字> 要產生的金鑰長度。必須大於 0。允許的最大值為所選摘要函數所產生的位元組數的255
倍(例如,sha512
會產生 64 位元組的雜湊,因此 HKDF 的最大輸出為 16320 位元組)。callback
<Function>err
<Error>derivedKey
<ArrayBuffer>
HKDF 是 RFC 5869 中定義的簡單金鑰衍生函數。所提供的 ikm
、salt
和 info
會與 digest
一起使用,以衍生一個長度為 keylen
位元組的金鑰。
所提供的 callback
函數會以兩個引數呼叫:err
和 derivedKey
。如果在衍生金鑰時發生錯誤,err
會設定為錯誤;否則 err
會為 null
。成功產生的 derivedKey
會以 <ArrayBuffer> 傳遞給 callback。如果任何輸入引數指定無效的值或類型,就會擲回錯誤。
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)
#
digest
<字串> 要使用的摘要演算法。ikm
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> 輸入金鑰材料。必須提供,但可以為零長度。salt
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 鹽值。必須提供,但可以為零長度。info
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 其他資訊值。必須提供,但可以為零長度,且不能超過 1024 位元組。keylen
<數字> 要產生的金鑰長度。必須大於 0。允許的最大值為所選摘要函數所產生的位元組數的255
倍(例如,sha512
會產生 64 位元組的雜湊,因此 HKDF 的最大輸出為 16320 位元組)。- 傳回:<ArrayBuffer>
提供 RFC 5869 中定義的同步 HKDF 金鑰衍生函數。所提供的 ikm
、salt
和 info
會與 digest
一起使用,以衍生一個長度為 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)
#
password
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>salt
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>iterations
<數字>keylen
<數字>digest
<字串>callback
<Function>
提供非同步密碼基礎金鑰衍生函數 2 (PBKDF2) 實作。由 digest
指定的選取 HMAC 摘要演算法套用於從 password
、salt
和 iterations
衍生請求位元組長度 (keylen
) 的金鑰。
提供的 callback
函數會以兩個參數呼叫:err
和 derivedKey
。如果在衍生金鑰時發生錯誤,err
會設定;否則 err
會為 null
。預設情況下,成功產生的 derivedKey
會以 Buffer
傳遞給 callback。如果任一輸入參數指定無效值或類型,則會擲回錯誤。
iterations
參數必須是設定為最高可能的數字。迭代次數越高,衍生金鑰會越安全,但需要更長的時間才能完成。
salt
應盡可能唯一。建議 salt 是隨機的,且長度至少為 16 個位元組。請參閱 NIST SP 800-132 以取得詳細資料。
傳遞字串作為 password
或 salt
時,請考慮 將字串用作加密 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)
#
password
<string> | <Buffer> | <TypedArray> | <DataView>salt
<string> | <Buffer> | <TypedArray> | <DataView>iterations
<數字>keylen
<數字>digest
<字串>- 傳回: <Buffer>
提供同步密碼衍生函數 2 (PBKDF2) 實作。指定的 digest
選取 HMAC 摘要演算法,用於從 password
、salt
和 iterations
衍生請求位元組長度 (keylen
) 的金鑰。
如果發生錯誤,會擲回 Error
,否則派生的金鑰會以 Buffer
回傳。
iterations
參數必須是設定為最高可能的數字。迭代次數越高,衍生金鑰會越安全,但需要更長的時間才能完成。
salt
應盡可能唯一。建議 salt 是隨機的,且長度至少為 16 個位元組。請參閱 NIST SP 800-132 以取得詳細資料。
傳遞字串作為 password
或 salt
時,請考慮 將字串用作加密 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)
#
privateKey
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>oaepHash
<字串> 用於 OAEP 填充和 MGF1 的雜湊函數。預設值:'sha1'
oaepLabel
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 用於 OAEP 填充的標籤。如果未指定,則不使用標籤。padding
<crypto.constants> 在crypto.constants
中定義的選用填充值,可能是:crypto.constants.RSA_NO_PADDING
、crypto.constants.RSA_PKCS1_PADDING
或crypto.constants.RSA_PKCS1_OAEP_PADDING
。
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>- 傳回:<Buffer> 包含解密內容的新
Buffer
。
使用 privateKey
解密 buffer
。buffer
先前已使用對應的公開金鑰加密,例如使用 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)
#
privateKey
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>key
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey> PEM 編碼的私鑰。passphrase
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 私鑰的選用通行碼。padding
<crypto.constants> 在crypto.constants
中定義的選用填充值,可能是:crypto.constants.RSA_NO_PADDING
或crypto.constants.RSA_PKCS1_PADDING
。encoding
<string> 當buffer
、key
或passphrase
為字串時使用的字串編碼。
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>- 傳回:<Buffer> 包含加密內容的新
Buffer
。
使用 privateKey
加密 buffer
。傳回的資料可以使用對應的公開金鑰解密,例如使用 crypto.publicDecrypt()
。
如果 privateKey
不是 KeyObject
,此函式會像將 privateKey
傳遞給 crypto.createPrivateKey()
一樣運作。如果它是一個物件,則可以傳遞 padding
屬性。否則,此函式會使用 RSA_PKCS1_PADDING
。
crypto.publicDecrypt(key, buffer)
#
key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>passphrase
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 私鑰的選用通行碼。padding
<crypto.constants> 在crypto.constants
中定義的選用填充值,可能是:crypto.constants.RSA_NO_PADDING
或crypto.constants.RSA_PKCS1_PADDING
。encoding
<string> 當buffer
、key
或passphrase
為字串時使用的字串編碼。
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>- 傳回:<Buffer> 包含解密內容的新
Buffer
。
使用 key
解密 buffer
。buffer
先前使用對應的私鑰加密,例如使用 crypto.privateEncrypt()
。
如果 key
不是 KeyObject
,此函式會像將 key
傳遞給 crypto.createPublicKey()
一樣運作。如果它是一個物件,則可以傳遞 padding
屬性。否則,此函式會使用 RSA_PKCS1_PADDING
。
由於 RSA 公開金鑰可以從私鑰衍生,因此可以傳遞私鑰而不是公開金鑰。
crypto.publicEncrypt(key, buffer)
#
key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>key
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey> PEM 編碼的公開或私人金鑰、<KeyObject> 或 <CryptoKey>。oaepHash
<字串> 用於 OAEP 填充和 MGF1 的雜湊函數。預設值:'sha1'
oaepLabel
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 用於 OAEP 填充的標籤。如果未指定,則不使用標籤。passphrase
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 私鑰的選用通行碼。padding
<crypto.constants> 在crypto.constants
中定義的選用填充值,可能是:crypto.constants.RSA_NO_PADDING
、crypto.constants.RSA_PKCS1_PADDING
或crypto.constants.RSA_PKCS1_OAEP_PADDING
。encoding
<string> 當buffer
、key
、oaepLabel
或passphrase
為字串時,要使用的字串編碼。
buffer
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>- 傳回:<Buffer> 包含加密內容的新
Buffer
。
使用 key
加密 buffer
的內容,並傳回一個新的 Buffer
,其中包含加密的內容。傳回的資料可以使用對應的私人金鑰解密,例如使用 crypto.privateDecrypt()
。
如果 key
不是 KeyObject
,此函式會像 key
已傳遞給 crypto.createPublicKey()
一樣運作。如果它是一個物件,可以傳遞 padding
屬性。否則,此函式會使用 RSA_PKCS1_OAEP_PADDING
。
由於 RSA 公開金鑰可以從私鑰衍生,因此可以傳遞私鑰而不是公開金鑰。
crypto.randomBytes(size[, callback])
#
size
<number> 要產生的位元組數。size
不得大於2**31 - 1
。callback
<Function>- 傳回:<Buffer>,如果未提供
callback
函式。
產生密碼學上強的偽亂數資料。size
參數是一個數字,表示要產生的位元組數目。
如果提供了 callback
函式,則會非同步產生位元組,並以兩個參數呼叫 callback
函式:err
和 buf
。如果發生錯誤,err
會是 Error
物件;否則會是 null
。buf
參數是一個 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.randomFillSync(buffer[, offset][, size])
#
buffer
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 必須提供。提供的buffer
大小不得大於2**31 - 1
。offset
<number> 預設值:0
size
<數字> 預設值:buffer.length - offset
。size
不可大於2**31 - 1
。- 傳回:<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 傳遞為
buffer
參數的物件。
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'));
任何 ArrayBuffer
、TypedArray
或 DataView
執行個體都可以傳遞為 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.randomFill(buffer[, offset][, size], callback)
#
buffer
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> 必須提供。提供的buffer
大小不得大於2**31 - 1
。offset
<number> 預設值:0
size
<數字> 預設值:buffer.length - offset
。size
不可大於2**31 - 1
。callback
<函式>function(err, buf) {}
。
此函式類似於 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'));
});
任何 ArrayBuffer
、TypedArray
或 DataView
執行個體都可以傳遞為 buffer
。
雖然這包含 Float32Array
和 Float64Array
的執行個體,但此函式不應使用於產生亂數浮點數。結果可能包含 +Infinity
、-Infinity
和 NaN
,即使陣列僅包含有限數字,它們也不會從均勻亂數分佈中擷取,也沒有有意義的下限或上限。
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.randomInt([min, ]max[, callback])
#
傳回一個隨機整數 n
,其中 min <= n < max
。此實作避免了 模數偏差。
範圍(max - min
)必須小於 248。min
和 max
必須是 安全整數。
如果沒有提供 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
<布林值> 預設情況下,為了提升效能,Node.js 會產生並快取足夠的隨機資料,以產生多達 128 個隨機 UUID。若要產生 UUID 而不用快取,請將disableEntropyCache
設為true
。預設值:false
。
- 傳回:<字串>
產生一個隨機 RFC 4122 版本 4 UUID。UUID 是使用密碼學偽亂數產生器產生的。
crypto.scrypt(password, salt, keylen[, options], callback)
#
password
<string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>salt
<字串> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>keylen
<數字>options
<Object>callback
<Function>
提供非同步的 scrypt 實作。Scrypt 是一種基於密碼的金鑰衍生函數,設計為在運算和記憶體方面都非常耗費資源,以使暴力破解攻擊無法獲利。
salt
應盡可能唯一。建議 salt 是隨機的,且長度至少為 16 個位元組。請參閱 NIST SP 800-132 以取得詳細資料。
傳遞字串作為 password
或 salt
時,請考慮 將字串用作加密 API 輸入時的注意事項。
callback
函數會呼叫兩個參數:err
和 derivedKey
。當金鑰衍生失敗時,err
是例外物件,否則 err
為 null
。derivedKey
會傳遞給 callback 作為 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])
#
password
<string> | <Buffer> | <TypedArray> | <DataView>salt
<string> | <Buffer> | <TypedArray> | <DataView>keylen
<數字>options
<Object>- 傳回: <Buffer>
提供同步的 scrypt 實作。Scrypt 是一種基於密碼的金鑰衍生函數,設計為在運算和記憶體方面都非常耗費資源,以使暴力破解攻擊無法獲利。
salt
應盡可能唯一。建議 salt 是隨機的,且長度至少為 16 個位元組。請參閱 NIST SP 800-132 以取得詳細資料。
傳遞字串作為 password
或 salt
時,請考慮 將字串用作加密 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()
#
- 傳回:<物件>
crypto.setEngine(engine[, flags])
#
engine
<string>flags
<crypto.constants> 預設:crypto.constants.ENGINE_METHOD_ALL
載入並設定某些或所有 OpenSSL 函式的 engine
(由旗標選取)。
engine
可以是引擎共用函式庫的 ID 或路徑。
選用的 flags
參數預設使用 ENGINE_METHOD_ALL
。flags
是位元欄位,採用下列旗標之一或多個組合(在 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)
#
bool
<boolean>true
以啟用 FIPS 模式。
在已啟用 FIPS 的 Node.js 建置中啟用符合 FIPS 的加密提供者。如果 FIPS 模式不可用,則會擲回錯誤。
crypto.sign(algorithm, data, key[, callback])
#
algorithm
<string> | <null> | <undefined>data
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>callback
<Function>- 傳回:<Buffer>,如果未提供
callback
函式。
使用指定的私鑰和演算法計算並傳回 data
的簽章。如果 algorithm
為 null
或 undefined
,則演算法會依據金鑰類型而定(特別是 Ed25519 和 Ed448)。
如果 key
不是 KeyObject
,這個函式會像 key
已傳遞給 crypto.createPrivateKey()
一樣運作。如果是物件,可以傳遞下列額外屬性
-
dsaEncoding
<字串> 對於 DSA 和 ECDSA,這個選項會指定已產生簽章的格式。它可以是下列其中之一'der'
(預設):DER 編碼 ASN.1 簽章結構編碼(r, s)
。'ieee-p1363'
:簽章格式r || s
,如 IEEE-P1363 中所建議。
-
padding
<整數> RSA 的選用填充值,下列其中之一crypto.constants.RSA_PKCS1_PADDING
(預設)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDING
會使用 MGF1,其雜湊函式與第 3.1 節中指定的用於簽署訊息的雜湊函式相同,請參閱 RFC 4055。 -
saltLength
<整數> 當填充是RSA_PKCS1_PSS_PADDING
時的鹽長度。特殊值crypto.constants.RSA_PSS_SALTLEN_DIGEST
將鹽長度設定為雜湊大小,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN
(預設) 將其設定為最大允許值。
如果提供 callback
函式,此函式會使用 libuv 的執行緒池。
crypto.subtle
#
crypto.webcrypto.subtle
的方便別名。
crypto.timingSafeEqual(a, b)
#
a
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>b
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>- 傳回:<boolean>
此函式使用恆定時間演算法比較表示給定 ArrayBuffer
、TypedArray
或 DataView
執行個體的基礎位元組。
此函式不會洩漏時序資訊,讓攻擊者可以猜測其中一個值。這適合用於比較 HMAC 摘要或機密值,例如驗證 cookie 或 功能網址。
a
和 b
都必須是 Buffer
、TypedArray
或 DataView
,而且它們必須具有相同的位元組長度。如果 a
和 b
具有不同的位元組長度,則會擲回錯誤。
如果 a
和 b
中至少有一個是具有多個位元組的 TypedArray
,例如 Uint16Array
,則會使用平台位元組順序計算結果。
當兩個輸入都是 Float32Array
或 Float64Array
時,此函式可能會因為浮點數的 IEEE 754 編碼而傳回意外的結果。特別是,x === y
或 Object.is(x, y)
並不表示兩個浮點數 x
和 y
的位元組表示相同。
使用 crypto.timingSafeEqual
無法保證周圍程式碼的時序安全性。應小心確保周圍程式碼不會引發時序漏洞。
crypto.verify(algorithm, data, key, signature[, callback])
#
algorithm
<string> | <null> | <undefined>data
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>key
<Object> | <string> | <ArrayBuffer> | <Buffer> | <TypedArray> | <DataView> | <KeyObject> | <CryptoKey>signature
<ArrayBuffer> | <Buffer> | <TypedArray> | <DataView>callback
<Function>- 傳回:<boolean>
true
或false
,視簽章對資料和公開金鑰的有效性而定,如果未提供callback
函式。
使用指定的金鑰和演算法驗證 data
的指定簽章。如果 algorithm
為 null
或 undefined
,則演算法會根據金鑰類型(特別是 Ed25519 和 Ed448)而定。
如果 key
不是 KeyObject
,此函式會像 key
已傳遞給 crypto.createPublicKey()
一樣運作。如果它是一個物件,可以傳遞下列其他屬性
-
dsaEncoding
<string> 對於 DSA 和 ECDSA,此選項會指定簽章的格式。它可以是下列其中一個'der'
(預設):DER 編碼 ASN.1 簽章結構編碼(r, s)
。'ieee-p1363'
:簽章格式r || s
,如 IEEE-P1363 中所建議。
-
padding
<整數> RSA 的選用填充值,下列其中之一crypto.constants.RSA_PKCS1_PADDING
(預設)crypto.constants.RSA_PKCS1_PSS_PADDING
RSA_PKCS1_PSS_PADDING
會使用 MGF1,其雜湊函式與第 3.1 節中指定的用於簽署訊息的雜湊函式相同,請參閱 RFC 4055。 -
saltLength
<整數> 當填充是RSA_PKCS1_PSS_PADDING
時的鹽長度。特殊值crypto.constants.RSA_PSS_SALTLEN_DIGEST
將鹽長度設定為雜湊大小,crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN
(預設) 將其設定為最大允許值。
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 模組新增至 Node.js 之前,尚未有統一串流 API 的概念,也沒有 Buffer
物件來處理二進位資料。因此,許多 crypto
類別有其他實作 串流 API(例如 update()
、final()
或 digest()
)的 Node.js 類別通常沒有的方法。此外,許多方法預設接受和傳回 'latin1'
編碼字串,而不是 Buffer
。此預設值在 Node.js v0.8 之後變更,改為預設使用 Buffer
物件。
支援弱式或受損演算法#
node:crypto
模組仍支援一些已受損且不建議使用的演算法。此 API 也允許使用金鑰大小過小的密碼和雜湊,這些金鑰太弱,無法安全使用。
使用者應自行負責根據其安全需求選擇密碼編譯演算法和金鑰大小。
根據 NIST SP 800-131A 的建議
- MD5 和 SHA-1 不再適用於需要防碰撞性的情況,例如數位簽章。
- 建議與 RSA、DSA 和 DH 演算法一起使用的金鑰至少要有 2048 位元,而 ECDSA 和 ECDH 曲線的金鑰至少要有 224 位元,才能安全使用數年。
modp1
、modp2
和modp5
的 DH 群組金鑰大小小於 2048 位元,不建議使用。
請參閱參考文件以取得其他建議和詳細資訊。
某些已知有弱點且實際上不太相關的演算法只能透過 舊版提供者 取得,而舊版提供者預設並未啟用。
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 時,Node.js 在與適當的 OpenSSL 3 提供者搭配使用時支援 FIPS 140-2,例如 OpenSSL 3 的 FIPS 提供者,可以透過遵循 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:crypto
、node:tls
和 node: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 草稿中新增伺服器 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 停用加密然後 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_METHDS |
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 的 salt 長度。 |
POINT_CONVERSION_COMPRESSED |
|
POINT_CONVERSION_UNCOMPRESSED |
|
POINT_CONVERSION_HYBRID |
Node.js 加密常數#
常數 | 說明 |
---|---|
defaultCoreCipherList |
指定 Node.js 使用的內建預設加密清單。 |
defaultCipherList |
指定目前 Node.js 程序使用的有效預設加密清單。 |