ماژول Crypto در Node.js: رمزنگاری، گواهی‌نامه‌ها و رمزگذاری داده‌ها

ماژول node:crypto در Node.js مجموعه‌ای از قابلیت‌های رمزنگاری ارائه می‌دهد که شامل توابع هش، HMAC، رمزگذاری و رمزگشایی، امضا و تأیید امضا است. این ماژول به‌عنوان یک رابط برای کتابخانهٔ OpenSSL عمل می‌کند و ابزارهای قدرتمندی برای امنیت داده‌ها در اختیار توسعه‌دهندگان قرار می‌دهد. کلیدواژه‌ها

Asymmetric Key TypesCertificate ClassCipheriv ClassOpenSSL Integration

~8 دقیقه مطالعه • بروزرسانی ۶ دی ۱۴۰۴

1. مقدمه


ماژول node:crypto قابلیت‌های رمزنگاری شامل توابع هش، HMAC، رمزگذاری، رمزگشایی، امضا و تأیید امضا را فراهم می‌کند.


2. مثال: HMAC


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

3. مدیریت نبود پشتیبانی Crypto


  • اگر Node.js بدون پشتیبانی از crypto ساخته شده باشد، فراخوانی require('node:crypto') خطا ایجاد می‌کند.
  • در CommonJS می‌توان با try/catch مدیریت کرد؛ در ESM بهتر است از import() استفاده شود.

4. انواع کلیدهای نامتقارن


رابط KeyObject انواع مختلف کلیدهای نامتقارن را پشتیبانی می‌کند:


  • rsa، rsa-pss
  • ec، ed25519، ed448
  • x25519، x448
  • الگوریتم‌های پساکوانتومی مانند ml-dsa و ml-kem

5. کلاس Certificate


برای کار با داده‌های SPKAC استفاده می‌شود:


  • Certificate.exportChallenge(spkac): استخراج بخش challenge.
  • Certificate.exportPublicKey(spkac): استخراج کلید عمومی.
  • Certificate.verifySpkac(spkac): بررسی اعتبار SPKAC.

رابط قدیمی نیز امکان ساخت نمونه‌های new Certificate() را فراهم می‌کند.


6. کلاس Cipheriv


برای رمزگذاری داده‌ها با کلید و بردار اولیه (IV) استفاده می‌شود. می‌توان آن را به‌صورت جریان یا با متدهای update() و final() به کار برد.


مثال: رمزگذاری به‌صورت جریان


const { scrypt, randomFill, createCipheriv } = require('node:crypto');
const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

scrypt(password, 'salt', 24, (err, key) => {
  randomFill(new Uint8Array(16), (err, iv) => {
    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();
  });
});

مثال: استفاده از update() و final()


const cipher = createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('some clear text data', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);

نتیجه‌گیری


ماژول node:crypto یک رابط قدرتمند برای OpenSSL است که امکان هش، رمزگذاری، مدیریت گواهی‌نامه‌ها و پشتیبانی از الگوریتم‌های مدرن رمزنگاری را فراهم می‌کند. توسعه‌دهندگان می‌توانند با استفاده از کلاس‌هایی مانند Certificate و Cipheriv برنامه‌های امن و پایدار بسازند.


1. DiffieHellmanGroup


کلاس DiffieHellmanGroup مشابه Diffie-Hellman عمل می‌کند اما اجازهٔ تغییر کلیدها پس از ایجاد را نمی‌دهد. از گروه‌های استاندارد modp14 تا modp18 پشتیبانی می‌کند.


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

2. ECDH (Elliptic Curve Diffie-Hellman)


کلاس ECDH برای تبادل کلید مبتنی بر منحنی بیضوی استفاده می‌شود. این روش امنیت بالاتری نسبت به DH سنتی دارد.


const { createECDH } = require('node:crypto');
const alice = createECDH('secp521r1');
const bob = createECDH('secp521r1');
const aliceKey = alice.generateKeys();
const bobKey = bob.generateKeys();
const secretAlice = alice.computeSecret(bobKey);
const secretBob = bob.computeSecret(aliceKey);

ویژگی‌ها


  • ECDH.convertKey(): تبدیل کلید عمومی به فرمت‌های مختلف (compressed/uncompressed).
  • ecdh.generateKeys(): تولید کلیدهای خصوصی و عمومی.
  • ecdh.computeSecret(): محاسبهٔ راز مشترک.
  • ecdh.getPrivateKey() و ecdh.getPublicKey(): دریافت کلیدها.

3. Hash Class


کلاس Hash برای تولید هش داده‌ها استفاده می‌شود. می‌توان آن را به‌صورت جریان یا با متدهای update() و digest() به کار برد.


