الوحدة ‎‎‎crypto‎ في Node.js

من موسوعة حسوب

الاستقرار: 2-مستقر

توفِّر الوحدة crypto وظيفة التشفير (cryptographic functionality) التي تتضمن مجموعةً من المغلفات (wrappers) التي تُستعمَل من أجل دوال شيفرة Hash في OpenSSL، والتشفير HMAC، والتشفير (cipher)، وفك التشفير (decipher)، والتوقيع (sign)، والتحقق (verify).

استعمل الأمر require('crypto')‎ للوصول إلى هذه الوحدة.

const crypto = require('crypto');

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

التحقق من توافر دعم للوحدة crypto

يُحتمَل في بعض الأحيان أن تُبنَى Node.js دون أن تحوي دعمًا للوحدة crypto. في بعض الحالات، سيؤدي استدعاء الأمر require('crypto')‎ إلى رمي خطأٍ.

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

الصنف Certificate

أضيف في الإصدار: v0.11.8.

إنَّ الصيغة SPKAC (اختصارٌ للعبارة Signed Public Key and Challenge، وتعرف أيضًا بالاسم Netscape SPKI) هي آلية لطلب توقيع الشهادة (Certificate Signing Request) نُفِّذت بدايةً من قبل المتصفح Netscape ثم حُدِّدَت رسميًا على أنَّها جزء من العنصر <keygen> في HTML5.

انتبه إلى أنَّ العنصر <keygen> قد أهمل بدءًا من الإصدار HTML 5.2، لذا لا يجب على المشاريع الجديدة أن تستعمله بعد الآن.

توفر الوحدة crypto الصنف Certificate للعمل مع بيانات SPKAC. أشهر استعمال لها هو معالجة المخرجات المُولَّدة باستعمال العنصر <keygen> في HTML5. تعمل Node.js على تنفيذ SPKAC في OpenSSL داخليًّا.

Certificate.exportChallenge(spkac)‎

أضيف في الإصدار: v9.0.0.

  • spkac:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> مكوِّن تحدي المصادقة (challenge، ويدعى أحيانًا challenge–response authentication) لهيكلية بيانات spkac التي تتضمن مفتاحًا عامًا (public key) وتحدِّيًا للمصادقة.
const { Certificate } = require('crypto');
const spkac = getSpkacSomehow();
const challenge = Certificate.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// UTF8 سيُطبَع تحدِّي المصادقة كسلسلة نصية بترميز

Certificate.exportPublicKey(spkac[, encoding])‎

أضيف في الإصدار: v9.0.0.

  • spkac:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> مكون المفتاح العام لهيكلية بيانات spkac التي تتضمن مفتاحًا عامًا (public key) وتحدِّيًا للمصادقة (challenge، ويدعى أيضًا challenge–response authentication).
  • encoding:‏ ‎ <string>
const { Certificate } = require('crypto');
const spkac = getSpkacSomehow();
const publicKey = Certificate.exportPublicKey(spkac);
console.log(publicKey);
// <Buffer ...> سيُطبَع المفتاح العام كأنه

Certificate.verifySpkac(spkac)‎

أضيف في الإصدار: v9.0.0.

  • spkac:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <boolean> القيمة true إن كانت هيكلية بيانات spkac صالحة، أو القيمة false خلاف ذلك.
const { Certificate } = require('crypto');
const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// false أو true ستُطبع القيمة

الواجهات البرمجية الإرثية (Legacy API)

لمَّا كانت الواجهات الإرثية (legacy interface) مدعومةً إلى الآن، فيمكن إنشاء نسخ جديدة من الصنف crypto.Certificate كما هو موضح في الأمثلة اللاحقة.

new crypto.Certificate()‎

يمكن إنشاء نسخ من الصنف Certificate باستعمال الكلمة المفتاحية new أو عبر استدعاء العبارة crypto.Certificate()‎ كدالة:

const crypto = require('crypto');

const cert1 = new crypto.Certificate();
const cert2 = crypto.Certificate();

certificate.exportChallenge(spkac)‎

أضيف في الإصدار: v0.11.8.

  • spkac: ‏<string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> مكوِّن تحدي المصادقة (challenge، أو يدعى أيضًا challenge–response authentication) لهيكلية بيانات spkac التي تتضمن مفتاحًا عامًا (public key) وتحدِّيًا للمصادقة.
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// UTF8 سيُطبَع تحدِّي المصادقة كسلسلة نصية بترميز

certificate.exportPublicKey(spkac)‎

أضيف في الإصدار: v0.11.8.

  • spkac: ‏<string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> مكون المفتاح العام لهيكلية بيانات spkac التي تتضمن مفتاحًا عامًا (public key) وتحدِّيًا للمصادقة (challenge، أو يدعى أيضًا challenge–response authentication).
  • encoding:‏ ‎ <string>
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// <Buffer ...> سيُطبَع المفتاح العام كأنه

certificate.verifySpkac(spkac)‎

أضيف في الإصدار: v0.11.8.

  • spkac: ‏<Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <boolean> القيمة true إن كانت هيكلية بيانات spkac صالحة، أو القيمة false خلاف ذلك.
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// false أو true ستُطبع القيمة

الصنف Cipher

أضيف في الإصدار: v0.1.94.

تُستعمَل نسخ الصنف Cipher في تشفير البيانات. يمكن استعمال هذا الصنف بإحدى الطريقتين التاليتين:

  • يُستعمَل كمجرًى قابلًا للقراءة والكتابة، إذ تكتب فيه البيانات الصرفة غير المشفرة بعد لتوليد البيانات المشفرة المقابلة لها في الجانب القابل للقراءة من هذا المجرى، أو
  • يُستعمَل التابعان cipher.update()‎ و cipher.final() لتوليد البيانات المشفرة.

يُستعمَل التابعان crypto.createCipher()‎ أو crypto.createCipheriv()‎ لإنشاء نسخٍ من الصنف Cipher. لا يجب إنشاء الكائنات Cipher باستعمال الكلمة المفتاحية new مباشرةً.

يوضِّح المثال التالي كيفية استعمال الكائنات Cipher كمجرى:

const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');

let encrypted = '';
cipher.on('readable', () => {
  const data = cipher.read();
  if (data)
    encrypted += data.toString('hex');
});
cipher.on('end', () => {
  console.log(encrypted);
  // ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504 :سيُطبَع
});

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

ويوضح المثال التالي كيفية استعمال الصنف Cipher مع نقل محتويات المجاري (piped streams):

const crypto = require('crypto');
const fs = require('fs');
const cipher = crypto.createCipher('aes192', 'a password');

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

input.pipe(cipher).pipe(output);

أمَّا المثال التالي، فيوضِّح كيفية استعمال التابعين cipher.update()‎ و cipher.final():

const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');

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

cipher.final([outputEncoding])‎

أضيف في الإصدار: v0.1.94.

  • outputEncoding:‏ ‎ <string>
  • القيم المعادة: <Buffer>‏ | <string> أيَّةُ محتويات مشفرة متبقية. إن كانت قيمة المعامل outputEncoding إحدى القيم التالية: 'latin1'، أو 'base64' ، أو 'hex'، فستُعاد سلسلة نصية. أمَّا إن لم يُعطَ المعامل outputEncoding، فسيُعاد كائن من النوع Buffer.

لن يعد بالإمكان استعمال الكائن Cipher لتشفير البيانات متى ما استدعي التابع cipher.final. أية محاولة لاستدعاء التابع cipher.final()‎ أكثر من مرة سينتج عنها رمي خطأٍ.

cipher.setAAD(buffer[, options])‎

أضيف في الإصدار: v1.0.0.

  • buffer:‏ ‎ <Buffer>
  • options:‏ ‎<Object>‎ خيارات التابع stream.transform.
  • القيم المعادة: <Cipher> كائن من النوع Cipher من أجل تقييد التابع (method chaining).

عند استعمال وضع التشفير الموثوق (authenticated encryption) -مثل GCM أو CCM أو OCB المدعومة حاليًا-، تضبط الدالة cipher.setAAD() القيمة المستعملة للبيانات الموثوقة الإضافية (AAD، اختصارٌ للعبارة additional authenticated data) في معامل الإدخال.

المعامل options هو اختياري من أجل الوضع GCM والوضع OCB. عند استعمال الوضع CCM، يجب أن يُحدَّد الخيار plaintextLength وأن تُطابِق قيمته طول النص المجرَّد (plaintext) بواحدة البايت. ارجع إلى «الوضع CCM» في الأسفل للمزيد من المعلومات.

يجب أن يُستدعَى التابع cipher.setAAD()‎ قبل استدعاء التابع cipher.update()‎.

cipher.getAuthTag()‎

أضيف في الإصدار: v1.0.0.

  • القيم المعادة: <Buffer> عند استعمال وضع التشفير الموثوق (GCM، و CCM، و OCB هي الأوضاع المدعومة حاليًا)، يعيد التابع cipher.getAuthTag()‎ كائنًا من النوع Buffer يحوي بطاقة المصادقة (authentication tag) التي حُسبَت من البيانات المعطاة.

يجب استدعاء التابع cipher.getAuthTag()‎ بعد اكتمال عملية التشفير باستعمال التابع cipher.final()‎ فقط.

cipher.setAutoPadding([autoPadding])‎

أضيف في الإصدار: v0.7.1.

  • autoPadding:‏ ‎ <boolean>‎قيمة منطقية. القيمة الافتراضية هي: true.
  • القيم المعادة: <Cipher> كائن من النوع Cipher من أجل تقييد التابع (method chaining).

عند استعمال خوارزميات التشفير الكتلية (block encryption algorithms)، سيضيف الصنف Cipher حاشية (padding) إلى البيانات المدخلة تلقائيًا لتتلاءم مع حجم الكتلة. لتعطيل هذا السلوك الافتراضي، استدعِ التابع بالشكل cipher.setAutoPadding(false)‎.

عندما تعطى القيمة false إلى المعامل autoPadding، يجب أن يكون طول البيانات المدخلة بأكملها من مضاعفات حجم كتلة الشيفرة وإلا سيرمي التابع cipher.final()‎ خطأً. تعطيل إضافة الحاشية تلقائيًّا مفيدٌ للحاشية غير القياسية (non-standard padding) مثل استعمال الحشوة 0x0 عوضًا عن PKCS.

يجب استدعاء التابع cipher.setAutoPadding()‎ قبل التابع cipher.final()‎.

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

سجل التغييرات
الإصدار التغييرات
v6.0.0 القيمة الافتراضية للمعامل inputEncoding تغيرت من binary إلى utf8.
v0.1.94 أضيف هذا التابع.

يعمل هذا التابع على تحديث عملية التشفير مع القيمة data. إن أعطي الوسيط inputEncoding، فيجب أن تكون قيمته 'utf8'، أو 'ascii'، أو 'latin1' وأن يكون الوسيط data سلسلةً نصيةً مرمزةً بهذا الترميز المحدد. إن لم يُعطَ الوسيط inputEncoding، فيجب أن يكون المعامل data كائنًا من النوع Buffer أو TypedArray أو DataView. من جهة أخرى، إن كان الوسيط data كائنًا من النوع Buffer أو TypedArray أو DataView، فسيُتجاهَل المعامل inputEncoding حينها.

يحدِّد الوسيط outputEncoding ترميز مخرجات البيانات المشفرة، والتي يمكن أن تكون 'latin1'، أو 'base64'، أو 'hex'. إن حُدِّد الوسيط outputEncoding، فستُعاد سلسلةٌ نصيةٌ مرمزةٌ بذلك الترميز المحدد. أما إن لم يُعطَ الوسيط outputEncoding، فسيُعاد كائن من النوع Buffer.

يمكن استدعاء التابع cipher.update()‎ عدة مرات مع البيانات الجديدة إلى أن يُستدعَى التابع cipher.final()‎‎. سيؤدي استدعاء التابع cipher.update()‎ بعد التابع cipher.final()‎‎ إلى رمي خطأٍ.

الصنف Decipher

أضيف في الإصدار: v0.1.94. تُستعمَل النسخ المنشأة من الصنف Decipher في فك تشفير البيانات. يمكن استعمال هذا الصنف في بإحدى الطريقتين التاليتين:

  • يُستعمَل كمجرًى قابلًا للقراءة والكتابة، إذ تكتب فيه البيانات الصرفة المشفرة للتوليد البيانات غير المشفرة المقابلة لها في الجانب القابل للقراءة من هذا المجرى، أو
  • يُستعمَل التابعان cipher.update()‎ و cipher.final() لتوليد البيانات غير المشفرة.

يُستعمَل التابعان crypto.createDecipher()‎ أو crypto.createDecipheriv()‎ لإنشاء نسخٍ من الصنف Decipher. لا يجب إنشاء الكائنات Decipher مباشرةً باستعمال الكلمة المفتاحية new.

يوضح المثال التالي كيفية استعمال الكائنات Decipher كمجاري:

const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');

let decrypted = '';
decipher.on('readable', () => {
  const data = decipher.read();
  if (data)
    decrypted += data.toString('utf8');
});
decipher.on('end', () => {
  console.log(decrypted);
  /ستُطبَع بعض البيانات النصية المفهومة
});

const encrypted =
    'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();

ويوضح المثال التالي كيفية استعمال الصنف decipher مع نقل محتويات المجاري (piped streams):

const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');

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

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

أما المثال التالي، يوضح كيفية استعمال التابعين cipher.update()‎ و cipher.final():

 const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');

const encrypted =
    'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// ستُطبَع بعض البيانات النصية المفهومة

decipher.final([outputEncoding])‎

