EVP_PKEY_SIGN(3SSL)

الاسم
EVP_PKEY_sign_init, EVP_PKEY_sign_init_ex, EVP_PKEY_sign_init_ex2, EVP_PKEY_sign, EVP_PKEY_sign_message_init, EVP_PKEY_sign_message_update, EVP_PKEY_sign_message_final - التوقيع باستخدام خوارزمية مفتاح عام

موجز
 #include <openssl/evp.h>

 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
 int EVP_PKEY_sign_init_ex2(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *algo,
                            const OSSL_PARAM params[]);
 int EVP_PKEY_sign_message_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *algo,
                                const OSSL_PARAM params[]);
 int EVP_PKEY_sign_message_update(EVP_PKEY_CTX *ctx,
                                  unsigned char *in, size_t inlen);
 int EVP_PKEY_sign_message_final(EVP_PKEY_CTX *ctx, unsigned char *sig,
                                 size_t *siglen, size_t sigsize);
 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
                   unsigned char *sig, size_t *siglen,
                   const unsigned char *tbs, size_t tbslen);

الوصف
EVP_PKEY_sign_init() يُهيئ سياق خوارزمية مفتاح عام ctx للتوقيع باستخدام الخوارزمية المُعطاة عند إنشاء السياق باستخدام EVP_PKEY_CTX_new(3) أو متغيراتها. تُستخدم الخوارزمية لجلب طريقة EVP_SIGNATURE ضمنيًا، انظر "الجلب الضمني" في provider(7) لمزيد من المعلومات حول الجلب الضمني.

EVP_PKEY_sign_init_ex() هو نفسه EVP_PKEY_sign_init() لكنه يُعين بالإضافة إلى ذلك المُعاملات الممررة params على السياق قبل الإرجاع.

EVP_PKEY_sign_init_ex2() يُهيئ سياق خوارزمية مفتاح عام ctx لتوقيع ملخص رسالة محسوب مسبقًا باستخدام الخوارزمية المُعطاة بواسطة algo والمفتاح المُعطى عبر EVP_PKEY_CTX_new(3) أو EVP_PKEY_CTX_new_from_pkey(3). لا يمكن استخدام سياق ctx بدون مفتاح مُحمّل مسبقًا مع هذه الدالة. توفر هذه الدالة نفس الوظيفة تقريبًا مثل EVP_PKEY_sign_init_ex()، لكنها مخصصة بشكل فريد للاستخدام مع ملخص رسالة محسوب مسبقًا، وتسمح بتحديد الشروط الدقيقة لذلك الملخص مسبقًا، إذا جُلبت خوارزمية توقيع مركبة (مثل RSA-SHA256). بعد استدعاء هذه الدالة، لا يُدعم عادةً تعيين مُعاملات تُعدل تنفيذ الملخص أو الحشو.

EVP_PKEY_sign_message_init() يُهيئ سياق خوارزمية مفتاح عام ctx لتوقيع رسالة ذات حجم غير محدود باستخدام الخوارزمية المُعطاة بواسطة algo والمفتاح المُعطى عبر EVP_PKEY_CTX_new(3) أو EVP_PKEY_CTX_new_from_pkey(3). يُدعم تمرير الرسالة بطريقة لمرة واحدة باستخدام EVP_PKEY_sign()، وعبر الجمع بين EVP_PKEY_sign_message_update() و EVP_PKEY_sign_message_final(). تُمكّن هذه الدالة من استخدام خوارزميات يمكنها معالجة إدخال بطول عشوائي، مثل ED25519 و RSA-SHA256 وما شابه.

EVP_PKEY_sign_message_update() يُضيف inlen بايت من in إلى البيانات المُراد معالجتها للتوقيع. يُحدد مواصفات وتنفيذ خوارزمية التوقيع كيفية معالجة بايتات الإدخال وما إذا كان هناك حد للحجم الكلي للإدخال. انظر "ملاحظات" أدناه لشرح أعمق.