const { createHash } = require('node:crypto');
const hash = createHash('sha256');
hash.update('some data to hash');
console.log(hash.digest('hex'));

ویژگی‌ها


  • hash.update(): افزودن داده برای هش.
  • hash.digest(): تولید خروجی هش.
  • hash.copy(): ایجاد کپی از وضعیت فعلی هش.

4. Hmac Class


کلاس Hmac برای تولید HMAC (هش مبتنی بر کلید) استفاده می‌شود. مشابه Hash است اما از یک کلید مخفی برای امنیت بیشتر بهره می‌برد.


const { createHmac } = require('node:crypto');
const hmac = createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));

ویژگی‌ها


  • hmac.update(): افزودن داده برای محاسبهٔ HMAC.
  • hmac.digest(): تولید خروجی HMAC.

نتیجه‌گیری


کلاس‌های DiffieHellmanGroup و ECDH امکان تبادل کلید امن را فراهم می‌کنند، در حالی که Hash و Hmac ابزارهای قدرتمندی برای تولید خلاصهٔ رمزنگاری داده‌ها هستند. ترکیب این قابلیت‌ها امنیت داده‌ها و ارتباطات را در برنامه‌های Node.js تضمین می‌کند.


1. Hmac Class


کلاس Hmac برای تولید HMAC (هش مبتنی بر کلید) استفاده می‌شود.


  • hmac.update(data[, inputEncoding]): افزودن داده برای محاسبهٔ HMAC.
  • hmac.digest([encoding]): تولید خروجی نهایی HMAC. پس از فراخوانی دیگر نمی‌توان از شیء استفاده کرد.

const { createHmac } = require('node:crypto');
const hmac = createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));

2. KeyObject Class


کلاس KeyObject برای نمایش کلیدهای متقارن و نامتقارن استفاده می‌شود. این کلاس امنیت بیشتری نسبت به استفاده از رشته‌ها یا Bufferها دارد.


  • KeyObject.from(key): تبدیل CryptoKey به KeyObject.
  • keyObject.export([options]): خروجی گرفتن از کلید در قالب PEM، DER یا JWK.
  • keyObject.equals(otherKeyObject): مقایسهٔ دو کلید.
  • keyObject.type: نوع کلید (secret، public یا private).
  • keyObject.symmetricKeySize: اندازهٔ کلید متقارن.

3. Sign Class


کلاس Sign برای تولید امضا استفاده می‌شود.


  • sign.update(data): افزودن داده برای امضا.
  • sign.sign(privateKey[, outputEncoding]): تولید امضا با کلید خصوصی.

const { generateKeyPairSync, createSign } = require('node:crypto');
const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const sign = createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');

4. Verify Class


کلاس Verify برای تأیید امضا استفاده می‌شود.


  • verify.update(data): افزودن داده برای بررسی.
  • verify.verify(publicKey, signature): تأیید امضا با کلید عمومی.

const { generateKeyPairSync, createVerify } = require('node:crypto');
const { publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const verify = createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));

5. X509Certificate Class


کلاس X509Certificate برای بررسی گواهی‌های X509 استفاده می‌شود.


  • x509.ca: بررسی اینکه گواهی CA است یا خیر.
  • x509.checkEmail(email): بررسی تطابق گواهی با ایمیل.
  • x509.checkHost(name): بررسی تطابق گواهی با نام میزبان.
  • x509.checkIP(ip): بررسی تطابق گواهی با IP.

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

نتیجه‌گیری


کلاس‌های Hmac، KeyObject، Sign، Verify و X509Certificate در Node.js ابزارهای پیشرفته‌ای برای مدیریت کلیدها، تولید و تأیید امضا، و بررسی گواهی‌های دیجیتال فراهم می‌کنند. این قابلیت‌ها امنیت داده‌ها و ارتباطات را در برنامه‌های Node.js تضمین می‌کنند.


1. X509Certificate Class


کلاس X509Certificate برای بررسی و مدیریت گواهی‌های X509 استفاده می‌شود.


  • x509.checkIssued(otherCert): بررسی اینکه آیا گواهی توسط گواهی دیگر صادر شده است.
  • x509.checkPrivateKey(privateKey): بررسی سازگاری کلید خصوصی با کلید عمومی گواهی.
  • x509.fingerprint / fingerprint256 / fingerprint512: تولید اثرانگشت گواهی با الگوریتم‌های مختلف.
  • x509.issuer / subject: اطلاعات صادرکننده و موضوع گواهی.
  • x509.validFrom / validTo: تاریخ اعتبار گواهی.
  • x509.verify(publicKey): بررسی امضای گواهی با کلید عمومی.