أضيف في الإصدار: v0.1.94.

  • outputEncoding: ‏‎ <string>
  • القيم المعادة: <Buffer>‏ | <string> أية محتويات غير مشفرة متبقية. إن كانت قيمة المعامل outputEncoding إحدى القيم التالية: 'latin1'، أو 'ascii' ، أو 'utf8'، فستُعاد سلسلة نصية. أمَّا إن لم يُعطَ المعامل outputEncoding، فسيعاد كائن من النوع Buffer.

لن يعد بالإمكان استعمال الكائن Decipher لفك تشفير البيانات متى ما استدعي التابع decipher.final()‎‎. أية محاولة لاستدعاء التابع cipher.final()‎ أكثر من مرة سينتج عنها رمي خطأٍ.

decipher.setAAD(buffer[, options])‎

سجل التغييرات
الإصدار التغييرات
v7.2.0 أصبح هذا التابع الآن يعيد مرجعًا إلى decipher.
v1.0.0 أضيف هذا التابع.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • options:‏ <Object> خيارات التابع stream.transform.
    • plaintextLength:‏ ‎ <number>‎

القيم المعادة: <Decipher> الكائن Decipher من أجل تقييد التابع (method chaining).

عند استعمال وضع التشفير الموثوق (authenticated encryption mode) -مثل GCM أو CCM أو OCB المدعومة حاليًا-، يضبط التابع decipher.setAAD()‎ القيمة المستعملة للبيانات الموثوقة الإضافية (AAD، اختصارٌ للعبارة additional authenticated data) في معامل الإدخال.

الوسيط options هو اختياري من أجل الوضع GCM. عند استعمال الوضع CCM، يجب أن يُحدَّد الخيار plaintextLength وأن تُطابِق قيمته طول النص المجرَّد (plaintext) بواحدة البايت. ارجع إلى الوضع CCM في الأسفل للمزيد من المعلومات.

يجب أن يستدعى التابع decipher.setAAD()‎ قبل استدعاء التابع decipher.update()‎.

decipher.setAuthTag(buffer)‎

سجل التغييرات
الإصدار التغييرات
v7.2.0 أصبح هذا التابع الآن يعيد مرجعًا إلى decipher.
v1.0.0 أضيف هذا التابع.

عند استعمال وضع التشفير الموثوق (authenticated encryption mode) -مثل GCM أو CCM أو OCB المدعومة حاليًا-، تُستعمَل الدالة decipher.setAuthTag()‎ لتمرير بطاقة المصادقة (authentication tag) المُستلمَة. إن لم تُعطَ أية بطاقة أو تم العبث بالنص المشفر، فسيرمي التابع decipher.final()‎‎ خطأً يشير إلى أنَّ النص المشفر يجب إهماله بسبب فشل المصادقة. انتبه إلى أنَّ إصدار Node.js هذا لا يتحقق من طول بطاقات المصادقة في الوضع GCM. يجب تنفيذ مثل هذا التحقق باستعمال تطبيقات أخرى لأهميته الكبيرة في موثوقية البيانات المشفَّرة، وإلا سيتمكن أي مهاجم من استعمال أية بطاقة مصادقة قصيرة اعتباطية لزيادة فرصة اجتياز المصادقة بنجاح (بنسبة تصل إلى 0.39%). يوصى بشدة قرن إحدى القيم 16، أو 15، أو 14، أو 13، أو 12، أو 8، أو 4 بايت مع كل مفتاح للمصادقة على البطاقات التي لها نفس الطول المحدد فقط. انظر أيضًا NIST SP 800-38D. يجب استدعاء التابع decipher.setAuthTag()‎ قبل التابع decipher.final()‎‎.

decipher.setAutoPadding([autoPadding])‎

أضيف في الإصدار: v0.7.1.

  • autoPadding:‏ ‎<boolean>‎ قيمة منطقية. القيمة الافتراضية هي: true.
  • القيم المعادة: <Decipher> الكائن Decipher من أجل تقييد التابع (method chaining).

إن كانت البيانات قد شُفِّرت دون استعمال حاشية كتلية قياسية (standard block padding)، فإنَّ استدعاء هذا التابع بالشكل decipher.setAutoPadding(false)‎ سيُعطِّل إضافة الحاشية تلقائيًّا لمنع التابع decipher.final()‎‎ من التحقق من وجود الحاشية وإزالتها. تعطيل إضافة الحاشية تلقائيًّا فعَّالٌ فقط في حال كان طول البيانات المدخلة من مضاعفات حجم كتلة الشيفرات. يجب استدعاء التابع decipher.setAutoPadding()‎ قبل التابع decipher.final()‎‎.

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

سجل التغييرات
الإصدار التغييرات
v6.0.0 القيمة الافتراضية للمعامل inputEncoding تغيرت من binary إلى utf8.
v0.1.94 أضيف هذا التابع.

يعمل هذا التابع على تحديث عملية فك التشفير مع القيمة data. إن أعطي الوسيط inputEncoding، فيجب أن تكون قيمته هي: 'latin1'، أو 'latin1'، أو 'hex' وأن يكون الوسيط data سلسلةً نصيةً مرمزةً بهذا الترميز المحدد. إن لم يُعطَ الوسيط inputEncoding، فيجب أن يكون المعامل data كائنًا من النوع Buffer. من جهة أخرى، إن كان الوسيط data كائنًا من النوع Buffer، فسيُتجاهَل المعامل inputEncoding حينها.

يحدد الوسيط outputEncoding ترميز مخرجات البيانات غير المشفرة، والتي يمكن أن تكون 'latin1'، أو 'ascii'، أو 'utf8'. إن حُدِّد الوسيط outputEncoding، فستُعاد سلسلةٌ نصيةٌ مرمزةٌ بالترميز المحدد. أما إن لم يُعطَ الوسيط outputEncoding، فسيُعاد كائن من النوع Buffer.

يمكن استدعاء التابع decipher.update()‎ عدة مرات مع البيانات الجديدة حتى يستدعى التابع decipher.final()‎. سيؤدي استدعاء التابع decipher.update()‎ بعد التابع cipher.final()‎‎ إلى رمي خطأٍ.

الصنف DiffieHellman

أضيف في الإصدار: v0.5.0.

الصنف DiffieHellman هو أداة لإنشاء تبادلات مفتاح Diffie-Hellman.

يمكن إنشاء نسخٍ من الصنف DiffieHellman باستعمال الدالة crypto.createDiffieHellman()‎.

const crypto = require('crypto');
const assert = require('assert');

// Alice توليد مفاتيح
const alice = crypto.createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Bob توليد مفاتيح
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();

// (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])‎

أضيف في الإصدار: v0.5.0.

يحسب هذا التابع السر المشترك (shared secret) مستعملًا الوسيط otherPublicKey على أنَّه المفتاح العام للطرف الآخر ثم يعيده. يُفسَّر المفتاح المعطى باستعمال الترميز inputEncoding المعطى، ويرمَّز السر بالترميز outputEncoding المحدد. يمكن استعمال أحد الترميزات 'latin1'، أو 'hex'، أو 'base64'. إن لم يُعطَ الوسيط inputEncoding، فسيُتوقَّع أن يكون الوسيط otherPublicKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

إن أعطي الوسيط outputEncoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.generateKeys([encoding])‎

أضيف في الإصدار: v0.5.0.

يولد هذا التابع قيمًا لمفتاح Diffie-Hellman عام أو خاص، ويعيد المفتاح العام مرمزًا بالترميز encoding المعطى. يجب أن يُنقَل هذا المفتاح إلى الطرف الآخر. يمكن استعمال أحد الترميزات 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.getGenerator([encoding])‎

أضيف في الإصدار: v0.5.0.

القيم المعادة: <Buffer> ‏| <string> يعيد هذا التابع مولد Diffie-Hellman مرمزًا بالترميز encoding المعطى، والذي يمكن أن يكون 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.getPrime([encoding])‎

أضيف في الإصدار: v0.5.0.

يعيد هذا التابع عدد Diffie-Hellman الأولي (prime) مرمزًا بالترميز encoding المعطى، والذي يمكن أن يكون 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.getPrivateKey([encoding])‎

أضيف في الإصدار: v0.5.0.

يعيد هذا التابع مفتاح Diffie-Hellman الخاص (private key) مرمزًا بالترميز encoding المعطى، والذي يمكن أن يكون 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.getPublicKey([encoding])‎

أضيف في الإصدار: v0.5.0.

يعيد هذا التابع مفتاح Diffie-Hellman العام (public key) مرمزًا بالترميز encoding المعطى، والذي يمكن أن يكون 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

diffieHellman.setPrivateKey(privateKey[, encoding])‎

أضيف في الإصدار: v0.5.0.

يضبط هذا التابع مفتاح Diffie-Hellman الخاص (private key). إن أعطي الوسيط encoding وكانت قيمته إمَّا 'latin1'، أو 'hex'، أو 'base64'، فسيُتوقَع أن يكون الوسيط privateKey سلسلةً نصيةً. أمَّا إن لم يُعطَ الوسيط encoding، فسيُتوقَّع أن يكون الوسيط privateKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

diffieHellman.setPublicKey(publicKey[, encoding])‎

أضيف في الإصدار: v0.5.0.

يضبط هذا التابع مفتاح Diffie-Hellman العام (publicKey key). إن أعطي الوسيط encoding وكانت قيمته إمَّا 'latin1'، أو 'hex'، أو 'base64'، فسيُتوقَع أن يكون الوسيط publicKey سلسلةً نصيةً. أمَّا إن لم يُعطَ الوسيط encoding، فسيُتوقَّع أن يكون الوسيط publicKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

diffieHellman.verifyError

أضيفت في الإصدار: v0.11.12. تمثِّل هذه الخاصية حقلًا مؤلفًا من بت واحد يحتوي على أية تحذيرات و/أو أخطاء ناتجة عن عملية التحقق التي أجريت أثناء تهيئة الكائن DiffieHellman.

القيم الصالحة التي يمكن لهذه الخاصية أن تأخذها هي (كما هو مُعرَّف في الوحدة constants):

  • DH_CHECK_P_NOT_SAFE_PRIME
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

الصنف ECDH

أضيف في الإصدار: v0.11.14.

الصنف ECDH هو أداةٌ لإنشاء تبادلات مفتاح ECDH (اختصارٌ للعبارة Elliptic Curve Diffie-Hellman).

يمكن إنشاء نسخٍ من الصنف ECDH باستعمال الدالة crypto.createECDH()‎.

const crypto = require('crypto');
const assert = require('assert');

// Alice توليد مفاتيح
const alice = crypto.createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Bob توليد مفاتيح
const bob = crypto.createECDH('secp521r1');
const bobKey = bob.generateKeys();

// (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]]])‎

أضيف في الإصدار: v10.0.0.

يحول هذا التابع مفتاح EC Diffie-Hellman العام المحدد بالوسيط key والوسيط curve إلى الصيغة المحددة في الوسيط format. يحدِّد الوسيط format صيغة المفتاح ويمكن أن يكون 'compressed'، أو 'uncompressed'، أو 'hybrid'. يُفسَّر المفتاح المعطى على أنَّه مرمزًا بالترميز inputEncoding المحدد، ويرمز المفتاح المعاد باستعمال الترميز outputEncoding المعطى. يمكن استعمال أحد الترميزات 'latin1'، أو 'hex'، أو 'base64'.

يمكن استعمال التابع crypto.getCurves()‎ للحصول على قائمة بالأسماء المنحنيات (curves) المتاحة. في إصدارات OpenSSL الحديثة، سيُظهِر الأمر openssl ecparam -list_curves اسم ووصف كل قيم المنحي البيضاوي (elliptic curve) المتاحة.

إن لم يُعطَ الوسيط format، فستُستعمَل الصيغة 'uncompressed' الافتراضية.

إن لم يُعطَ الوسيط inputEncoding، فسيُتوقَّع من الوسيط key أن يكون كائنًا من النوع Buffer، أو TypedArray، أو DataView.

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

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

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

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

// يجب أن يكون المفتاح المحول والمفتاح العام غير المضغوط متماثلين تمامًا
console.log(uncompressedKey === ecdh.getPublicKey('hex'));

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

الإصدار التغييرات
v10.0.0 تغيَّرت صيغة الخطأ لدعمٍ أفضلٍ للخطأ الناتج عن مفتاح عام غير صالح.
v6.0.0 تغيرت القيم الافتراضية للوسيط inputEncoding من binary إلى utf8.
v0.11.14 أضيف هذا التابع.

يحسب هذا التابع السر المشترك (shared secret) مستعملًا الوسيط otherPublicKey على أنَّه المفتاح العام للطرف الآخر ثم يعيده. يُفسَّر المفتاح المعطى باستعمال الترميز inputEncoding المعطى، ويرمَّز السر المعاد بالترميز outputEncoding المحدد. يمكن استعمال أحد الترميزات 'latin1'، أو 'hex'، أو 'base64'. إن لم يُعطَ الوسيط inputEncoding، فسيُتوقَّع أن يكون الوسيط otherPublicKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

إن أعطي الوسيط outputEncoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيعاد كائن من النوع Buffer.

سيرمي التابع ecdh.computeSecret()‎ الخطأ ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY عندما يقع أو يخرج خارج المنحني البيضاوي (elliptic curve). لمَّا كان الوسيط otherPublicKey يُزوَّد عادةً من مستخدمٍ بعيدٍ عبر شبكة غير آمنة، فيُنصح بشدة أن يعالج المطورون هذا الاستثناء بما يتوافق مع ذلك.

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