EVP_PKEY_sign_message_final() يُوقع البيانات المُعالجة ويضع البيانات في sig، وعدد بايتات التوقيع في *siglen، إذا لم يتجاوز عدد البايتات الحجم المُعطى بواسطة sigsize. يمكن أن يكون sig NULL، وفي هذه الحالة، يُحدث فقط *siglen بعدد بايتات التوقيع.

EVP_PKEY_sign() هي دالة لمرة واحدة يمكن استخدامها مع جميع دوال التهيئة أعلاه. عندما أُجريت التهيئة باستخدام EVP_PKEY_sign_init() أو EVP_PKEY_sign_init_ex() أو EVP_PKEY_sign_init_ex2()، تُوقع البيانات المُحددة بواسطة tbs و tbslen بعد الحشو المناسب. عندما أُجريت التهيئة باستخدام EVP_PKEY_sign_message_init()، تُهضم البيانات المُحددة بواسطة tbs و tbslen بواسطة خوارزمية ملخص الرسالة الضمنية، ويُوقع الناتج بعد الحشو المناسب. إذا كان sig NULL، يُكتب الحجم الأقصى للمخزن الناتج إلى المُعامل siglen. إذا لم يكن sig NULL، فيجب أن يحتوي المُعامل siglen قبل الاستدعاء على طول مخزن sig، وإذا كان الاستدعاء ناجحًا، يُكتب التوقيع إلى sig وتُكتب كمية البيانات إلى siglen.

ملاحظات

  عام
بعض تطبيقات التوقيع تُراكم بيانات الإدخال فقط ولا تُجري معالجة إضافية قبل توقيعها (تتوقع أن يكون الإدخال ملخصًا)، بينما تضغط أخرى البيانات، عادةً بإنتاج ملخص داخليًا، وتوقع الناتج. بعضها يدعم كلا وضعي التشغيل في نفس الوقت. يُتوقع من المستدعي معرفة كيف يجب أن تتصرف الخوارزمية المُختارة وتحت أي ظروف.

على سبيل المثال، يمكن توقع أن يتوقع تطبيق RSA فقط ملخص رسالة كإدخال، بينما يمكن توقع أن يعالج ED25519 الإدخال بتجزئة، أي إنتاج ملخص الرسالة داخليًا، وبينما يمكن توقع أن يتعامل RSA-SHA256 مع أي من وضعي التشغيل، اعتمادًا على ما إذا أُهيئت العملية باستخدام EVP_PKEY_sign_init_ex2() أو باستخدام EVP_PKEY_sign_message_init().

بالمثل، يتوقع تنفيذ RSA عادةً ضبط تفاصيل إضافية، مثل خوارزمية خلاصة الرسالة التي يُفترض معالجة الإدخال بها، بالإضافة إلى وضع الحشو (padding) (انظر EVP_PKEY_CTX_set_signature_md(3) و EVP_PKEY_CTX_set_rsa_padding(3) وغيرها من الوظائف المماثلة)، بينما يحتوي تنفيذ RSA-SHA256 عادةً على هذه التفاصيل محددة مسبقاً وغير قابلة للتغيير.

لا يمكن استخدام الدوال الموصوفة هنا لدمج خوارزميات منفصلة. على وجه الخصوص، لا يمكن استخدام EVP_PKEY_CTX_set_signature_md(3) ولا مُعامل OSSL_PARAM "digest" (OSSL_SIGNATURE_PARAM_DIGEST) لدمج خوارزمية توقيع مع خوارزمية تجزئة لمعالجة الإدخال. بعبارة أخرى، ليس من الممكن تحديد ctx مُحمّل مسبقًا بمفتاح RSA، أو algo جلب "RSA" ومحاولة تحديد SHA256 بشكل منفصل للحصول على وظيفة RSA-SHA256. إذا كان دمج الخوارزميات بهذه الطريقة مرغوبًا، يُرجى استخدام EVP_DigestSignInit(3) والدوال المرتبطة.

  أداء توقيعات متعددة