2. Argon2 Functions


توابع crypto.argon2 و crypto.argon2Sync برای مشتق‌سازی رمز عبور استفاده می‌شوند. Argon2 مقاوم در برابر حملات brute-force است.


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

3. Prime Checking


توابع crypto.checkPrime و crypto.checkPrimeSync برای بررسی اول بودن یک عدد استفاده می‌شوند.


  • checkPrime(candidate, options, callback): بررسی اول بودن عدد به‌صورت غیرهمزمان.
  • checkPrimeSync(candidate, options): بررسی اول بودن عدد به‌صورت همزمان.

4. Cipher and Decipher


توابع crypto.createCipheriv و crypto.createDecipheriv برای رمزگذاری و رمزگشایی داده‌ها با الگوریتم‌های مختلف استفاده می‌شوند.


5. Diffie-Hellman and ECDH


توابع crypto.createDiffieHellman و crypto.createECDH برای تبادل کلید امن استفاده می‌شوند.


Examples


// بررسی صدور گواهی
if (!x509.verify(otherCert.publicKey)) {
  throw new Error('Certificate not issued by otherCert');
}

// استفاده از Argon2 برای مشتق‌سازی رمز عبور
argon2('argon2id', parameters, (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));
});

نتیجه‌گیری


کلاس X509Certificate و توابع پیشرفته مانند argon2 و checkPrime در Node.js ابزارهای قدرتمندی برای مدیریت گواهی‌ها، کلیدها و امنیت رمز عبور فراهم می‌کنند. این قابلیت‌ها امنیت داده‌ها و ارتباطات را در برنامه‌های Node.js به سطح بالاتری ارتقا می‌دهند.


1. Signature Verification


  • crypto.createVerify(algorithm[, options]): ایجاد شیء Verify برای بررسی امضا با الگوریتم مشخص.
  • پشتیبانی از الگوریتم‌های digest مانند RSA-SHA256.

2. Key Encapsulation Mechanisms (KEM)


  • crypto.encapsulate(publicKey): تولید sharedKey و ciphertext با استفاده از کلید عمومی.
  • crypto.decapsulate(privateKey, ciphertext): بازیابی sharedKey با استفاده از کلید خصوصی.
  • پشتیبانی از الگوریتم‌های RSA، EC، X25519، X448 و ML-KEM.

3. Diffie-Hellman


  • crypto.diffieHellman({ privateKey, publicKey }): محاسبهٔ راز مشترک با کلیدهای DH یا ECDH.

4. Key Generation


  • crypto.generateKey(type, options, callback): تولید کلید متقارن (HMAC یا AES).
  • crypto.generateKeySync(type, options): نسخهٔ همزمان.
  • crypto.generateKeyPair(type, options, callback): تولید کلید نامتقارن (RSA، DSA، EC، DH).
  • crypto.generateKeyPairSync(type, options): نسخهٔ همزمان.

5. Prime Generation


  • crypto.generatePrime(size[, options], callback): تولید عدد اول شبه‌تصادفی.
  • crypto.generatePrimeSync(size[, options]): نسخهٔ همزمان.
  • پشتیبانی از safe primes و شرایط خاص برای DH.

6. Cipher and Curve Information


  • crypto.getCipherInfo(nameOrNid): دریافت اطلاعات دربارهٔ الگوریتم رمزگذاری.
  • crypto.getCiphers(): لیست الگوریتم‌های رمزگذاری پشتیبانی‌شده.
  • crypto.getCurves(): لیست منحنی‌های بیضوی پشتیبانی‌شده.
  • crypto.getHashes(): لیست الگوریتم‌های هش پشتیبانی‌شده.

7. Examples


// ایجاد Verify برای بررسی امضا
const verify = crypto.createVerify('SHA256');
verify.update('data');
console.log(verify.verify(publicKey, signature));

// تولید کلید RSA
crypto.generateKeyPair('rsa', {
  modulusLength: 4096,
  publicKeyEncoding: { type: 'spki', format: 'pem' },
  privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'secret' }
}, (err, publicKey, privateKey) => {
  console.log(publicKey, privateKey);
});

نتیجه‌گیری


توابع پیشرفتهٔ ماژول crypto در Node.js مانند createVerify، encapsulate/decapsulate، diffieHellman و تولید کلیدها ابزارهای قدرتمندی برای مدیریت امنیت داده‌ها و ارتباطات فراهم می‌کنند. این قابلیت‌ها توسعه‌دهندگان را قادر می‌سازند تا برنامه‌های امن‌تر و مقاوم‌تر در برابر حملات بسازند.


نوشته و پژوهش شده توسط دکتر شاهین صیامی