أضيف في الإصدار: v0.11.14.

  • encoding:‏ ‎ <string>
  • format:‏ ‎<string>‎ القيمة الافتراضية هي: 'uncompressed'.
  • القيم المعادة: <Buffer>‏ | <string>

يولد هذا التابع قيمًا لمفتاح EC Diffie-Hellman عام وخاص، ويعيد المفتاح العام منسقًا ومرمزًا وفقًا لقيمة الوسيط format والوسيط encoding. يجب أن يُنقَل هذا المفتاح إلى الطرف الآخر.

يحدد الوسيط format صيغة المفتاح ويمكن أن يكون 'compressed'، أو 'uncompressed'، أو 'hybrid'. إن لم يُعطَ الوسيط format، فستُسعمَل القيمة 'compressed' الافتراضية له.

يمكن أن يأخذ الوسيط encoding إحدى القيم 'latin1'، أو 'hex'، أو 'base64'. إن لم يُعطَ الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيُعاد كائن من النوع Buffer.

ecdh.getPrivateKey([encoding])‎

أضيف في الإصدار: v0.11.14.

يعيد هذا التابع مفتاح EC Diffie-Hellman الخاص (private key) مرمزًا بالترميز encoding المعطى، والذي يمكن أن يكون 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيُعاد كائن من النوع Buffer.

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

أضيف في الإصدار: v0.11.14.

يعيد هذا التابع مفتاح EC Diffie-Hellman العام (private key) مرمزًا بالترميز encoding ومنسَّقًا بالصيغة format المعطاة.

يحدِّد الوسيط format صيغة المفتاح ويمكن أن يكون 'compressed'، أو 'uncompressed'. إن لم يُعطَ الوسيط format، فستُسعمَل القيمة 'compressed' الافتراضية له.

يمكن أن يأخذ الوسيط encoding إحدى القيم 'latin1'، أو 'hex'، أو 'base64'. إن لم يُعطَ الوسيط encoding، فستُعاد سلسلة نصية؛ خلا ذلك، سيُعاد كائن من النوع Buffer.

ecdh.setPrivateKey(privateKey[, encoding])‎

أضيف في الإصدار: v0.11.14.

يضبط هذا التابع مفتاح EC Diffie-Hellman الخاص (private key). إن أعطي الوسيط encoding وكانت قيمته 'latin1'، أو 'hex'، أو 'base64'، فسيُتوقَّع أن يكون الوسيط privateKey سلسلةً نصيةً. أمَّا إن لم يعطَ الوسيط encoding، فسيُتوقَّع أن يكون الوسيط privateKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

إن كان المفتاح privateKey غير صالح للمنحني المحدد عندما أنشئ الكائن ECDH، فسيُرمى خطأٌ. بعد ضبط المفتاح الخاص، يُولَّد المفتاح العام (public point) المرتبط به أيضًا ويُضبَط في الكائن ECDH.

ecdh.setPublicKey(publicKey[, encoding])‎

أضيف في الإصدار: v0.11.14، وأهمل منذ الإصدار: v5.2.0. الاستقرار: 0-مهمل

يضبط هذا التابع مفتاح EC Diffie-Hellman العام (public key). إن أعطي الوسيط encoding وكانت قيمته 'latin1'، أو 'hex'، أو 'base64'، فسيُتوقَّع أن يكون الوسيط publicKey سلسلةً نصيةً. أمَّا إن لم يعطَ الوسيط encoding، فسيُتوقَّع أن يكون الوسيط privateKey كائنًا من النوع Buffer، أو TypedArray، أو DataView.

انتبه إلى أنَّه لا يوجد أي سبب يحيجك إلى استدعاء هذا التابع لأنَّ الكائن ECDH يتطلَّب مفتاحًا خاصًّا ومفتاحًا عامًا من الطرف الآخر فقط لحساب السر المتشارك. سيستدعى عادةً أحد التابعان ecdh.generateKeys()‎ أو ecdh.setPrivateKey()‎. يحاول التابع ecdh.setPrivateKey()‎ توليد المفتاح العام المرتبط بالمفتاح الخاص الذي ضُبِط.

const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');

// .الخاصة السابقة Alice ملاحظة: هذه طريقة مختصرة لتحديد أحد مفاتيح 
// .من غير الحكمة استعمال مفتاح خاص يمكن التنبؤ بقيمته في تطبيق حقيقي
alice.setPrivateKey(
  crypto.createHash('sha256').update('alice', 'utf8').digest()
);

// زوجًا من المفاتيح المولدة حديثًا وذات تشفير قوي وشبه عشوائية Bob يستعمل
bob.generateKeys();

const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

// متماثلين في القيمة aliceSecret و bobSecret يجب أن يكون
console.log(aliceSecret === bobSecret);

الصنف Hash

أضيف في الإصدار: v0.1.92.

الصنف Hash هو أداةٌ لإنشاء القيم hash للبيانات. يمكن استعمال هذا الصنف بإحدى الطريقتين التاليتين:

  • يُستعمَل كمجرًى قابلًا للقراءة والكتابة، إذ تكتب فيه البيانات لتوليد القيمة hash المقابلة لها في الجانب القابل للقراءة من هذا المجرى، أو
  • يُستعمَل التابعان hash.update()‎ و hash.digest()‎ لتوليد القيمة hash المحسوبة.

يُستعمَل التابع crypto.createHash()‎ لإنشاء نسخٍ من الصنف Hash. لا يجب إنشاء الكائنات Hash باستعمال الكلمة المفتاحية new مباشرةً.

يوضح المثال التالي كيفية استعمال الكائنات Hash كمجاري:

const crypto = require('crypto');
const hash = crypto.createHash('sha256');

hash.on('readable', () => {
  const data = hash.read();
  if (data) {
    console.log(data.toString('hex'));
    // سيُطبَع:
    //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
  }
});

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

ويوضح المثال التالي كيفية استعمال الصنف Hash مع نقل محتويات المجاري (piped streams):

 
const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('sha256');

const input = fs.createReadStream('test.js');
input.pipe(hash).pipe(process.stdout);

أمَّا المثال التالي، فيوضِّح كيفية استعمال التابعان hash.update()‎ و hash.digest()‎:

const crypto = require('crypto');
const hash = crypto.createHash('sha256');

hash.update('some data to hash');
console.log(hash.digest('hex'));
// سيُطبَع:
//   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50

hash.digest([encoding])‎

أضيف في الإصدار: v0.1.92.

يحسب هذا التابع القيمة hash (إذ يصف المصطلح digest ببساطة عملية إيجاد القيم hash المختصرة) لجميع البيانات الممررة إليه (باستعمال التابع hash.update()‎‎). يمكن أن يأخذ الوسيط encoding القيمة 'hex'، أو 'latin1'، أو 'base64'. إن لم يُعطَ هذا الوسيط، فستُعاد سلسلة نصية؛ خلا ذلك، سيُعاد كائن من النوع Buffer. لا يمكن استعمال الكائن Hash مرةً أخرى بعد استدعاء التابع hash.digest()‎. سيؤدي استدعاء التابع hash.digest()‎ عدة مرات إلى رمي خطأٍ.

hash.update(data[, inputEncoding])‎

سجل التغييرات
الإصدار التغييرات
v6.0.0 تغيرت القيمة الافتراضية للوسيط inputEncoding من binary إلى utf8.
v0.1.92 أضيف هذا التابع.

يحدِّث هذا التابع محتوى الكائن Hash مع البيانات data المعطاة، وبالترميز inputEncoding المعطى والذي يمكن أن يكون 'utf8'، أو 'ascii'، أو 'latin1'. إن أعطي الوسيط encoding وكانت الوسيط data سلسلةً نصيةً، فسيُفرَض استعمال الترميز 'utf8'. إن كان الوسيط data كائنًا من النوع Buffer، أو TypedArray، أو DataView، فسيُتحاهَل حينها الوسيط inputEncoding إن أعطي. يمكن استدعاء هذا التابع عدة مرات مع بيانات جديدة طالما كان متاحًا في المجرى.

الصنف Hmac

أضيف في الإصدار: v0.1.94. الصنف Hmac هو أداةٌ لإنشاء التشفير HMAC (اختصارٌ للعبارة keyed-hash message authentication code أو العبارة hash-based message authentication code) للبيانات. يمكن استعمال هذا الصنف بإحدى الطريقتين التاليتين:

  • يُستعمَل كمجرًى قابلًا للقراءة والكتابة، إذ تكتب فيه البيانات لتوليد التشفير HMAC المقابل لها في الجانب القابل للقراءة من هذا المجرى، أو
  • يُستعمَل التابعان hmac.update()‎ و hmac.digest()‎ لتوليد القيمة HMAC المحسوبة.

يُستعمَل التابع crypto.createHmac()‎ لإنشاء نسخٍ من الصنف Hmac. لا يجب إنشاء الكائنات Hmac باستعمال الكلمة المفتاحية new مباشرةً. يوضح المثال التالي كيفية استعمال الكائنات Hmac كمجاري:

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

hmac.on('readable', () => {
  const data = hmac.read();
  if (data) {
    console.log(data.toString('hex'));
    // سيُطبَع:
    //   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
  }
});

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

ويوضح المثال التالي كيفية استعمال الصنف Hash مع نقل محتويات المجاري (piped streams)

const crypto = require('crypto');
const fs = require('fs');
const hmac = crypto.createHmac('sha256', 'a secret');

const input = fs.createReadStream('test.js');
input.pipe(hmac).pipe(process.stdout);
أما المثال التالي، فيُوضِّح كيفية استعمال التابعان hmac.update()‎ و hmac.digest()‎:
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'a secret');

hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// سيُطبَع:
//   7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e

hmac.digest([encoding])‎

أضيف في الإصدار: v0.1.94.

يحسب هذا التابع القيمة hash للتشفير HMAC (إذ يصف المصطلح digest ببساطة عملية إيجاد القيم hash) لجميع البيانات الممررة إليه باستعمال التابع hash.update()‎. يمكن أن يأخذ الوسيط encoding القيمة 'hex'، أو 'latin1'، أو 'base64'. إن لم يُعطَ هذا الوسيط، فستُعاد سلسلة نصية؛ خلا ذلك، سيُعاد كائن من النوع Buffer. لا يمكن استعمال الكائن Hmac مرةً أخرى بعد استدعاء التابع hmac.digest()‎. سيؤدي استدعاء التابع hmac.digest()‎ عدة مرات إلى رمي خطأٍ.

hmac.update(data[, inputEncoding])‎

سجل التغييرات
الإصدار التغييرات
v6.0.0 تغيرت القيمة الافتراضية للوسيط inputEncoding من binary إلى utf8.
v0.1.94 أضيف هذا التابع.

يحدِّث هذا التابع محتوى الكائن Hmac مع البيانات data المعطاة، وبالترميز inputEncoding المعطى والذي يمكن أن يكون 'utf8'، أو 'ascii'، أو 'latin1'. إن أعطي الوسيط encoding وكانت الوسيط data سلسلة نصية، فسيُفرَض استعمال الترميز 'utf8'. إن كان الوسيط data كائنًا من النوع Buffer، أو TypedArray، أو DataView، فسيُتحاهَل حينها الوسيط inputEncoding إن أعطي. يمكن استدعاء هذا التابع عدة مرات مع بيانات جديدة طالما كان متاحًا في المجرى.

الصنف Sign

أضيف في الإصدار: v0.1.92. الصنف Sign هو أداةٌ لتوليد التواقيع (signatures). يمكن استعمال هذا الصنف بإحدى الطريقتين التاليتين:

  • يُستعمَل كمجرًى قابلًا للكتابة، إذ تكتب فيه البيانات المراد توقيعها ثم يُستعمَل التابع sign.sign()‎ لتوليد وإعادة التوقيع، أو
  • يُستعمَل التابعان sign.update()‎ و sign.sign()‎ لتوليد التوقيع.

يُستعمَل التابع crypto.createSign()‎ لإنشاء نسخٍ من الصنف Sign، إذ تُمرَّر إليه سلسلة نصية تحوي اسم للدالة hash المراد استعمالها. لا يجب إنشاء الكائنات Sign باستعمال الكلمة المفتاحية new مباشرةً. يوضّح المثال التالي كيفية استعمال الكائنات Sign كمجاري:

const crypto = require('crypto');
const sign = crypto.createSign('SHA256');

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

const privateKey = getPrivateKeySomehow();
console.log(sign.sign(privateKey, 'hex'));
// .SHA-256 سيُطبَع التوقيع المحسوب باستعمال المفتاح الخاص المحدد والخوارزمية 
// انظر المعامل) RSASSA-PKCS1-v1_5 يجب استعمال الخوارزمية ،RSA من أجل المفاتيح
// فيجب استعمال ،EC أما من أجل مفاتيح .(RSASSA-PSS في الأسفل من أجل padding
// ECDSA الخوارزمية

أما المثال التالي، فيوضِّح كيفية استعمال التابعان sign.update()‎ و sign.sign()‎:

 
const crypto = require('crypto');
const sign = crypto.createSign('SHA256');

sign.update('some data to sign');

const privateKey = getPrivateKeySomehow();
console.log(sign.sign(privateKey, 'hex'));
// سيُطبَع التوقيع المحسوب