عند التهيئة باستخدام EVP_PKEY_sign_init_ex() أو EVP_PKEY_sign_init_ex2()، يمكن استدعاء EVP_PKEY_sign() أكثر من مرة على نفس السياق لإجراء عدة عمليات لمرة واحدة باستخدام نفس المُعاملات.

عند التهيئة باستخدام EVP_PKEY_sign_message_init()، ليس من الممكن استدعاء EVP_PKEY_sign() عدة مرات.

القيم المُرجعة
جميع الدوال تُرجع 1 للنجاح و 0 أو قيمة سالبة للفشل.

على وجه الخصوص، قد تُرجع EVP_PKEY_sign_init() ومتغيراتها الأخرى -2 للإشارة إلى أن العملية غير مدعومة من قبل خوارزمية المفتاح العام.

أمثلة

  RSA مع حشوة PKCS#1 لـ SHA256
توقيع البيانات باستخدام RSA مع حشو PKCS#1 وملخص SHA256 كإدخال:

 #include <openssl/evp.h>
 #include <openssl/rsa.h>

 EVP_PKEY_CTX *ctx;
 /* md is a SHA-256 digest in this example. */
 unsigned char *md, *sig;
 size_t mdlen = 32, siglen;
 EVP_PKEY *signing_key;

 /*
  * NB: assumes signing_key and md are set up before the next
  * step. signing_key must be an RSA private key and md must
  * point to the SHA-256 digest to be signed.
  */
 ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
 if (ctx == NULL)
     /* Error occurred */
 if (EVP_PKEY_sign_init(ctx) <= 0)
     /* Error */
 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
     /* Error */
 if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
     /* Error */

 /* Determine buffer length */
 if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
     /* Error */

 sig = OPENSSL_malloc(siglen);

 if (sig == NULL)
     /* malloc failure */

 if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
     /* Error */

 /* Signature is siglen bytes written to buffer sig */

  RSA-SHA256 مع ملخص محسوب مسبقًا
وقع ملخصًا باستخدام RSA-SHA256 باستخدام دوال اللقطة الواحدة. يُلاحظ أن RSA-SHA256 يُفترض أن يكون تطبيقًا لـ "sha256WithRSAEncryption"، حيث يكون الحشو محددًا مسبقًا ليكون RSA_PKCS1_PADDING، ويُفترض أن الملخص المُدخل قد حُسب باستخدام SHA256.

 #include <openssl/evp.h>
 #include <openssl/rsa.h>

 EVP_PKEY_CTX *ctx;
 /* md is a SHA-256 digest in this example. */
 unsigned char *md, *sig;
 size_t mdlen = 32, siglen;
 EVP_PKEY *signing_key;

 /*
  * NB: assumes signing_key and md are set up before the next
  * step. signing_key must be an RSA private key and md must
  * point to the SHA-256 digest to be signed.
  */
 ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
 alg = EVP_SIGNATURE_fetch(NULL, "RSA-SHA256", NULL);

 if (ctx == NULL)
     /* Error occurred */
 if (EVP_PKEY_sign_init_ex2(ctx, alg, NULL) <= 0)
     /* Error */

 /* Determine buffer length */
 if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
     /* Error */

 sig = OPENSSL_malloc(siglen);

 if (sig == NULL)
     /* malloc failure */

 if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
     /* Error */

 /* Signature is siglen bytes written to buffer sig */

  RSA-SHA256، طلقة واحدة