في بعض الحالات، يمكن إنشاء النسخة Sign أيضًا عبر تمرير اسم خوارزمية التوقيع، مثل 'RSA-SHA256'؛ سيؤدي هذا إلى استعمال الخوارزمية المقابلة لحساب القيمة hash. انتبه إلى أنَّ هذا الأمر لا ينطبق على كل خوارزميات التوقيع، مثل الخوارزمية 'ecdsa-with-SHA256'. في مثل هذه الحالة، استعمل أسماء خوارزميات hash عوضًا عن ذلك. يوضح المثال التالي كيفية حساب قيمة توقيع باستعمال اسم خوارزمية توقيع إرثية (legacy signature algorithm):

const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');

sign.update('some data to sign');

const privateKey = getPrivateKeySomehow();
console.log(sign.sign(privateKey, 'hex'));
// سيُطبَع التوقيع المحسوب

sign.sign(privateKey[, outputFormat])‎

سجل التغييرات
الإصدار التغييرات
v8.0.0 أضيف دعمٌ للخوارزمية RSASSA-PSS وخيارات أخرى.
v0.1.92 أضيف هذا التابع.

يحسب هذا التابع التوقيع لكل البيانات المُمرَّرة إليه باستعمال إمَّا التابع sign.update()‎ أو التابع sign.write()‎. يمكن أن يكون الوسيط privateKey كائنًا أو سلسلة نصية. إن كان سلسلة نصية، فسيُعامَل وكأنه مفتاح خام (raw key) بدون عبارة مرور (passphrase). أمَّا إن كان الوسيط privateKey كائنًا، فيجب أن يحتوي على خاصية واحدة أو أكثر من الخاصيات التالية:

  • Key:‏ ‎<string>‎ مفتاح خاص مرمَّز بالترميز PEM (مطلوب).
  • passphrase:‏ ‎<string>‎ عبارة مرور من أجل المفتاح الخاص.
  • padding:‏ ‎<integer>‎ قيمة حاشية اختيارية من أجل RSA، وتأخذ إحدى القيم التالية:
    • crypto.constants.RSA_PKCS1_PADDING (القيمة الافتراضية)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

انتبه إلى أنَّ القيمة RSA_PKCS1_PSS_PADDING ستستعمل MGF1 مع نفس الدالة hash المستعملة لتوقيع الرسالة كما هو محدَّد في الفقرة 3.1 من المعيار RFC 4055.

  • saltLength:‏ ‎‎<integer>‎ طول إضافي (salt length) يُستعمَل عندما تكون قيمة padding هي RSA_PKCS1_PSS_PADDING. تضبط القيمة crypto.constants.RSA_PSS_SALTLEN_DIGEST الخاصَّة الطول الإضافي إلى طول القيمة hash، وتضبط القيمة crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (الافتراضية) ذلك الطول إلى أكبر قيمة مسموحٌ بها.

يمكن أن يأخذ الوسيط outputFormat إحدى القيم 'latin1'، أو 'hex'، أو 'base64'. إن أعطي هذا الوسيط، فستُعاد سلسلة نصية. خلا ذلك، سيُعاد كائن من النوع Buffer. لا يمكن استعمال الكائن Sign مرةً أخرى بعد استدعاء التابع sign.sign()‎. سينتج عن استدعاء التابع sign.sign()‎ عدة مرات خطأٌ مرمي.

sign.update(data[, inputEncoding])‎

سجل التغييرات
الإصدار التغييرات
v6.0.0 تغيرت القيمة الافتراضية للوسيط inputEncoding من binary إلى utf8.
v0.1.92 أضيف هذا التابع.

يحدِّث هذا التابع محتوى الكائن Sign مع البيانات data المعطاة، وبالترميز inputEncoding المعطى والذي يمكن أن يكون 'utf8'، أو 'ascii'، أو 'latin1'. إن أعطي الوسيط encoding وكان الوسيط data سلسلةً نصيةً، فسيُفرَض استعمال الترميز 'utf8'. إن كان الوسيط data كائنًا من النوع Buffer، أو TypedArray، أو DataView، فسيُتجاهَل حينها الوسيط inputEncoding إن أعطي. يمكن استدعاء هذا التابع عدة مرات مع بيانات جديدة طالما كان متاحًا في المجرى.

الصنف Verify

أضيف في الإصدار: v0.1.92.

الصنف Verify هو أداةٌ للتحقق من التوقيع. يمكن استعمال هذا الصنف بإحدى الطريقتين التاليتين:

  • يستعمل كمجرًى قابلًا للكتابة، إذ تكتب فيه البيانات المراد التحقق من صحتها مع التوقيع المقابل لها، أو
  • يُستعمَل التابعان verify.update()‎ و verify.verify()‎ للتحقق من التوقيع.

يُستعمَل التابع crypto.createVerify()‎ لإنشاء نسخٍ من الصنف Verify إذ تُمرَّر إليه سلسلة نصية تحوي اسم للدالة hash المراد استعمالها. لا يجب إنشاء الكائنات Verify باستعمال الكلمة المفتاحية new مباشرةً. يوضح المثال التالي كيفية استعمال الكائنات Verify كمجاري:

const crypto = require('crypto');
const verify = crypto.createVerify('SHA256');

verify.write('some data to sign');
verify.end();

const publicKey = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(publicKey, signature));
// false أو القيمة true ستُطبع القيمة

ويوضح المثال التالي كيفية استعمال التابع verify.update()‎ مع التابع verify.verify()‎:

 
const crypto = require('crypto');
const verify = crypto.createVerify('SHA256');

verify.update('some data to sign');

const publicKey = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(publicKey, signature));
// false أو القيمة true ستُطبع القيمة

verify.update(data[, inputEncoding])‎

سجل التغييرات
الإصدار التغييرات
v6.0.0 تغيرت القيمة الافتراضية للوسيط inputEncoding من binary إلى utf8.
v0.1.92 أضيف هذا التابع.

يحدِّث هذا التابع محتوى الكائن Verify مع البيانات data المعطاة، وبالترميز inputEncoding المعطى والذي يمكن أن يكون 'utf8'، أو 'ascii'، أو 'latin1'. إن أعطي الوسيط encoding وكانت الوسيط data سلسلة نصية، فسيُفرَض استعمال الترميز 'utf8'. إن كان الوسيط data كائنًا من النوع Buffer، أو TypedArray، أو DataView، فسيُتحاهَل حينها الوسيط inputEncoding إن أعطي. يمكن استدعاء هذا التابع عدة مرات مع بيانات جديدة طالما كان متاحًا في المجرى.

verify.verify(object, signature[, signatureFormat])‎

سجل التغييرات
الإصدار التغييرات
v8.0.0 أضيف دعمٌ للخوارزمية RSASSA-PSS وخيارات أخرى.
v0.1.92 أضيف هذا التابع.

يتحقق هذا التابع من كون البيانات المعطاة تستعمل الكائن object والتوقيع signature المعطى. يمكن أن يكون الوسيط object إمَّا سلسلة نصية تحتوي على كائن مرمز بالترميز PEM -الذي يمكن أن يكون مفتاح RSA عام، أو مفتاح DSA عام، أو شهادةً من النوع X.509-، أو كائنًا يحوي خاصيةً واحدةً أو أكثر من الخاصيات التالية:

  • Key:‏ ‎<string>‎ مفتاح خاص مُرمَّز بالترميز PEM (مطلوب).
  • padding:‏ ‎<integer‎>‎ قيمة حاشية اختيارية من أجل RSA، وتأخذ إحدى القيم التالية:
    • crypto.constants.RSA_PKCS1_PADDING (القيمة الافتراضية)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

انتبه إلى أنَّ القيمة RSA_PKCS1_PSS_PADDING ستستعمل MGF1 مع نفس الدالة hash التي استعملت في توقيع الرسالة كما هو محدد في الفقرة 3.1 من المعيار RFC 4055.

  • saltLength:‏ ‎<integer‎>‎ طول إضافي (salt length، أو طول ملحي) يُستعمَل عندما تكون قيمة padding هي RSA_PKCS1_PSS_PADDING. تضبط القيمة crypto.constants.RSA_PSS_SALTLEN_DIGEST الخاصَّة الطول الإضافي إلى طول القيمة hash، وتضبط القيمة crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (الافتراضية) ذلك الطول إلى أكبر قيمة مسموح بها.

الوسيط signature هو التوقيع المحسوب مسبقًا للبيانات بالترميز signatureFormat والذي يمكن أن يأخذ إحدى القيم 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط signatureFormat، فسيُتوقَّع أن يكون الوسيط signature سلسلةً نصيةً. خلا ذلك، سيُتوقَّع أن يكون كائنًا من النوع Buffer، أو TypedArray، أو DataView. لا يمكن استعمال الكائن Verify مرةً أخرى بعد استدعاء التابع verify.verify()‎. سينتج عن استدعاء التابع sign.sign()‎ عدة مرات خطأ مرمي.

توابع وخاصيات الوحدة crypto

سنورد في ما يلي التوابع والخاصيات المستعملة في الوحدة crypto:

Crypto.constants

أضيفت في الإصدار: v6.3.0.

  • القيم المعادة: <Object> يعاد كائن يحتوي على الثوابت التي تُستعمَل عادةً مع العمليات المتعلقة بالتشفير (crypto) والأمن (security). الثوابت المعرَّفة حاليًا موجودةٌ في قسم «ثوابت الوحدة Crypto».

crypto.DEFAULT_ENCODING

أضيفت في الإصدار: v0.9.3، وأهملت بدءًا من الإصدار: 10.0.0. تعيد هذه الخاصية الترميز الافتراضي المراد استعماله مع الدوال التي يمكن أن تُمرَّر إليها إمَّا سلاسل نصية أو كائنات من النوع Buffer. القيمة الافتراضية هي 'buffer' أي استعمال الكائنات Buffer افتراضيًّا مع التوابع. سبب وجود الآلية crypto.DEFAULT_ENCODING هي للتوافقية الرجوعية (backwards compatibility) مع التطبيقات الإرثية (legacy programs) التي تتوقع أن يكون الترميز 'latin1' هو الترميز الافتراضي. يجب على التطبيقات الجديدة أن تتوقع أنَّ 'buffer' هي القيمة الافتراضية. انتبه إلى أنَّ هذه الخاصية قد أُهملَت.

crypto.fips

أضيفت في الإصدار: v6.0.0، وأهملت بدءًا من الإصدار: 10.0.0. تُستعمَل هذه الخاصية للتحقق فيما إذا كان مزود الوحدة crypto المتوافق مع FIPS يُستعمَل حاليًا وذلك للتحكم به. ضبط هذه الخاصية إلى القيمة true يتطلب من FIPS أن تبني Node.js. انتبه إلى أنَّ هذه الخاصية قد أُهملَت. استعمل رجاءً التابع crypto.setFips()‎ والتابع crypto.getFips()‎ عوضًا عن ذلك.

crypto.createCipher(algorithm, password[, options])‎

الإصدار التغييرات
v10.10.0 أصبح التشفير باستعمال الوضع OCB مدعومًا الآن.
v10.2.0 يمكن الآن استعمال الخيار authTagLength لتوليد بطاقات مصادقة قصيرة في الوضع GCM بحجم 16 بايت افتراضيًّا.
v10.0.0 أهمل هذا التابع.
v0.1.94 أضيف هذا التابع.

الاستقرار: 0-مهمل. استعمل التابع crypto.createCipheriv()‎ عوضًا عنه.

ينشئ هذا التابع كائنًا من النوع Cipher ثم يعيده وذلك باستعمال الخوارزمية algorithm وكلمة المرور password. يتحكم الوسيط options بسلوك المجرى وهو اختياري إلا عند التشفير باستعمال الوضع CCM أو الوضع OCB (مثل 'aes-128-ccm'). في هذه الحالة، يُطلَب الخيار authTagLength لتحديد طول بطاقة المصادقة بواحدة البايت (راجع الوضع CCM في الأسفل). في الوضع GCM، لا يُطلب استعمال الخيار authTagLength، ولكن يمكن استعماله لضبط طول بطاقة المصادقة التي ستُعاد عبر التابع getAuthTag()‎؛ الطول الافتراضي هو 16 بايت. تعتمد الخوارزمية algorithm المعطاة على OpenSSL، مثل 'aes192' وغيرها. في إصدارات OpenSSL الحديثة، سيُظهر الأمر openssl list -cipher-algorithms (أو openssl list-cipher-algorithms في الإصدارات القديمة) خوارزميات التشفير المتاحة. يُستعمَل الوسيط password لاشتقاق مفتاح التشفير والمتغير الأولي (initialization vector، ويدعى اختصارًا IV أو يدعى أحيانًا starting variable [تختصر إلى SV]). يجب أن يكون إمَّا سلسلةً نصيةً مرمزةً بالترميز 'latin1'، أو كائنًا من النوع Buffer، أو TypedArray، أو DataView. يُنفَّذ التابع crypto.createCipher()‎ لاشتقاق المفاتيح باستعمال الدالة EVP_BytesToKey التي تخص OpenSSL مع ضبط الخوارزمية التي تحسب قيمة hash إلى MD5، والتكرار مرة واحدة، وبدون طول إضافي (salt). يسمح نقص الطول الإضافي (salt) بهجمات القاموس (dictionary attacks) لأنَّ كلمة المرور نفسها تولِّد دومًا المفتاح نفسه. يؤدي أيضًا عدد مرات التكرار المنخفض والخوارزمية hash الغير آمنة بالتحقق من كلمات المرور بسرعة كبيرة. تماشيًا مع توصية OpenSSL باستعمال خوارزمية حديثة عوضًا عن EVP_BytesToKey، يوصى بأن يعمل المطورون على اشتقاق مفتاح ومتغير أولي (IV) بأنفسهم باستعمال التابع crypto.scrypt()‎، وأن يستعملوا التابع crypto.createCipheriv()‎ لإنشاء الكائن Cipher. لا يجب على المستخدمين أن يستعملوا القيم المشفرة مع وضع العداد (counter mode) -مثل CTR، أو GCM، أو CCM- في التابع crypto.createCipher()‎. سيُطلَق تحذير عند تنفيذ ذلك لتجنب خطر إعادة استعمال المتغير IV الأولي الذي يؤدي إلى حدوث نقطة ضعف أو ثغرة. لمزيد من التفاصيل حول حالة إعادة استعمال المتغير IV في الوضع GCM، تصفَّح هذا المرجع.

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

سجل التغييرات
الإصدار التغييرات
v10.10.0 أصبح التشفير باستعمال الوضع OCB مدعومًا الآن.
v10.2.0 يمكن الآن استعمال الخيار authTagLength لتوليد بطاقات مصادقة قصيرة في الوضع GCM بحجم 16 بايت افتراضيًّا.
v9.9.0 يمكن الآن أن يأخذ المتغير iv القيمة null عند عدم الحاجة إلى متغير أولي (initialization vector).
v0.1.94 أضيف هذا التابع.

ينشئ هذا التابع كائنًا من النوع Cipher ثم يعيده وذلك باستعمال الخوارزمية algorithm والمفتاح key والمتغير الأولي iv. يتحكم الوسيط options بسلوك المجرى وهو اختياري إلا عند التشفير باستعمال الوضع CCM أو الوضع OCB (مثل 'aes-128-ccm'). في هذه الحالة، يُطلَب الخيار authTagLength لتحديد طول بطاقة المصادقة بواحدة البايت (راجع الوضع CCM في الأسفل). في الوضع GCM، لا يُطلب استعمال الخيار authTagLength، ولكن يمكن استعماله لضبط طول بطاقة المصادقة التي ستُعاَد عبر التابع getAuthTag()‎‎؛ الطول الافتراضي هو 16 بايت. تعتمد الخوارزمية algorithm المعطاة على OpenSSL، مثل 'aes192' وغيرها. في إصدارات OpenSSL الحديثة، سيُظهِر الأمر openssl list -cipher-algorithms (أو openssl list-cipher-algorithms في الإصدارات القديمة) خوارزميات التشفير المتاحة. الوسيط key هو المفتاح الخام (raw key) الذي تستعمله الخوارزمية algorithm، والوسيط iv هو المتغير الأولي (initialization vector). يجب أن يكون كلا هذين الوسيطين إما سلسلةً نصيةً مرمزةً بالترميز 'utf8'، أو كائنًا من النوع Buffer، أو TypedArray، أو DataView. إن لم يكن هنالك حاجة لاستعمال المتغير الأولي في عملية التشفير، فيمكن استعمال القيمة null حينئذٍ مع الوسيط iv. يجب أن تكون المتغيرات الأولية (IV) فريدةً وغير قابلة للتنبؤ بأي شكل من الأشكال. من الناحية المثالية، يجب أن يكونوا قيمًا عشوائية بشكل مشفرة. لا يفترض أن تكون هذه المتغيرات سرِّية، إذ تضاف عادةً بدون تشفير إلى الرسائل المشفرة نصيًّا (ciphertext messages). قد يبدو -للوهلة الأولى- أن هنالك شيئًا من التناقض المتعلق بالشرط الذي ينص على أنَّ هذه المتغيرات يجب أن تكون فريدةً وغير قابلة للتنبؤ في آنٍ واحدٍ ولكن لا يجب أن تكون سرية أيضًا؛ على أي حال، من المهم حاليًا أن تبقي في بالك أنه لا ينبغي على المهاجم أن يكون قادرًا على التنبؤ في وقت مبكر ما هي قيمة المتغير الأولي التي ستُعطَى.

crypto.createCredentials(details)‎

أضيف في الإصدار: 0.1.92، وأهمل في الإصدار: v0.11.13.

الاستقرار: 0-مهمل؛ استعمل التابع tls.createSecureContext()‎ عوضًا عنه.

  • details:‏ ‎<Object>‎ مماثل تمامًا للتابع tls.createSecureContext()‎.
  • القيم المعادة: <tls.SecureContext>

هذا التابع هو تابعٌ مهملٌ، ويستعمل في إنشاء الكائن tls.SecureContext وإعادته. على أي حال، لا يجب استعماله، إذ حل التابع tls.createSecureContext()‎ -الذي يشبه هذا التابع في الوسائط والقيم المعادة تمامًا- مكانه. يعيد هذا التابع الكائن tls.SecureContext، كما يفعل التابع tls.createSecureContext()‎ عند استدعائه.

crypto.createDecipher(algorithm, password[, options])‎

سجل التغييرات
الإصدار التغييرات
v10.10.0 أصبح التشفير باستعمال الوضع OCB مدعومًا الآن.
v10.0.0 أهمل هذا التابع.
v0.1.94 أضيف هذا التابع.

الاستقرار: 0-مهمل؛ استعمل التابع crypto.createDecipheriv()‎ عوضًا عنه.

ينشئ هذا التابع كائنًا من النوع Decipher ثم يعيده وذلك باستعمال الخوارزمية algorithm وكلمة المرور password (المفتاح). يتحكم الوسيط options بسلوك المجرى وهو اختيار إلا عند التشفير باستعمال الوضع CCM أو الوضع OCB (مثل 'aes-128-ccm'). في هذه الحالة، يُطلب الخيار authTagLength لتحديد طول بطاقة المصادقة بواحدة البايت (راجع الوضع CCM في الأسفل). يُنفَّذ التابع crypto.createDecipher()‎ لاشتقاق المفاتيح باستعمال الدالة EVP_BytesToKey التي تخص OpenSSL مع ضبط الخوارزمية التي تحسب قيمة hash إلى MD5، والتكرار مرةً واحدةً، وبدون طول إضافي (salt). يسمح نقص الطول الإضافي (salt) بهجمات القاموس (dictionary attacks) لأنَّ كلمة المرور نفسها تولد دومًا المفتاح نفسه. يؤدي أيضًا عدد مرات التكرار المنخفض والخوارزمية hash الغير آمنة إلى التحقق من كلمات المرور بسرعة كبيرة. تماشيًا مع توصية OpenSSL باستعمال خوارزمية أحدث عوضًا عن EVP_BytesToKey، يوصى بأن يعمل المطورون على اشتقاق مفتاح ومتغير أولي (IV) بأنفسهم باستعمال التابع crypto.scrypt()‎، وأن يستعملوا التابع crypto.createDecipheriv()‎ لإنشاء الكائن Decipher.

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

سجل التغييرات
الإصدار التغييرات
v10.10.0 أصبح التشفير باستعمال الوضع OCB مدعومًا الآن.
v10.2.0 يمكن الآن استعمال الخيار authTagLength لتقييد أطوال بطاقة المصادقة GCM المقبولة.
v9.9.0 يمكن الآن أن يأخذ المتغير iv القيمة null عند عدم الحاجة إلى استعمال متغير أولي (initialization vector).
v0.1.94 أضيف هذا التابع.

ينشئ هذا التابع كائنًا من النوع Decipher ثم يعيده وذلك باستعمال الخوارزمية algorithm والمفتاح key والمتغير الأولي (IV). يتحكم الوسيط options بسلوك المجرى وهو اختياري إلا عند التشفير باستعمال الوضع CCM أو الوضع OCB (مثل 'aes-128-ccm'). في هذه الحالة، يُطلَب الخيار authTagLength لتحديد طول بطاقة المصادقة بواحدة البايت (راجع الوضع CCM في الأسفل). في الوضع GCM، لا يُطلب استعمال الخيار authTagLength، ولكن يمكن استعماله لتقييد طول بطاقات المصادقة المقبولة بطول محدد. تعتمد الخوارزمية algorithm المعطاة على OpenSSL، مثل 'aes192' وغيرها. في إصدارات OpenSSL الحديثة، سيُظهِر الأمر openssl list -cipher-algorithms (أو openssl list-cipher-algorithms في الإصدارات القديمة) خوارزميات التشفير المتاحة. الوسيط key هو المفتاح الخام (raw key) الذي تستعمله الخوارزمية algorithm، والوسيط iv هو المتغير الأولي (initialization vector). يجب أن يكون كلا هذين الوسيطين إما سلسلةً نصيةً مرمزةً بالترميز 'utf8'، أو كائنًا من النوع Buffer، أو النوع TypedArray، أو النوع DataView. إن لم يكن هنالك حاجة لاستعمال المتغير الأولي في عملية التشفير، فيمكن استعمال القيمة null حينئذٍ مع الوسيط iv. يجب أن تكون المتغيرات الأولية (IVs) فريدةً وغير قابلة للتنبؤ بأي شكل من الأشكال. من الناحية المثالية، يجب أن يكونوا قيمًا عشوائية بطريقة مشفرة. لا يفترض أن تكون هذه المتغيرات سرِّية، إذ تضاف عادةً بدون تشفير إلى الرسائل المشفرة نصيًّا (ciphertext messages). قد يبدو أن هنالك شيئًا من التناقض المتعلق بالشرط الذي ينص على أنَّ هذه المتغيرات يجب أن تكون فريدةً وغير قابلة للتنبؤ في آنٍ واحدٍ ولكن لا يجب أن تكون سرية أيضًا؛ على أي حال، من المهم حاليًا أن تُبقِي في بالك أنَّه لا ينبغي على المهاجم أن يكون قادرًا على التنبؤ في وقت مبكر بقيمة المتغير IV التي ستعطى.

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

سجل التغييرات
الإصدار التغييرات
v8.0.0 يمكن أن يكون الوسيط prime الآن كائنًا من النوع TypeArra أو النوع DataView.
v8.0.0 يمكن أن يكون الوسيط prime الآن كائنًا من النوع Uint8Array.
v6.0.0 تغيرت القيمة الافتراضية لمعاملات الترميز الآن من binary إلى utf8.
v0.11.12 أضيف هذا التابع.

ينشئ هذا التابع كائن تبادل المفتاح DiffieHellman باستعمال العدد الأولي prime المعطى والمولد generator الاختياري (إن أعطي). يمكن أن يكون الوسيط gernerator عددًا، أو سلسلة نصية، أو كائنًا من النوع Buffer. إن لم يُعطَ هذا الوسيط، فستكون قيمته الافتراضية هي: 2. يمكن أن يأخذ الوسيطان primeEncoding و generatorEncoding القيمة 'latin1'، أو 'hex'، أو 'base64'. إن أعطي الوسيط generatorEncoding، فسيُتوقَع أن يكون الوسيط gernerator سلسلةً نصيةً؛ خلا ذلك، سيُتوقع أن يكون عددًا، أو كائنًا من النوع Buffer، أو النوع TypedArray، أو النوع DataView.

crypto.createDiffieHellman(primeLength[, generator])‎

أضيف في الإصدار: v0.5.0.

ينشئ هذا التابع كائن تبادل المفتاح DiffieHellman ويولد عددًا أوليًا بطول primeLength بت باستعمال المولد generator العددي الاختياري. إن لم يُعطَ الوسيط generator، فستُستعمَل القيمة 2 الافتراضية.

crypto.createECDH(curveName)‎

أضيف في الإصدار: v0.11.14.

ينشئ هذا التابع كائن تبادل المفتاح ECDH (اختصارٌ للعبارة Elliptic Curve Diffie-Hellman) باستعمال المنحني المُعرَّف مسبقًا والمُحدَّد عبر السلسلة النصية curveName. يمكن استعمال التابع crypto.getCurves()‎ للحصول على قائمة بأسماء المنحنيات المتوافرة. في إصدارات OpenSSL الأخيرة، سيُظهر الأمر openssl ecparam -list_curves أيضًا اسمًا ووصفًا لكل منحني بيضاوي (elliptic curve) متاح.

crypto.createHash(algorithm[, options])‎

أضيف في الإصدار: v0.1.92.

  • algorithm:‏ ‎ <string>
  • options:‏ <Object> خيارات التابع stream.transform.
  • القيم المعادة: <Hash>

ينشئ هذا التابع الكائن Hash الذي يمكن استعماله لتوليد القيمة hash المشفرة للبيانات والرسائل باستعمال الخوارزمية algorithm المعطاة. يعتمد الوسيط algorithm على الخوارزميات المتاحة التي يدعمها الإصدار OpenSSL المثبَّت على المنصة آنذاك، مثل 'sha256' و 'sha512' وغيرها. في إصدارات OpenSSL الحديثة، سيُظهِر الأمر openssl list -digest-algorithms (أو الأمر openssl list-message-digest-algorithms في الإصدارات القديمة) الخوارزميات المتاحة التي تحسب القيمة hash. يوضح المثال التالي كيفية توليد المجموع sha256 لملف:

const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');

const hash = crypto.createHash('sha256');

const input = fs.createReadStream(filename);
input.on('readable', () => {
  const data = input.read();
  if (data)
    hash.update(data);
  else {
    console.log(`${hash.digest('hex')} ${filename}`);
  }
});

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

أضيف في الإصدار: v0.1.94.

  • Options:‏ ‎<Object>‎ خيارات التابع stream.transform.
  • القيم المعادة: <Hmac>