وقع مستندًا باستخدام RSA-SHA256 باستخدام دوال اللقطة الواحدة. يُلاحظ أن RSA-SHA256 يُفترض أن يكون تطبيقًا لـ "sha256WithRSAEncryption"، حيث يكون الحشو محددًا مسبقًا ليكون RSA_PKCS1_PADDING.

 #include <openssl/evp.h>
 #include <openssl/rsa.h>

 EVP_PKEY_CTX *ctx;
 /* in is the input in this example. */
 unsigned char *in, *sig;
 /* inlen is the length of the input in this example. */
 size_t inlen, siglen;
 EVP_PKEY *signing_key;
 EVP_SIGNATURE *alg;

 /*
  * NB: assumes signing_key, in and inlen are set up before
  * the next step. signing_key must be an RSA private key,
  * in must point to data to be digested and signed, and
  * inlen must be the size of the data in bytes.
  */
 ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
 alg = EVP_SIGNATURE_fetch(NULL, "RSA-SHA256", NULL);

 if (ctx == NULL || alg == NULL)
     /* Error occurred */
 if (EVP_PKEY_sign_message_init(ctx, alg, NULL) <= 0)
     /* Error */

 /* Determine sig buffer length */
 if (EVP_PKEY_sign(ctx, NULL, &siglen, in, inlen) <= 0)
     /* Error */

 sig = OPENSSL_malloc(siglen);

 if (sig == NULL)
     /* malloc failure */

 if (EVP_PKEY_sign(ctx, sig, &siglen, in, inlen) <= 0)
     /* Error */

 /* Signature is siglen bytes written to buffer sig */

  RSA-SHA256، باستخدام التحديث والنهاية
هذا مماثل للمثال السابق، لكن مع السماح بوظيفية شبيهة بالدفق.

 #include <openssl/evp.h>
 #include <openssl/rsa.h>

 EVP_PKEY_CTX *ctx;
 /* in is the input in this example. */
 unsigned char *in, *sig;
 /* inlen is the length of the input in this example. */
 size_t inlen, siglen;
 EVP_PKEY *signing_key;
 EVP_SIGNATURE *alg;

 /*
  * NB: assumes signing_key, in and inlen are set up before
  * the next step. signing_key must be an RSA private key,
  * in must point to data to be digested and signed, and
  * inlen must be the size of the data in bytes.
  */
 ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
 alg = EVP_SIGNATURE_fetch(NULL, "RSA-SHA256", NULL);

 if (ctx == NULL || alg == NULL)
     /* Error occurred */
 if (EVP_PKEY_sign_message_init(ctx, alg, NULL) <= 0)
     /* Error */

 while (inlen > 0) {
     if (EVP_PKEY_sign_message_update(ctx, in, inlen)) <= 0)
         /* Error */
     if (inlen > 256) {
         inlen -= 256;
         in += 256;
     } else {
         inlen = 0;
     }
 }

 /* Determine sig buffer length */
 if (EVP_PKEY_sign_message_final(ctx, NULL, &siglen) <= 0)
     /* Error */

 sig = OPENSSL_malloc(siglen);

 if (sig == NULL)
     /* malloc failure */

 if (EVP_PKEY_sign_message_final(ctx, sig, &siglen) <= 0)
     /* Error */

 /* Signature is siglen bytes written to buffer sig */

انظر أيضًا
EVP_PKEY_CTX_new(3), EVP_PKEY_CTX_ctrl(3), EVP_PKEY_encrypt(3), EVP_PKEY_decrypt(3), EVP_PKEY_verify(3), EVP_PKEY_verify_recover(3), EVP_PKEY_derive(3)

التاريخ
أُضيفت الدالتان EVP_PKEY_sign_init() و EVP_PKEY_sign() في OpenSSL 1.0.0.

الدالة EVP_PKEY_sign_init_ex() أُضيفت في OpenSSL 3.0.

أُضيفت الدوال EVP_PKEY_sign_init_ex2() و EVP_PKEY_sign_message_init() و EVP_PKEY_sign_message_update() و EVP_PKEY_sign_message_final() في OpenSSL 3.4.

حقوق النسخ
حقوق النشر 2006-2025 لمؤلفي مشروع OpenSSL. جميع الحقوق محفوظة.

مرخص بموجب رخصة Apache 2.0 (المشار إليها فيما يلي بـ ”الرخصة“). لا يجوز لك استخدام هذا الملف إلا وفقًا لشروط الرخصة. يمكنك الحصول على نسخة منها في الملف LICENSE الموجود في حزمة التوزيع المصدرية أو على الرابط <https://www.openssl.org/source/license.html>.

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.