ينشئ هذا التابع الكائن Hmac ثم يعيده والذي يستعمل الخوارزمية algorithm والمفتاح key المعطى. يتحكم الوسيط options الاختياري بسلوك المجرى. يعتمد الوسيط algorithm على الخوارزميات المتاحة التي يدعمها الإصدار OpenSSL المثبَّت على المنصة آنذاك، مثل 'sha256' و 'sha512' وغيرها. في إصدارات OpenSSL الحديثة، سيُظر الأمر openssl list -digest-algorithms (أو الأمر openssl list-message-digest-algorithms في الإصدارات القديمة) الخوارزميات المتاحة التي تحسب القيمة hash. الوسيط key هو المفتاح HMAC المستعمل في توليد قيمة hash المشفرة للكائن Hmac. يوضح المثال التالي كيفية توليد HMAC باستعمال الخوارزمية sha256 لملف:

const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');

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

const input = fs.createReadStream(filename);
input.on('readable', () => {
  const data = input.read();
  if (data)
    hmac.update(data);
  else {
    console.log(`${hmac.digest('hex')} ${filename}`);
  }
});

crypto.createSign(algorithm[, options])‎

أضيف في الإصدار: v0.1.92.

  • algorithm:‏ ‎ <string>
  • options:‏ <Object> خيارات التابع stream.Writable.
  • القيم المعادة: <Sign>

ينشئ هذا التابع كائنًا من النوع Sign التي يستعمل الخوارزمية algorithm المعطاة. استعمل التابع crypto.getHashes()‎ للحصول على مصفوفة بأسماء خوارزميات التوقيع المتاحة. يتحكم الوسيط options الاختياري بسلوك المجرى stream.Writable.

crypto.createVerify(algorithm[, options])‎

أضيف في الإصدار: v0.1.92.

  • Options:‏ <Object> خيارات التابع stream.Writable.

ينشئ هذا التابع كائنًا من النوع Verify الذي يستعمل الخوارزمية algorithm المعطاة. استعمل التابع crypto.getHashes()‎ للحصول على مصفوفة بأسماء خوارزميات التوقيع المتاحة. يتحكم الوسيط options الاختياري بسلوك المجرى stream.Writable.

crypto.getCiphers()‎

أضيف في الإصدار: v0.9.3.

  • القيم المعادة: <string[]‎> مصفوفةٌ بأسماء خوارزميات التشفير المدعومة.
const ciphers = crypto.getCiphers();
console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]

crypto.getCurves()‎

أضيف في الإصدار: v2.3.0.

  • القيم المعادة: <string[]‎> مصفوفةٌ بأسماء المنحنيات البيضاوية (elliptic curves) المدعومة.
const curves = crypto.getCurves();
console.log(curves); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]

crypto.getDiffieHellman(groupName)‎

أضيف في الإصدار: v0.7.5.

ينشئ هذا التابع كائن تبادل المفتاح DiffieHellman المعرَّف مسبقًا. المجموعات المدعومة هي: 'modp1'، و 'modp2'، و 'modp5' (المعرفة في المعيار RFC 2412، ولكن انظر أيضًا قسم «دعم الخوارزميات الضعيفة والخطرة»)، و 'modp14'، و 'modp15'، و 'modp16'، و 'modp17'، و 'modp18' (المعرف في المعيار RFC 3526). يحاكي الكائن المعاد واجهة الكائنات المنشأة عبر التابع crypto.createDiffieHellman()‎، ولكن لن يسمح بتعديل المفاتيح (مع التابع diffieHellman.setPublicKey()‎ مثلًا). ميزة استعمال هذا التابع هي أنه لا يتوجب على الأطراف توليد ولا تبادل معاملات مجموعة (group modulus) مسبقًا مما يوفر وقت المعالجة والاتصال.

const crypto = require('crypto');
const alice = crypto.getDiffieHellman('modp14');
const bob = crypto.getDiffieHellman('modp14');

alice.generateKeys();
bob.generateKeys();

const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

// متماثلين bobSecret والثابت aliceSecret يجب أن يكون الثابت
console.log(aliceSecret === bobSecret);

crypto.getFips()‎

أضيف في الإصدار: v10.0.0.

  • القيم المعادة: <boolean> القيمة true إذا، وفقط إذا، كان مزود التشفير المتوافق مع FIPS قيد الاستخدام.

crypto.getHashes()‎

أضيف في الإصدار: v0.9.3.

  • القيم المعادة: <string[]‎> مصفوفةٌ بأسماء الخوارزميات hash المدعومة، مثل 'RSA-SHA256'.
const hashes = crypto.getHashes();
console.log(hashes); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]

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

سجل التغييرات
الإصدار التغييرات
v8.0.0 أصبح المعامل digest مطلوبًا دومًا.
v6.0.0 أصبح استدعاء هذا التابع دون تمرير المعامل digest مهملًا الآن، وسيُطلَق تحذير بذلك.
v6.0.0 تغيَّر الترميز الافتراضي للمعامل password عندما يكون سلسلة نصية من binary إلى utf8.
v0.5.5 أضيف هذا التابع.

يوفر هذا التابع تنفيذًا غير متزامن للدالة PBKDF2 (اختصارٌ للعبارة Password-Based Key Derivation Function 2 أي دالة اشتقاق المفتاح الذي يعتمد على كلمة المرور). تُطبَّق الخوارزمية التي تحسب HMAC المحددة بالوسيط digest لاشتقاق مفتاح بالطول keylen المطلوب (بالبايت) من الوسائط password، و salt، و iterations. تُستدعَى الدالة callback المعطاة مع الوسيطين: err، و derivedKey. إن حدث خطأ أثناء اشتقاق المفتاح، فستُعيَّن قيمة الوسيط err؛ خلا ذلك، ستكون قيمة الوسيط err هي null. ستُمرَّر القيمة derivedKey المولَّدة بنجاح إلى دالة رد النداء ككائن من النوع Buffer. سيُرمَى خطأ إن كان أيٌّ من الوسائط المدخلة يحدد قيمًا أو أنواعًا غير صالحة. يجب أن يكون الوسيط iterations عددًا يأخذ أعلى قيمة ممكنة. كلما كان عدد التكرارات كبيرًا، كان المفتاح المشتق آمنًا أكثر ولكن ذلك سيستهلك مزيدًا من الوقت لإتمام العملية. أما الوسيط salt، فيجب أن يكون فريدًا قدر الإمكان. يوصى أيضًا أن يكون عشوائيًّا وبطول 16 بايت على الأقل. لمزيد من التفاصيل، اطلع على المرجع NIST SP 800-132.

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

يمكن استعمال الخاصية crypto.DEFAULT_ENCODING لتغيير كيفية تمرير derivedKey إلى دالة رد النداء. على أي حال، هذه الخاصية قد أصبحت مهملةً ويجب تجنب استعمالها.

const crypto = require('crypto');
crypto.DEFAULT_ENCODING = 'hex';
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey);  // '3745e48...aa39b34'
});

يمكن استعمال التابع crypto.getHashes()‎ لمعرفة أسماء الخوارزميات hash المدعومة. انتبه إلى أنَّ الواجهة البرمجية هذه تستعمل مجمع الخيوط الخاص بالمكتبة libuv التي يكون لها آثارًا مفاجئة وسلبية على الأداء لبعض التطبيقات. راجع القسم UV_THREADPOOL_SIZE=size في توثيق خيارات سطر الأوامر في Node.js لمزيد من التفاصيل.

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

سجل التغييرات
الإصدار التغييرات
v6.0.0 أصبح استدعاء هذا التابع دون تمرير المعامل digest مهملًا الآن، وسيُطلَق تحذير بذلك.
v6.0.0 تغير الترميز الافتراضي للمعامل password عندما يكون سلسلة نصية من binary إلى utf8.
v0.5.5 أضيف هذا التابع.

يوفر هذا التابع تنفيذًا متزامنًا للدالة PBKDF2 (اختصارٌ للعبارة Password-Based Key Derivation Function 2، أي دالة اشتقاق المفتاح الذي تعتمد على كلمة المرور). تُطبَّق الخوارزمية التي تحسب HMAC المحددة بالوسيط digest لاشتقاق مفتاحٍ بالطول keylen المطلوب (بالبايت) من الوسائط password، و salt، و iterations. إن حصل أي خطأ، فسيُرمَى الخطأ Error، أو سيعاد المفتاح المشتق ككائن من النوع Buffer. يجب أن يكون الوسيط iterations عددًا بأعلى قيمة ممكنة. كلما كان عدد التكرارات كبيرًا، كان المفتاح المشتق أكثر أمانًا، ولكن ذلك سيستهلك مزيدًا من الوقت لإتمام العملية. يجب أن يكون الوسيط salt فريدًا قدر الإمكان، ويوصى أيضًا أن يكون عشوائيًّا وبطول 16 بايت على الأقل. لمزيد من التفاصيل، اطلع على المرجع NIST SP 800-132.

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

يمكن استعمال الخاصية crypto.DEFAULT_ENCODING لتغيير كيفية إعادة المفتاح derivedKey. على أي حال، هذه الخاصية قد أصبحت مهملةً ويجب تجنب استعمالها.

const crypto = require('crypto');
crypto.DEFAULT_ENCODING = 'hex';
const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512');
console.log(key);  // '3745e48...aa39b34'

يمكن استعمال التابع crypto.getHashes()‎ لمعرفة أسماء الخوارزميات hash المدعومة.

crypto.privateDecrypt(privateKey, buffer)‎

أضيف في الإصدار: v0.11.14.

  • privateKey:‏ <Object>‏ | ‎ <string>
    • key:‏ ‎<string>‎ مفتاحٌ خاص مُرمَّز بالترميز PEM.
    • passphrase:‏ ‎<string>‎ عبارة مرور اختيارية للمفتاح key الخاص.
    • padding:‏ ‎<crypto.constants‎>‎ قيمة حشوة إضافية معرَّفة في الثوابت crypto.constants والتي يمكن أن تكون: crypto.constants.RSA_NO_PADDING، أو crypto.constants.RSA_PKCS1_PADDING، أو crypto.constants.RSA_PKCS1_OAEP_PADDING.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> كائن جديد من النوع Buffer يحوي المحتويات الوسيط buffer المعطى بعد فك تشفيرها.

يفك هذا التابع تشفير محتويات الوسيط buffer المعطى باستعمال المفتاح privateKey. يمكن أن يكون الوسيط privateKey كائنًا أو سلسلة نصية. إن كان سلسلة نصية، فسيُعامَل وكأنه المفتاح المعطى بدون عبارة مرور (passphrase) وسيستعمل القيمة RSA_PKCS1_OAEP_PADDING للطول الإضافي.

crypto.privateEncrypt(privateKey, buffer)‎

أضيف في الإصدار: v1.1.0.

  • privateKey:‏ <Object>‏ | ‎ <string>
  • key:‏‎<string> ‎ مفتاحٌ خاص مُرمَّز بالترميز PEM.
  • passphrase:‏ ‎<string>‎ عبارة مرور اختيارية للمفتاح key الخاص.
  • padding:‏ ‎<crypto.constants>‎ قيمة حشوة إضافية معرَّفة في الثوابت crypto.constants والتي يمكن أن تكون: crypto.constants.RSA_NO_PADDING، أو crypto.constants.RSA_PKCS1_PADDIN.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> كائن جديد من النوع Buffer يحوي المحتويات الوسيط buffer المعطى بعد تشفيرها.

يشفِّر هذا التابع محتويات الوسيط buffer المعطى باستعمال المفتاح privateKey. يمكن أن يكون الوسيط privateKey كائنًا أو سلسلةً نصيةً. إن كان سلسلة نصية، فسيُعامَل وكأنه المفتاح المعطى بدون عبارة مرور (passphrase) وستُستعمَل القيمة RSA_PKCS1_PADDING للحاشية.

crypto.publicDecrypt(key, buffer)‎

أضيف في الإصدار: v1.1.0.

  • key:‏ <Object>‏ | ‎ <string>
    • key:‏ ‎<string>‎ مفتاحٌ عام أو خاص مُرمَّز بالترميز PEM.
    • passphrase:‏ ‎<string>‎ عبارة مرور اختيارية للمفتاح key الخاص.
    • padding:‏ ‎<crypto.constants>‎ قيمة حشوة إضافية مُعرَّفَة في الثوابت crypto.constants والتي يمكن أن تكون: crypto.constants.RSA_NO_PADDING، أو crypto.constants.RSA_PKCS1_PADDING.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> كائن جديد من النوع Buffer يحوي المحتويات الوسيط buffer المعطى بعد فك تشفيرها.

يفك هذا التابع تشفير محتويات الوسيط buffer المعطى باستعمال المفتاح key. يمكن أن يكون الوسيط key كائنًا أو سلسلة نصية. إن كان سلسلة نصية، فسيُعامَل وكأنه المفتاح المعطى بدون عبارة مرور (passphrase) وسيُستعمَل القيمة RSA_PKCS1_PADDING للحاشية. لما كان بالإمكان اشتقاق المفاتيح RSA العامة من المفاتيح الخاصة، فيمكن بناءً على ذلك تمرير مفتاح خاص عوضًا عن مفتاح عام.

crypto.publicEncrypt(key, buffer)‎

أضيف في الإصدار: v0.11.14.

  • key:‏ <Object>‏ | ‎ <string>
    • key:‏ ‎<string>‎ مفتاحٌ عام أو خاص مُرمَّز بالترميز PEM.
    • passphrase:‏ ‎<string>‎ عبارة مرور اختيارية للمفتاح key الخاص.
    • padding:‏ ‎<crypto.constants>‎ قيمة حاشية إضافية مُعرَّفَة في الثوابت crypto.constants والتي يمكن أن تكون: crypto.constants.RSA_NO_PADDING، أو crypto.constants.RSA_PKCS1_PADDING، أو RSA_PKCS1_OAEP_PADDIN.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • القيم المعادة: <Buffer> كائن جديد من النوع Buffer يحوي المحتويات الوسيط buffer المعطى بعد تشفيرها.

يفك هذا التابع تشفير محتويات الوسيط buffer المعطى باستعمال المفتاح key. يمكن أن يكون الوسيط key كائنًا أو سلسلة نصية. إن كان سلسلة نصية، فسيُعامَل وكأنه المفتاح المعطى بدون عبارة مرور (passphrase) وستُستعمَل القيمة RSA_PKCS1_PADDING للحاشية. لما كان بالإمكان اشتقاق المفاتيح RSA العامة من المفاتيح الخاصة، فيمكن بناءً على ذلك تمرير مفتاح خاص عوضًا عن مفتاح عام.

crypto.randomBytes(size[, callback])‎

سجل التغييرات
الإصدار التغييرات
v9.0.0 يؤدي تمرير القيمة null إلى الوسيط callback إلى رمي الخطأ ERR_INVALID_CALLBACK.
v0.5.8 أضيف هذا التابع.

يولِّد هذا التابع بيانات ذات تشفير جيد وشبه عشوائية. يحدد الوسيط size عدد البايتات المراد توليدها. إن أعطيت الدالة callback، فستُولَّد البايتات بشكل غير متزامن وستستدعى الدالة callback مع الوسيطين: err، و buf. إن حصل أي خطأ، فسيكون الوسيط err كائنًا من النوع Error؛ خلا ذلك، ستكون قيمته null. أما الوسيط buf، فهو كائنٌ من النوع Buffer يحوي البايتات المولدة.

// توليد البايتات بشكل غير متزامن
const crypto = require('crypto');
crypto.randomBytes(256, (err, buf) => {
  if (err) throw err;
  console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
});

أما إن لم تُعطَ الدالة callback، فستُولَّد البايتات بشكل متزامن وتعاد في كائن من النوع Buffer. سيُرمَى خطأٌ إن حصل أي خطأ أثناء عملية توليد البايتات.

// توليد البايتات بشكل متزامن
const buf = crypto.randomBytes(256);
console.log(
  `${buf.length} bytes of random data: ${buf.toString('hex')}`);

انتبه إلى أنَّ التابع crypto.randomBytes()‎ لن يكمل عملية التوليد حتى تكون العشوائية (entropy) كافية. لا يجب أن يستغرق هذا أكثر من بضعة أجزاء من الميلي ثانية. الوقت الوحيد الذي قد تستغرق فيه الدالة أطول فترة يمكن أن تتخيلها لتوليد البايتات العشوائية هي بعد الإقلاع حقيقةً؛ أي في الفترة التي لا يزال فيها مقياس العشوائية في النظام بأكمله منخفضًا. انتبه إلى أنَّ الواجهة البرمجية هذه تستعمل مجمع الخيوط الخاص بالمكتبة libuv التي يكون لها آثارًا مفاجئة وسلبية على الأداء لبعض التطبيقات. راجع القسم UV_THREADPOOL_SIZE=size في توثيق «خيارات سطر الأوامر في Node.js» لمزيد من التفاصيل. ينفَّذ الإصدار غير المتزامن من التابع crypto.randomBytes()‎ في طلب مجمع خيط وحيد (single threadpool request). إن أردت تقليل التغيير في طول مهمة مجمع الخيط، فَاعْمَل على تجزئة الطلبات randomBytes الكبيرة عند تنفيذ ذلك بوصفه جزءًا من عملية إنجاز طلبٍ لعميل.

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

الإصدار التغييرات
v9.0.0 أصبح بالإمكان أن يكون الوسيط buffer كانئًا من النوع TypedArray أو DataView.
v7.10.0 أضيف هذا التابع.

يمثل هذا التابع الإصدار المتزامن من التابع crypto.randomFill()‎.

const buf = Buffer.alloc(10);
console.log(crypto.randomFillSync(buf).toString('hex'));

crypto.randomFillSync(buf, 5);
console.log(buf.toString('hex'));

// :كل ما سبق مماثل تمامًا لما يلي
crypto.randomFillSync(buf, 5, 5);
console.log(buf.toString('hex'));

يمكن الآن أن يكون الوسيط buffer كائنًا من النوع TypedArray أو DataView:

const a = new Uint32Array(10);
console.log(Buffer.from(crypto.randomFillSync(a).buffer,
                        a.byteOffset, a.byteLength).toString('hex'));

const b = new Float64Array(10);
console.log(Buffer.from(crypto.randomFillSync(b).buffer,
                        b.byteOffset, b.byteLength).toString('hex'));

const c = new DataView(new ArrayBuffer(10));
console.log(Buffer.from(crypto.randomFillSync(c).buffer,
                        c.byteOffset, c.byteLength).toString('hex'));

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

سجل التغييرات
الإصدار التغييرات
v9.0.0 أصبح بالإمكان أن يكون الوسيط buffer كانئًا من النوع TypedArray أو DataView.
v7.10.0 أضيف هذا التابع.
  • buffer:‏ <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>‎يجب أن يعطى هذا الوسيط.
  • offset:‏ ‎<number>‎ القيمة الافتراضية هي: 0
  • size:‏ <number> القيمة الافتراضية هي: buffer.length - offset.
  • callback:‏ ‎<Function>‎ دالة من الشكل function(err, buf) {}‎.

هذا التابع مماثل تمامًا للتابع crypto.randomBytes()‎ باستثناء أنه يتطلب أن يكون الوسيط الأول المُمرَّر إليها كائنًا من النوع Buffer الذي يراد ملؤه. أضف إلى ذلك أنه يتطلب أيضًا تمرير دالة رد نداء (callback). إن لم تعطَ الدالة callback، فسيُرمى خطأٌ.

const buf = Buffer.alloc(10);
crypto.randomFill(buf, (err, buf) => {
  if (err) throw err;
  console.log(buf.toString('hex'));
});

crypto.randomFill(buf, 5, (err, buf) => {
  if (err) throw err;
  console.log(buf.toString('hex'));
});

// :كل ما سبق مماثل تمامًا لما يلي
crypto.randomFill(buf, 5, 5, (err, buf) => {
  if (err) throw err;
  console.log(buf.toString('hex'));
});

يمكن الآن أن يكون الوسيط buffer كائنًا من النوع TypedArray أو DataView:

const a = new Uint32Array(10);
crypto.randomFill(a, (err, buf) => {
  if (err) throw err;
  console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
    .toString('hex'));
});

const b = new Float64Array(10);
crypto.randomFill(b, (err, buf) => {
  if (err) throw err;
  console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
    .toString('hex'));
});

const c = new DataView(new ArrayBuffer(10));
crypto.randomFill(c, (err, buf) => {
  if (err) throw err;
  console.log(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)
    .toString('hex'));
});

انتبه إلى أنَّ الواجهة البرمجية هذه تستعمل مجمع الخيوط الخاص بالمكتبة libuv التي يكون لها آثارًا مفاجئة وسلبية على الأداء لبعض التطبيقات. راجع القسم UV_THREADPOOL_SIZE=size في توثيق «خيارات سطر الأوامر في Node.js» لمزيد من التفاصيل. ينفَّذ الإصدار غير المتزامن من التابع crypto.randomFill()‎ في طلب مجمع خيط وحيد (single threadpool request). إن أردت تقليل التغيير في طول مهمة مجمع الخيط، فَاعْمَل على تجزئة الطلبات randomFill الكبيرة عند تنفيذ ذلك بوصفه جزءًا من عملية إنجاز طلبٍ لعميل.

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

سجل التغييرات
الإصدار التغييرات
v10.9.0 أضيفت أسماء الخيارات التالية: cost، و blockSize، و parallelization.
v10.5.0 أضيف هذا التابع.
  • password:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • salt:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • keylen:‏ ‎ <number>
  • options:‏ ‎ <Object>
    • cost:‏ ‎<number>‎‎ معامل يحدد المقدار المطلوب من الذاكرة أو المعالج. يجب أن يكون من مضاعفات العدد 2n، إذ n هو 1، أو 2، ...إلخ.
    • N:‏ ‎<number>‎‎ معامل يحدد المقدار المطلوب من الذاكرة أو المعالج. يجب أن يكون من مضاعفات العدد 2n، إذ n هو 1، أو 2، ...إلخ. القيمة الافتراضية هي: 16384.
    • blockSize:‏ <number>‎‎ معامل حجم الكتلة (block size). القيمة الافتراضية هي: 8.
    • parallelization:‏ ‎<number>‎‎ معامل التوازي (Parallelization parameter). القيمة الافتراضية هي: 1.
    • N:‏ ‎<number>‎ اسمٌ بديل للمعامل cost. يجب تحديد أحدهما فقط.
    • r:‏ ‎<number>‎‎ اسمٌ بديل للمعامل blockSize. يجب تحديد أحدهما فقط.
    • p:‏ ‎<number>‎ اسمٌ بديل للمعامل parallelization. يجب تحديد أحدهما فقط.
    • maxmem:‏ ‎<number>‎ الحد الأعلى للذاكرة. يجب أن تكون (تقريبًا) 128 * N * r > maxmem. القيمة الافتراضية هي: 32 * 1024 * 1024.
  • callback:‏ ‎ <Function>‎

يوفر هذا التابع تنفيذًا غير متزامن للدالة scrypt. الدالة scrypt هي دالة اشتقاق مفتاح يعتمد على كلمة سر صُمِّمَت خصيصًا لتكون ذات قدرة حسابية كبيرة واستهلاك ذكي للذاكرة لكي لا تحقق أية هجمات شرسة غايتها. يجب أن تكون قيمة الوسيط salt فريدةً قدر الإمكان. يوصى أيضًا أن تكون قيمة salt عشوائية ولا يقل طولها عن 10 بايت. ارجع إلى المستند NIST SP 800-132 لمزيد من التفاصيل. تُستدعَى الدالة callback مع الوسيطين err، و derivedKey. يكون الوسيط err كائنَ استثناء عند فشل اشتقاق المفتاح وإلا ستكون قيمته null. يُمرَّر الوسيط derivedKey إلى دالة رد النداء ككائن من النوع Buffer. يُرمَى استثناءٌ إن كانت قيمة أو نوع أحد الوسائط الممررة غير صالحة.

const crypto = require('crypto');
// استعمال القيم الافتراضية
crypto.scrypt('secret', 'salt', 64, (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
});
// N استعمال قيمة مخصصة للمعامل
crypto.scrypt('secret', 'salt', 64, { N: 1024 }, (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
});

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

سجل التغييرات
الإصدار التغييرات
v10.9.0 أضيفت أسماء الخيارات التالية: cost، و blockSize، و parallelization.
v10.5.0 أضيف هذا التابع.
  • password:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • salt:‏ <string>‏ | <Buffer>‏ | <TypedArray>‏ | ‎ <DataView>
  • keylen:‏ ‎ <number>
  • options:‏ ‎ <Object>
    • cost:‏ ‎‎ <number>‎‎معامل يحدد المقدار المطلوب من الذاكرة أو المعالج. يجب أن يكون من مضاعفات العدد 2n، إذ n هو 1، أو 2، ...إلخ.
    • N:‏ ‎<number>‎ معامل يحدد المقدار المطلوب من الذاكرة أو المعالج. يجب أن يكون من مضاعفات العدد 2n، إذ n هو 1، أو 2، ...إلخ. القيمة الافتراضية هي: 16384.
    • blockSize:‏ ‎ <number>‎‎معامل حجم الكتلة (block size). القيمة الافتراضية هي: 8.
    • parallelization:‏ ‎‎ <number>‎‎ معامل التوازي (Parallelization parameter). القيمة الافتراضية هي: 1.
    • N:‏ ‎‎ <number>‎‎اسمٌ بديل للمعامل cost. يجب تحديد أحدهما فقط.
    • r:‏ ‎‎ <number>‎‎اسمٌ بديل للمعامل blockSize. يجب تحديد أحدهما فقط.
    • p:‏ ‎‎ <number>‎اسمٌ بديل للمعامل parallelization. يجب تحديد أحدهما فقط.
    • maxmem:‏ ‎‎ <number>‎الحد الأعلى للذاكرة. يجب أن تكون (تقريبًا) 128 * N * r > maxmem. القيمة الافتراضية هي: 32 * 1024 * 1024.
  • callback:‏ ‎ <Function>
  • القيم المعادة: <Buffer>

يوفر هذا التابع تنفيذًا متزامنًا للدالة scrypt. الدالة scrypt هي دالة اشتقاق مفتاح يعتمد على كلمة سر صُمِّمَت خصيصًا لتكون ذات قدرة حسابية كبيرة واستهلاك ذكي وواسع للذاكرة لكي لا تحقق أية هجمات شرسة غايتها. يجب أن تكون قيمة الوسيط salt فريدةً قدر الإمكان. يُوصَى أيضًا أن تكون قيمة salt عشوائية ولا يقل طولها عن 10 بايت. ارجع إلى المستند NIST SP 800-132 لمزيد من التفاصيل. يرمى استثناءٌ إن كانت قيمة أو نوع أحد الوسائط الممررة غير صالح.

const crypto = require('crypto');
// استخدام القيم الافتراضية
const key1 = crypto.scryptSync('secret', 'salt', 64);
console.log(key1.toString('hex'));  // '3745e48...08d59ae'
// N استعمال قيمة مخصصة للمعامل
const key2 = crypto.scryptSync('secret', 'salt', 64, { N: 1024 });
console.log(key2.toString('hex'));  // '3745e48...aa39b34'

crypto.setEngine(engine[, flags])‎

أضيف في الإصدار: v0.11.11.

  • engine:‏ ‎ <string>
  • flags:‏ ‎ <crypto.constants>‎ القيمة الافتراضية هي: crypto.constants.ENGINE_METHOD_ALL.

تحمل هذه الدالة وتضبط الوسيط engine لبعض أو جميع دوال OpenSSL (المحددة عبر الوسيط flags). يمكن أن يكون الوسيط engine إما مُعرِّفًا (id) أو مسارًا لمكتبة المحرك المشتركة. الوسيط flags هو حقل بِتِّي (bit field)، وقيمته الافتراضية هي ENGINE_METHOD_ALL. يمكن أن يأخذ رايةً واحدةً أو مزيجًا من الرايات التالية (المعرَّفة في 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

الرايات التالية قد أهملت في الإصدار OpenSSL-1.1.0:

  • crypto.constants.ENGINE_METHOD_ECDH
  • crypto.constants.ENGINE_METHOD_ECDSA
  • crypto.constants.ENGINE_METHOD_STORE

crypto.setFips(bool)‎

أضيف في الإصدار: v10.0.0.

  • bool:‏ ‎<boolean>‎ إن أعطيت القيمة true فسيُفعَّل الوضع FIPS.

يفعِّل هذا التابع الوضع FIPS المتوافق مع مزوِّد التشفير (crypto provider) في الإصدار Node.js المبني مع تمكين FIPS. سيُرمى خطأٌ إن لم يكن الوضع FIPS متاحًا.

crypto.timingSafeEqual(a, b)‎

أضيف في الإصدار: v6.6.0.

يعتمد هذا التابع على إحدى خوارزميات الوقت الثابت (constant-time algorithm). تعيد القيمة true إن كان الوسيط a مساويًا للوسيط b دون تسريب معلومات التوقيت التي ستسمح للمهاجم باستنتاج قيمة ما. هذا التابع مناسب للموازنة بين القيم HMAC أو القيم السرية مثل الكعكات المتعلقة بالمصادقة أو العناوين url الخارقة (capability urls). يجب أن يكون كلا الوسيطين a و b من النوع Buffer، أو TypedArray، أو DataView، ويجب أيضًا أن يكون لهما الطول نفسه. لا يضمن استعمال التابع crypto.timingSafeEqual أن تكون الشيفرة المحيطة ذات توقيت آمن (timing-safe). يجب أخذ الحيطة والحذر للتأكد من أنَّ الشيفرة المحيطة لا تخلق نقاط ضعف من ناحية التوقيت.

ملاحظات

واجهات المجاري البرمجية الإرثية (Legacy Streams API) قبل الإصدار Node.js v0.10

أضيفت الوحدة Crypto إلى Node.js قبل ظهور مصطلح واجهة مجرى موحَّد برمجية (unified Stream API)، وحتى قبل وجود الكائنات Buffer التي تُستعمَل في التعامل مع البيانات الثنائية. بناءً على ذلك، امتلكت الأصناف crypto المُعرَّفة آنذاك توابع لم توجد في أصناف أخرى تنفذ واجهة المجاري البرمجية (مثل update()‎، أو final()‎، أو digest()‎). أضف إلى ذلك، أغلب التوابع قبلت وأعادت سلاسل نصية مرمَّزة بالترميز 'latin1' بشكل افتراضي بدلًا من الكائنات Buffer. هذا السلوك الافتراضي تغيَّر بعد الإصدار Node.js v0.8 إلى استعمال الكائنات Buffer افتراضيًّا.

تغييرات الصنف ECDH الحديثة

استعمال الصنف ECDH مع أزواج من المفاتيح المولَّدة بشكل غير ديناميكي قد أصبح بسيطًا. يمكن الآن استدعاء التابع ecdh.setPrivateKey() مع مفتاح خاص حُدِّد مسبقًا وسيُحسَب المفتاح العام المرتبط ثم يخزَّن في الكائن. هذا يسمح للشيفرة بتخزين وتوفير الجزء الخاص من زوج المفاتيح EC فقط. يتحقق التابع ecdh.setPrivateKey()‎ الآن أيضًا من كون المفتاح الخاص صالحًا للمنحني المحدد. أصبح التابع ecdh.setPublicKey()‎ الآن مهملًا، إذ أنَّ إدراجه ضمن واجهة برمجية لم يكن مفيدًا. يجب إمَّا أن يعيَّن المفتاح الخاص الذي خُزِّن مسبقًا لتوليد المفتاح العام المرتبط به تلقائيًّا، أو استدعاء التابع ecdh.generateKeys()‎. العقبة الرئيسية في استعمال التابع ecdh.setPublicKey()‎‎ هي أنه يمكن استعماله لوضع زوج المفاتيح ECDH في حالة غير ثابتة (inconsistent state).

دعم الخوارزميات الضعيفة والخطرة

لا زالت الوحدة crypto تدعم بعض الخوارزميات التي تُعدُّ خطرة وتحوي ثغرات والتي لا يُنصَح باستعمالها مطلقًا في الوقت الحالي. تسمح الواجهة البرمجية أيضًا باستعمال عمليات التشفير وحساب hash مع مفاتيح صغيرة الحجم تعدُّ ضعيفةً للغاية وغير آمنة. يجب على المستخدمين أن يأخذوا على عاتقهم مسؤولية اختيار خوارزمية تشفير وحجم مفتاح بما يتطابق مع متطلبات الأمان التي يحتاجونها. بناءً على التوصيات المشار إليها في المستند NIST SP 800-131A:

  • لم يعد يُقبَل باستعمال الخوارزمية MD5 و SHA1 في المواقع التي لا يجب أن يحصل فيها أي تضارب مثل التواقيع الرقمية.
  • يوصى بأن لا يقل حجم المفتاح المستعمل مع الخوارزميات RSA، و DSA، و DH عن 2048 بت، والذي للمنحني ECDSA و ECDH لا يقل أيضًا عن 244 بت في حال أريد استعماله بشكل آمن لعدة سنوات.
  • تملك مجموعات DH التي تخص modp1، و modp2، و modp5 حجم مفتاح أصغر من 2048 ولا يوصى باستعمالها.

ألقِ نظرة على المستند الذي أشرنا إليه آنفًا للاطلاع على المزيد من التوصيات والتفاصيل.

الوضع CCM

الوضع CCM هو أحد الخوارزميات AEAD المدعومة. يجب على التطبيقات التي تستعمل هذا الوضع أن تلتزم بقيود معينة عند استعمال واجهة التشفير البرمجية وهي:

  • يجب تحديد طول بطاقة المصادقة أثناء إنشاء عملية التشفير عبر ضبط الخيار authTagLength، ويجب أن يكون أحد القيم التالية: 4، أو 6، أو 8، أو 10، 12، أو 14، أو 16 بايت.
  • يجب أن يتراوح طول المتغير الأولي ‎‎(initialization vector) N بين 7 و 13 بايت؛ أي 7 ‎≤ N ≤ 13.
  • يجب أن يحدد طول النص المجرد (plaintext) إلى القيمة 2 ** (8 * (15 - N)) بايت.
  • عند فك التشفير، يجب ضبط بطاقة المصادقة عبر setAuthTag()‎ قبل تحديد بيانات موثوقة إضافية أو استدعاء update()‎. خلا ذلك، ستفشل عملية فك التشفير وسيرمي final()‎ خطأً يتطابق مع الفقرة 2.6 في المعيار RFC 3610.
  • قد يؤدي استعمال توابع الصنف stream، مثل التابع write(data)‎، أو التابع end(data)‎، أو pipe()‎، في الوضع CCM إلى فشلها، إذ لا يستطيع الوضع CCM معالجة أكثر من قطعة واحدة من البيانات لكل نسخة.
  • عند تمرير بيانات موثوقة إضافية (AAD، اختصارٌ للعبارة additional authenticated data)، يجب أن يُمرَّر طول الرسالة الفعلية بالبايت إلى setAAD()‎ عبر الخيار plaintextLength. هذا الامر ليس ضروريًّا إن لم تُستعمَل بيانات موثوقة إضافية.
  • بما أن الوضع CCM يعالج الرسالة بأكملها في الوقت نفسه، فلا يمكن استدعاء التابع update()‎ سوى مرةً واحدةً فقط.
  • رغم أنَّ استدعاء update()‎ كافٍ لتشفير أو فك تشفير الرسالة إلا أنه يجب استدعاء final()‎ لحساب أو التحقق من بطاقة المصادقة.
const crypto = require('crypto');

const key = 'keykeykeykeykeykeykeykey';
const nonce = crypto.randomBytes(12);

const aad = Buffer.from('0123456789', 'hex');

const cipher = crypto.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 = crypto.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) {
  console.error('Authentication failed!');
}

console.log(receivedPlaintext);

ثوابت الوحدة Crypto

يمكن تصدير الثوابت التالية باستدعاء crypto.constants التي يمكن تطبيقها واستعمالها في أماكن متعددة في الوحدات crypto، و tls، و https وعلى وجه الخصوص في OpenSSL.

خيارات OpenSSL

الثابت الوصف
SSL_OP_ALL يطبِّق حلول متعددة لخطأ ضمن OpenSSL. للمزيد من التفاصيل، ألقِ نظرة على هذا التوثيق.
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION يسمح بإعادة عملية التفاوض الإرثية غير الآمنة (legacy insecure renegotiation) بين OpenSSL والعملاء أو الخوادم غير المحمية.
SSL_OP_CIPHER_SERVER_PREFERENCE يحاول استعمال أولويات الخادم بدلًا من العميل عند تحديد عملية التشفير. للمزيد من التفاصيل، ألقِ نظرة على هذا التوثيق
SSL_OP_CISCO_ANYCONNECT يوجه OpenSSL لاستعمال الإصدار «speshul» من DTLS_BAD_VER من Cisco.
SSL_OP_COOKIE_EXCHANGE يوجه OpenSSL لتشغيل عملية تبادل الكعكات (cookie exchange).
SSL_OP_CRYPTOPRO_TLSEXT_BUG يوجه OpenSSL لإضافة العملية server-hello من إصدار قديم للمسودة cryptopro.
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS يوجه OpenSSL لتعطيل الحل البديل للثغرة SSL 3.0/TLS 1.0 الذي أضيف في الإصدار OpenSSL 0.9.6d.
SSL_OP_EPHEMERAL_RSA يوجه OpenSSL لاستعمال المفتاح tmp_rsa دومًا عند تنفيذ العملية RSA.
SSL_OP_LEGACY_SERVER_CONNECT يسمح باتصال مبدئي مع الخوادم التي لا تدعم RI.
SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
SSL_OP_MICROSOFT_SESS_ID_BUG
SSL_OP_MSIE_SSLV2_RSA_PADDING يوجه OpenSSL لتعطيل الحل البديل لثغرة بروتوكول الوسيط (man-in-the-middle protocol-version vulnerability) في تنفيذ الخادم SSL 2.0.
SSL_OP_NETSCAPE_CA_DN_BUG
SSL_OP_NETSCAPE_CHALLENGE_BUG
SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
SSL_OP_NO_COMPRESSION يوجه OpenSSL لتعطيل دعم ضغط SSL/TLS.
SSL_OP_NO_SSLv2
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 لتعطيل استعمال بطاقات ( tickets) 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_PKCS1_CHECK_1
SSL_OP_PKCS1_CHECK_2
SSL_OP_SINGLE_DH_USE يوجه OpenSSL لإنشاء مفتاح جديد دومًا عند استعمال المعاملات DH المؤقتة أو سريعة الزوال (temporary/ephemeral).
SSL_OP_SINGLE_ECDH_USE يوجه OpenSSL لإنشاء مفتاح جديد دومًا عند استعمال المعاملات ECDH المؤقتة أو سريعة الزوال (temporary/ephemeral).
SSL_OP_SSLEAY_080_CLIENT_DH_BUG
SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
SSL_OP_TLS_BLOCK_PADDING_BUG
SSL_OP_TLS_D5_BUG
SSL_OP_TLS_ROLLBACK_BUG يوجه OpenSSL لتعطيل اكتشاف هجوم استعادة الإصدار السابق (version rollback attack).

ثوابت محرك 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
ALPN_ENABLED
RSA_PKCS1_PADDING
RSA_SSLV23_PADDING
RSA_NO_PADDING
RSA_PKCS1_OAEP_PADDING
RSA_X931_PADDING
RSA_PKCS1_PSS_PADDING
RSA_PSS_SALTLEN_DIGEST يضبط الطول الإضافي (salt) الذي يخص RSA_PKCS1_PSS_PADDING إلى حجم قيمة hash عند التوقيع أو التحقق.
RSA_PSS_SALTLEN_MAX_SIGN يضبط الطول الإضافي (salt) الذي يخص RSA_PKCS1_PSS_PADDING إلى أكبر قيمة مسموحة عند التوقيع أو التحقق.
RSA_PSS_SALTLEN_AUTO تعمل على جعل الطول الإضافي الذي يخص RSA_PKCS1_PSS_PADDING يحدد تلقائيًّا عند التوقيع أو التحقق.
POINT_CONVERSION_COMPRESSED
POINT_CONVERSION_UNCOMPRESSED
POINT_CONVERSION_HYBRID

ثوابت الوحدة crypto في Node.js

الثابت الوصف
defaultCoreCipherList يحدد قائمة التشفير الافتراضية الضمنيَّة التي تستعملها Node.js.
defaultCipherList تحدد قائمة التشفيرالافتراضية الفعالة التي تستعملها عملية Node.js الحالية.

مصادر