Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
python-ecdsa — توقيع/تحقق ECDSA واتفاق مفاتيح ECDH بلغة بايثون نقية | Kitploit
أدوات/GitHubGitHub/tlsfuzzer/python-ecdsa
أدوات التشفير/فك التشفيرالتشفيرالأدوات والمكوناتالمصادقةالتعلم والتعليم
GitHubtlsfuzzer/python-ecdsa

python-ecdsa

توقيع/تحقق ECDSA واتفاق مفاتيح ECDH بلغة بايثون نقية

عرض المستودع
975342منذ 2 أشهرتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

ECDSA و ECDH بلغة Python الخالصة

GitHub CI Documentation Status Coverage Status condition coverage mutation score CodeQL Latest Version Code style: black

هذا تطبيق سهل الاستخدام لتشفير المنحنيات الإهليلجية (ECC) مع دعم لـ ECDSA (خوارزمية التوقيع الرقمي بالمنحنيات الإهليلجية)، وEdDSA (خوارزمية التوقيع الرقمي بمنحنيات إدواردز)، وECDH (تبادل مفاتيح ديفي-هيلمان بالمنحنيات الإهليلجية)، مطبق بالكامل في Python ومصدر بموجب رخصة MIT. باستخدام هذه المكتبة، يمكنك إنشاء أزواج مفاتيح (مفتاح توقيع ومفتاح تحقق) بسرعة، وتوقيع الرسائل، والتحقق من التوقيعات. يمكنك أيضًا الاتفاق على مفتاح سري مشترك استنادًا إلى المفاتيح العامة المتبادلة. المفاتيح والتوقيعات قصيرة جدًا، مما يجعل من السهل التعامل معها ودمجها في بروتوكولات أخرى.

ملاحظة: لا ينبغي استخدام هذه المكتبة في بيئات الإنتاج؛ راجع Security لمزيد من التفاصيل.

الميزات

توفر هذه المكتبة توليد المفاتيح والتوقيع والتحقق واشتقاق السر المشترك لخمس منحنيات NIST الشهيرة من فئة "Suite B" على حقل GF(p) (الحقل الأولي)، بأطوال مفاتيح 192 و224 و256 و384 و521 بت. "الأسماء المختصرة" لهذه المنحنيات، كما تعرفها أداة OpenSSL (openssl ecparam -list_curves)، هي: prime192v1، secp224r1، prime256v1، secp384r1، وsecp521r1. كما تتضمن منحنى 256-بت secp256k1 المستخدم في Bitcoin. يوجد أيضًا دعم للنسخ العادية (غير الملتوية) لمنحنيات Brainpool من 160 إلى 512 بت. "الأسماء المختصرة" لتلك المنحنيات هي: brainpoolP160r1، brainpoolP192r1، brainpoolP224r1، brainpoolP256r1، brainpoolP320r1، brainpoolP384r1، . كما تم تضمين بعض المنحنيات الصغيرة من معيار SEC (بشكل أساسي لتسريع اختبار المكتبة)، وهي: ، ، ، و. يُدعم أيضًا توليد المفاتيح والتوقيع والتحقق لمنحنيات Ed25519 وEd448. لا يتم تضمين منحنيات أخرى، لكن إضافة دعم لمزيد من المنحنيات على الحقول الأولية ليس بالأمر الصعب.

الاعتماديات

تعتمد هذه المكتبة على Python وحزمة 'six' فقط. وهي متوافقة مع Python 2.6 و2.7 و3.6+. كما أنها تدعم التنفيذ على تطبيقات بديلة مثل pypy وpypy3.

إذا تم تثبيت gmpy2 أو gmpy، فسيتم استخدامهما لإجراء عمليات حسابية أسرع. يمكن تثبيت أي منهما بعد تثبيت هذه المكتبة، وسيكتشف python-ecdsa وجودهما عند بدء التشغيل ويستخدمهما تلقائيًا. ويُفضّل استخدام gmpy2 على Python3 للحصول على الأداء الأمثل.

لتشغيل اختبارات التوافق مع OpenSSL، يجب أن تكون أداة 'openssl' في مسار PATH. تم اختبار هذا الإصدار بنجاح مع OpenSSL 0.9.8o و1.0.0a و1.0.2f و1.1.1d و3.0.1 (من بين إصدارات أخرى).

التثبيت

هذه المكتبة متاحة على PyPI، ويُنصح بتثبيتها باستخدام pip:``` pip install ecdsa

root@kitploit:~
في حال كانت هناك حاجة لأداء أعلى ولم يكن استخدام الكود الأصلي مشكلة، فمن الممكن تحديد التثبيت مع `gmpy2`:```
pip install ecdsa[gmpy2]

أو (خيار أبطأ وقديم):``` pip install ecdsa[gmpy]

root@kitploit:~
## السرعة

يوضح الجدول التالي المدة التي تستغرقها هذه المكتبة لتوليد أزواج المفاتيح
(`keygen`)، لتوقيع البيانات (`sign`)، للتحقق من تلك التوقيعات (`verify`)،
لاشتقاق سر مشترك (`ecdh`)،
وللتحقق من التوقيعات دون حساب مسبق خاص بالمفتاح (`no PC verify`).
جميع هذه القيم بالثواني.
للتسهيل، تُقدَّم أيضاً القيم العكسية لهذه القيم:
كم عدد المفاتيح التي يمكن توليدها في الثانية (`keygen/s`)، وكم عدد التوقيعات
التي يمكن إنشاؤها في الثانية (`sign/s`)، وكم عدد التوقيعات التي يمكن التحقق منها
في الثانية (`verify/s`)، وكم عدد الأسرار المشتركة التي يمكن اشتقاقها في الثانية
(`ecdh/s`)، وكم عدد التوقيعات دون حساب مسبق خاص
بالمفتاح التي يمكن التحقق منها في الثانية (`no PC verify/s`). حجم التوقيع
الخام (عادةً أصغر
طريقة يمكن بها ترميز التوقيع) مُقدَّم أيضاً في عمود `siglen`.
استخدم `tox -e speed` لتوليد هذا الجدول على جهازك الخاص.
على معالج Intel Core i7 4790K @ 4.0GHz أحصل على الأداء التالي:```
                  siglen    keygen   keygen/s      sign     sign/s    verify   verify/s  no PC verify  no PC verify/s
        NIST192p:     48   0.00032s   3134.06   0.00033s   2985.53   0.00063s   1598.36       0.00129s         774.43
        NIST224p:     56   0.00040s   2469.24   0.00042s   2367.88   0.00081s   1233.41       0.00170s         586.66
        NIST256p:     64   0.00051s   1952.73   0.00054s   1867.80   0.00098s   1021.86       0.00212s         471.27
        NIST384p:     96   0.00107s    935.92   0.00111s    904.23   0.00203s    491.77       0.00446s         224.00
        NIST521p:    132   0.00210s    475.52   0.00215s    464.16   0.00398s    251.28       0.00874s         114.39
       SECP256k1:     64   0.00052s   1921.54   0.00054s   1847.49   0.00105s    948.68       0.00210s         477.01
 BRAINPOOLP160r1:     40   0.00025s   4003.88   0.00026s   3845.12   0.00053s   1893.93       0.00105s         949.92
 BRAINPOOLP192r1:     48   0.00033s   3043.97   0.00034s   2975.98   0.00063s   1581.50       0.00135s         742.29
 BRAINPOOLP224r1:     56   0.00041s   2436.44   0.00043s   2315.51   0.00078s   1278.49       0.00180s         556.16
 BRAINPOOLP256r1:     64   0.00053s   1892.49   0.00054s   1846.24   0.00114s    875.64       0.00229s         437.25
 BRAINPOOLP320r1:     80   0.00073s   1361.26   0.00076s   1309.25   0.00143s    699.29       0.00322s         310.49
 BRAINPOOLP384r1:     96   0.00107s    931.29   0.00111s    901.80   0.00230s    434.19       0.00476s         210.20
 BRAINPOOLP512r1:    128   0.00207s    483.41   0.00212s    471.42   0.00425s    235.43       0.00912s         109.61
       SECP112r1:     28   0.00015s   6672.53   0.00016s   6440.34   0.00031s   3265.41       0.00056s        1774.20
       SECP112r2:     28   0.00015s   6697.11   0.00015s   6479.98   0.00028s   3524.72       0.00058s        1716.16
       SECP128r1:     32   0.00018s   5497.65   0.00019s   5272.89   0.00036s   2747.39       0.00072s        1396.16
       SECP160r1:     42   0.00025s   3949.32   0.00026s   3894.45   0.00046s   2153.85       0.00102s         985.07
         Ed25519:     64   0.00076s   1324.48   0.00042s   2405.01   0.00109s    918.05       0.00344s         290.50
           Ed448:    114   0.00176s    569.53   0.00115s    870.94   0.00282s    355.04       0.01024s          97.69

                       ecdh     ecdh/s
        NIST192p:   0.00104s    964.89
        NIST224p:   0.00134s    748.63
        NIST256p:   0.00170s    587.08
        NIST384p:   0.00352s    283.90
        NIST521p:   0.00717s    139.51
       SECP256k1:   0.00154s    648.40
 BRAINPOOLP160r1:   0.00082s   1220.70
 BRAINPOOLP192r1:   0.00105s    956.75
 BRAINPOOLP224r1:   0.00136s    734.52
 BRAINPOOLP256r1:   0.00178s    563.32
 BRAINPOOLP320r1:   0.00252s    397.23
 BRAINPOOLP384r1:   0.00376s    266.27
 BRAINPOOLP512r1:   0.00733s    136.35
       SECP112r1:   0.00046s   2180.40
       SECP112r2:   0.00045s   2229.14
       SECP128r1:   0.00054s   1868.15
       SECP160r1:   0.00080s   1243.98

لاختبار الأداء مع تحميل gmpy2، استخدم tox -e speedgmpy2. على نفس الجهاز، أحصل على الأداء التالي مع gmpy2:``` siglen keygen keygen/s sign sign/s verify verify/s no PC verify no PC verify/s NIST192p: 48 0.00017s 5933.40 0.00017s 5751.70 0.00032s 3125.28 0.00067s 1502.41 NIST224p: 56 0.00021s 4782.87 0.00022s 4610.05 0.00040s 2487.04 0.00089s 1126.90 NIST256p: 64 0.00023s 4263.98 0.00024s 4125.16 0.00045s 2200.88 0.00098s 1016.82 NIST384p: 96 0.00041s 2449.54 0.00042s 2399.96 0.00083s 1210.57 0.00172s 581.43 NIST521p: 132 0.00071s 1416.07 0.00072s 1389.81 0.00144s 692.93 0.00312s 320.40 SECP256k1: 64 0.00024s 4245.05 0.00024s 4122.09 0.00045s 2206.40 0.00094s 1068.32 BRAINPOOLP160r1: 40 0.00014s 6939.17 0.00015s 6681.55 0.00029s 3452.43 0.00057s 1769.81 BRAINPOOLP192r1: 48 0.00017s 5920.05 0.00017s 5774.36 0.00034s 2979.00 0.00069s 1453.19 BRAINPOOLP224r1: 56 0.00021s 4732.12 0.00022s 4622.65 0.00041s 2422.47 0.00087s 1149.87 BRAINPOOLP256r1: 64 0.00024s 4233.02 0.00024s 4115.20 0.00047s 2143.27 0.00098s 1015.60 BRAINPOOLP320r1: 80 0.00032s 3162.38 0.00032s 3077.62 0.00063s 1598.83 0.00136s 737.34 BRAINPOOLP384r1: 96 0.00041s 2436.88 0.00042s 2395.62 0.00083s 1202.68 0.00178s 562.85 BRAINPOOLP512r1: 128 0.00063s 1587.60 0.00064s 1558.83 0.00125s 799.96 0.00281s 355.83 SECP112r1: 28 0.00009s 11118.66 0.00009s 10775.48 0.00018s 5456.00 0.00033s 3020.83 SECP112r2: 28 0.00009s 11322.97 0.00009s 10857.71 0.00017s 5748.77 0.00032s 3094.28 SECP128r1: 32 0.00010s 10078.39 0.00010s 9665.27 0.00019s 5200.58 0.00036s 2760.88 SECP160r1: 42 0.00015s 6875.51 0.00015s 6647.35 0.00029s 3422.41 0.00057s 1768.35 Ed25519: 64 0.00030s 3322.56 0.00018s 5568.63 0.00046s 2165.35 0.00153s 654.02 Ed448: 114 0.00060s 1680.53 0.00039s 2567.40 0.00096s 1036.67 0.00350s 285.62

root@kitploit:~
                   ecdh     ecdh/s
    NIST192p:   0.00050s   1985.70
    NIST224p:   0.00066s   1524.16
    NIST256p:   0.00071s   1413.07
    NIST384p:   0.00127s    788.89
    NIST521p:   0.00230s    434.85
   SECP256k1:   0.00071s   1409.95

BRAINPOOLP160r1: 0.00042s 2374.65 BRAINPOOLP192r1: 0.00051s 1960.01 BRAINPOOLP224r1: 0.00066s 1518.37 BRAINPOOLP256r1: 0.00071s 1399.90 BRAINPOOLP320r1: 0.00100s 997.21 BRAINPOOLP384r1: 0.00129s 777.51 BRAINPOOLP512r1: 0.00210s 475.99 SECP112r1: 0.00022s 4457.70 SECP112r2: 0.00024s 4252.33 SECP128r1: 0.00028s 3589.31 SECP160r1: 0.00043s 2305.02

root@kitploit:~
(هناك أيضًا إصدار `gmpy`، قم بتشغيله باستخدام `tox -e speedgmpy`)

للمقارنة، فإن تنفيذًا محسّنًا للغاية (بما في ذلك التجميع الخاص
ببعض المنحنيات)، مثل ذلك الموجود في OpenSSL 1.1.1d، يوفر
أرقام الأداء التالية على نفس الجهاز.
قم بتشغيل `openssl speed ecdsa` و `openssl speed ecdh` لإعادة إنتاجها:```
                              sign    verify    sign/s verify/s
 192 bits ecdsa (nistp192)   0.0002s   0.0002s   4785.6   5380.7
 224 bits ecdsa (nistp224)   0.0000s   0.0001s  22475.6   9822.0
 256 bits ecdsa (nistp256)   0.0000s   0.0001s  45069.6  14166.6
 384 bits ecdsa (nistp384)   0.0008s   0.0006s   1265.6   1648.1
 521 bits ecdsa (nistp521)   0.0003s   0.0005s   3753.1   1819.5
 256 bits ecdsa (brainpoolP256r1)   0.0003s   0.0003s   2983.5   3333.2
 384 bits ecdsa (brainpoolP384r1)   0.0008s   0.0007s   1258.8   1528.1
 512 bits ecdsa (brainpoolP512r1)   0.0015s   0.0012s    675.1    860.1

                              sign    verify    sign/s verify/s
 253 bits EdDSA (Ed25519)   0.0000s   0.0001s  28217.9  10897.7
 456 bits EdDSA (Ed448)     0.0003s   0.0005s   3926.5   2147.7

                               op      op/s
 192 bits ecdh (nistp192)   0.0002s   4853.4
 224 bits ecdh (nistp224)   0.0001s  15252.1
 256 bits ecdh (nistp256)   0.0001s  18436.3
 384 bits ecdh (nistp384)   0.0008s   1292.7
 521 bits ecdh (nistp521)   0.0003s   2884.7
 256 bits ecdh (brainpoolP256r1)   0.0003s   3066.5
 384 bits ecdh (brainpoolP384r1)   0.0008s   1298.0
 512 bits ecdh (brainpoolP512r1)   0.0014s    694.8

يمكن تسلسل المفاتيح والتوقيعات بطرق مختلفة (انظر الاستخدام أدناه). بالنسبة لمفتاح NIST192p، تتطلب التمثيلات الأساسية الثلاثة سلاسل بالأطوال التالية (بالبايت):

root@kitploit:~
to_string:  signkey= 24, verifykey= 48, signature=48
compressed: signkey=n/a, verifykey= 25, signature=n/a
DER:        signkey=106, verifykey= 80, signature=55
PEM:        signkey=278, verifykey=162, (no support for PEM signatures)

التاريخ

في عام 2006، أعلن بيتر بيرسون عن تنفيذه الخالص بلغة بايثون لخوارزمية ECDSA في رسالة إلى sci.crypt، متاحة من موقع التحميل. في عام 2010، كتب براين وارنر غلافًا حول هذا الكود، لجعله أسهل وأكثر أمانًا في الاستخدام. في عام 2020، أدرج هوبيرت كاريو تنفيذًا لتشفير المنحنيات الإهليلجية يستخدم إحداثيات جاكوبي داخليًا، مما يحسّن الأداء حوالي 20 ضعفًا. أنت الآن تطّلع على ملف README لهذا الغلاف.

الاختبار

لتشغيل مجموعة الاختبارات الكاملة، نفّذ ما يلي:

root@kitploit:~
tox -e coverage

على معالج Intel Core i7 4790K بتردد 4.0GHz، تستغرق الاختبارات حوالي 18 ثانية للتنفيذ. تستخدم مجموعة الاختبارات hypothesis لذلك هناك بعض التباين المتأصل في زمن تنفيذ مجموعة الاختبارات.

يتحقق جزء من test_pyecdsa.py وtest_ecdh.py من التوافق مع OpenSSL، عبر تشغيل أداة سطر الأوامر "openssl"، تأكد من وجودها في PATH الخاص بك إذا كنت تريد اختبار التوافق معها (إذا كان OpenSSL مفقودًا، أو قديمًا جدًا، أو لا يدعم جميع المنحنيات المدعومة في الإصدارات المنبعثة، فسترى اختبارات تم تخطيها في تشغيل coverage أعلاه).

الأمان

لم يتم تصميم هذه المكتبة مع وضع الأمان في الاعتبار. إذا كنت تعالج بيانات تحتاج إلى الحماية، نقترح عليك استخدام غلاف عالي الجودة حول OpenSSL. pyca/cryptography هو أحد الأمثلة على هذا الغلاف. الاستخدام الأساسي لهذه المكتبة هو كمكتبة محمولة لاختبار التوافق وكأداة تعليمية.

هذه المكتبة لا تحمي من هجمات القنوات الجانبية.

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

يُرجى أيضًا ملاحظة أن أي مكتبة تشفير مكتوبة بلغة بايثون الخالصة ستكون عرضة لنفس هجمات القنوات الجانبية. وذلك لأن بايثون لا توفر بدائيات آمنة ضد القنوات الجانبية (باستثناء hmac.compare_digest())، مما يجعل البرمجة الآمنة ضد القنوات الجانبية مستحيلة.

تعتمد هذه المكتبة على مصدر قوي للأرقام العشوائية. لا تستخدمها على نظام لا يوفر فيه os.urandom() أرقامًا عشوائية آمنة تشفيريًا.

الاستخدام

تبدأ بإنشاء SigningKey. يمكنك استخدامه لتوقيع البيانات، بتمرير البيانات كسلسلة بايتات واستلام التوقيع (وهو أيضًا سلسلة بايتات). يمكنك أيضًا أن تطلب من SigningKey أن يمنحك VerifyingKey المقابل. يمكن استخدام VerifyingKey للتحقق من التوقيع، بتمرير كل من سلسلة البيانات وسلسلة بايتات التوقيع: إما أن يُرجع True أو يرفع BadSignatureError.```python from ecdsa import SigningKey sk = SigningKey.generate() # uses NIST192p vk = sk.verifying_key signature = sk.sign(b"message") assert vk.verify(signature, b"message")

root@kitploit:~
يرتبط كل `SigningKey`/`VerifyingKey` بمنحنى محدد، مثل
NIST192p (الافتراضي). المنحنيات الأطول أكثر أمانًا، لكنها تستغرق وقتًا أطول في
الاستخدام، وتنتج مفاتيح وتوقيعات أطول.```python
from ecdsa import SigningKey, NIST384p
sk = SigningKey.generate(curve=NIST384p)
vk = sk.verifying_key
signature = sk.sign(b"message")
assert vk.verify(signature, b"message")

يمكن تسلسل SigningKey إلى عدة صيغ مختلفة: أقصرها هو استدعاء s=sk.to_string()، ثم إعادة إنشائه باستخدام SigningKey.from_string(s, curve) . لا تخزّن هذه الصيغة القصيرة المنحنى، لذا يجب التأكد من تمرير نفس المنحنى الذي استخدمته للمفتاح الأصلي إلى from_string(). يبلغ طول الصيغة القصيرة لمفتاح توقيع قائم على NIST192p 24 بايت فقط. إذا كان ترميز النقطة غير صالح أو لم يقع على المنحنى المحدد، فسيرفع from_string() استثناء MalformedPointError.```python from ecdsa import SigningKey, NIST384p sk = SigningKey.generate(curve=NIST384p) sk_string = sk.to_string() sk2 = SigningKey.from_string(sk_string, curve=NIST384p) print(sk_string.hex()) print(sk2.to_string().hex())

root@kitploit:~
ملاحظة: على الرغم من أن الطرق تُسمى `to_string()` إلا أن النوع الذي تُرجعه هو في الواقع `bytes`، وجزء "string" متبقٍ من Python 2.

`sk.to_pem()` و `sk.to_der()` سيقومان بتسلسل مفتاح التوقيع إلى نفس التنسيقات التي يستخدمها OpenSSL. يبدو ملف PEM مثل تنسيق ASCII-armored المألوف `"-----BEGIN EC PRIVATE KEY-----"` المشفّر بـ base64، وتنسيق DER هو شكل ثنائي أقصر لنفس البيانات.

`SigningKey.from_pem()/.from_der()` سيعكس هذا التسلسل. تتضمن هذه التنسيقات اسم المنحنى، لذلك لا تحتاج إلى تمرير معرّف منحنى إلى مفكك التسلسل. في حال كان الملف تالفًا، سيرفع `from_der()` و`from_pem()` استثناء `UnexpectedDER` أو` MalformedPointError`.```python
from ecdsa import SigningKey, NIST384p
sk = SigningKey.generate(curve=NIST384p)
sk_pem = sk.to_pem()
sk2 = SigningKey.from_pem(sk_pem)
# sk and sk2 are the same key

وبالمثل، يمكن تسلسل VerifyingKey بنفس الطريقة: vk.to_string()/VerifyingKey.from_string()، to_pem()/from_pem() و to_der()/from_der(). نفس وسيطة curve= مطلوبة من أجل VerifyingKey.from_string().```python from ecdsa import SigningKey, VerifyingKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk_string = vk.to_string() vk2 = VerifyingKey.from_string(vk_string, curve=NIST384p)

vk and vk2 are the same key

from ecdsa import SigningKey, VerifyingKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk_pem = vk.to_pem() vk2 = VerifyingKey.from_pem(vk_pem)

vk and vk2 are the same key

root@kitploit:~
هناك عدة طرق مختلفة لحساب التوقيع. في الأساس، يأخذ ECDSA رقمًا يمثل البيانات الموقَّعة، ويُرجع زوجًا من الأرقام يمثل التوقيع. تُستخدم وسيطة `hashfunc=` في `sk.sign()` و `vk.verify()` لتحويل أي سلسلة نصية إلى ملخّص بطول ثابت، والذي يتحول بعد ذلك إلى رقم يمكن لـ ECDSA توقيعه، ويجب أن يستخدم كل من التوقيع والتحقق نفس الأسلوب. القيمة الافتراضية هي `hashlib.sha1`، لكن إذا كنت تستخدم NIST256p أو منحنى أطول، يمكنك استخدام `hashlib.sha256` بدلاً من ذلك.

هناك أيضًا طرق متعددة لتمثيل التوقيع. تقدّمه طريقتا `sk.sign()` و `vk.verify()` الافتراضيتان كسلسلة قصيرة، للبساطة وتقليل الحمل. لاستخدام مخطط مختلف، استخدم وسيطتي `sk.sign(sigencode=)` و `vk.verify(sigdecode=)`. توجد دوال مساعدة في وحدة `ecdsa.util` قد تكون مفيدة هنا.

من الممكن أيضًا إنشاء `SigningKey` من "بذرة"، وهي حتمية التحديد. يمكن استخدام هذا في البروتوكولات التي تريد فيها اشتقاق مفاتيح توقيع متسقة من سر آخر، على سبيل المثال عندما تريد ثلاثة مفاتيح منفصلة وتريد تخزين سر رئيسي واحد فقط. يجب أن تبدأ ببذرة غير قابلة للتخمين وموزّعة بشكل منتظم تحتوي على حوالي `curve.baselen` بايت من العشوائية، ثم تستخدم إحدى الدوال المساعدة في `ecdsa.util` لتحويلها إلى عدد صحيح في النطاق الصحيح، ثم تمررها أخيرًا إلى `SigningKey.from_secret_exponent()`، كما يلي:```python
import os
from ecdsa import NIST384p, SigningKey
from ecdsa.util import randrange_from_seed__trytryagain

def make_key(seed):
  secexp = randrange_from_seed__trytryagain(seed, NIST384p.order)
  return SigningKey.from_secret_exponent(secexp, curve=NIST384p)

seed = os.urandom(NIST384p.baselen) # or other starting point
sk1a = make_key(seed)
sk1b = make_key(seed)
# note: sk1a and sk1b are the same key
assert sk1a.to_string() == sk1b.to_string()
sk2 = make_key(b"2-"+seed)  # different key
assert sk1a.to_string() != sk2.to_string()

في حال كان التطبيق سيتحقق من عدد كبير من التوقيعات المُنشأة بمفتاح واحد، فمن الممكن حساب بعض القيم الداخلية مسبقًا لجعل التحقق من التوقيعات أسرع بشكل ملحوظ. تحدث نقطة التعادل عند حوالي 100 توقيع تم التحقق منها.

لإجراء الحساب المسبق، يمكنك استدعاء طريقة precompute() على مثيل VerifyingKey:```python from ecdsa import SigningKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk.precompute() signature = sk.sign(b"message") assert vk.verify(signature, b"message")

root@kitploit:~
بمجرد استدعاء `precompute()`، ستصبح جميع عمليات التحقق من التوقيع بهذا المفتاح
أسرع في التنفيذ.

## التوافق مع OpenSSL

لإنتاج توقيعات يمكن التحقق منها بواسطة أدوات OpenSSL، أو للتحقق من
التوقيعات التي أنتجتها تلك الأدوات، استخدم:```python
# openssl ecparam -name prime256v1 -genkey -out sk.pem
# openssl ec -in sk.pem -pubout -out vk.pem
# echo "data for signing" > data
# openssl dgst -sha256 -sign sk.pem -out data.sig data
# openssl dgst -sha256 -verify vk.pem -signature data.sig data
# openssl dgst -sha256 -prverify sk.pem -signature data.sig data

import hashlib
from ecdsa import SigningKey, VerifyingKey
from ecdsa.util import sigencode_der, sigdecode_der

with open("vk.pem") as f:
   vk = VerifyingKey.from_pem(f.read())

with open("data", "rb") as f:
   data = f.read()

with open("data.sig", "rb") as f:
   signature = f.read()

assert vk.verify(signature, data, hashlib.sha256, sigdecode=sigdecode_der)

with open("sk.pem") as f:
   sk = SigningKey.from_pem(f.read(), hashlib.sha256)

new_signature = sk.sign_deterministic(data, sigencode=sigencode_der)

with open("data.sig2", "wb") as f:
   f.write(new_signature)

# openssl dgst -sha256 -verify vk.pem -signature data.sig2 data

ملاحظة: إذا كان التوافق مع OpenSSL 1.0.0 أو إصدارات أقدم ضروريًا، فيمكن استخدام sigencode_string و sigdecode_string من ecdsa.util لكتابة وقراءة التوقيعات على التوالي.

يمكن أيضًا كتابة المفاتيح بصيغة يمكن لـ openssl التعامل معها:```python from ecdsa import SigningKey, VerifyingKey

with open("sk.pem") as f: sk = SigningKey.from_pem(f.read()) with open("sk.pem", "wb") as f: f.write(sk.to_pem())

with open("vk.pem") as f: vk = VerifyingKey.from_pem(f.read()) with open("vk.pem", "wb") as f: f.write(vk.to_pem())

root@kitploit:~
## Entropy

يتطلب إنشاء مفتاح توقيع باستخدام `SigningKey.generate()` شكلاً من أشكال
الإنتروبيا (على عكس
`from_secret_exponent`/`from_string`/`from_der`/`from_pem`
وهي حتمية ولا تتطلب مصدر إنتروبيا). المصدر الافتراضي
هو `os.urandom()`، لكن يمكنك تمرير أي دالة أخرى تتصرف
مثل `os.urandom` كوسيط `entropy=` للقيام بشيء مختلف. قد
يكون هذا مفيدًا في اختبارات الوحدة، حيث تريد تحقيق نتائج قابلة للتكرار. تعد
أداة `ecdsa.util.PRNG` مفيدة هنا: فهي تأخذ بذرة وتنتج
تيارًا عشوائيًا زائفًا قويًا منها:```python
from ecdsa.util import PRNG
from ecdsa import SigningKey
rng1 = PRNG(b"seed")
sk1 = SigningKey.generate(entropy=rng1)
rng2 = PRNG(b"seed")
sk2 = SigningKey.generate(entropy=rng2)
# sk1 and sk2 are the same key

وبالمثل، يتطلب توليد توقيع ECDSA رقمًا عشوائيًا، وكل توقيع يجب أن يستخدم رقمًا مختلفًا (استخدام نفس الرقم مرتين سيكشف فورًا عن مفتاح التوقيع الخاص). تأخذ طريقة sk.sign() وسيطًا entropy= يعمل بنفس طريقة SigningKey.generate(entropy=).

التوقيعات الحتمية

إذا استدعيت SigningKey.sign_deterministic(data) بدلاً من .sign(data)، فسيُنشئ الكود توقيعًا حتميًا بدلاً من توقيع عشوائي. يستخدم هذا خوارزمية RFC6979 لتوليد قيمة k فريدة بأمان، مشتقة من المفتاح الخاص والرسالة التي يتم توقيعها. في كل مرة توقّع فيها نفس الرسالة بنفس المفتاح، ستحصل على نفس التوقيع (باستخدام نفس k).

قد يصبح هذا هو الإعداد الافتراضي في إصدار مستقبلي، لأنه ليس عرضة لأعطال مصدر الإنتروبيا.

أمثلة

أنشئ زوج مفاتيح NIST192p واحفظ كليهما فورًا على القرص:```python from ecdsa import SigningKey sk = SigningKey.generate() vk = sk.verifying_key with open("private.pem", "wb") as f: f.write(sk.to_pem()) with open("public.pem", "wb") as f: f.write(vk.to_pem())

root@kitploit:~
قم بتحميل مفتاح توقيع من القرص، واستخدمه لتوقيع رسالة (باستخدام SHA-1)، واكتب
التوقيع إلى القرص:```python
from ecdsa import SigningKey
with open("private.pem") as f:
    sk = SigningKey.from_pem(f.read())
with open("message", "rb") as f:
    message = f.read()
sig = sk.sign(message)
with open("signature", "wb") as f:
    f.write(sig)

حمّل مفتاح التحقق والرسالة والتوقيع من القرص، وتحقق من التوقيع (بافتراض تجزئة SHA-1):```python from ecdsa import VerifyingKey, BadSignatureError vk = VerifyingKey.from_pem(open("public.pem").read()) with open("message", "rb") as f: message = f.read() with open("signature", "rb") as f: sig = f.read() try: vk.verify(sig, message) print "good signature" except BadSignatureError: print "BAD SIGNATURE"

root@kitploit:~
أنشئ زوج مفاتيح NIST521p:```python
from ecdsa import SigningKey, NIST521p
sk = SigningKey.generate(curve=NIST521p)
vk = sk.verifying_key

إنشاء ثلاثة مفاتيح توقيع مستقلة من بذرة رئيسية:```python from ecdsa import NIST192p, SigningKey from ecdsa.util import randrange_from_seed__trytryagain

def make_key_from_seed(seed, curve=NIST192p): secexp = randrange_from_seed__trytryagain(seed, curve.order) return SigningKey.from_secret_exponent(secexp, curve)

sk1 = make_key_from_seed("1:%s" % seed) sk2 = make_key_from_seed("2:%s" % seed) sk3 = make_key_from_seed("3:%s" % seed)

root@kitploit:~
Load a verifying key from disk and print it using hex encoding in
uncompressed and compressed format (defined in X9.62 and SEC1 standards):

قم بتحميل مفتاح تحقق من القرص وطباعته باستخدام ترميز سداسي عشري بالتنسيق غير المضغوط والمضغوط (المعرّف في معايير X9.62 وSEC1):```python
from ecdsa import VerifyingKey

with open("public.pem") as f:
    vk = VerifyingKey.from_pem(f.read())

print("uncompressed: {0}".format(vk.to_string("uncompressed").hex()))
print("compressed: {0}".format(vk.to_string("compressed").hex()))

قم بتحميل مفتاح تحقق من سلسلة hex بالتنسيق المضغوط، ثم قم بإخراجه غير مضغوط:```python from ecdsa import VerifyingKey, NIST256p

comp_str = '022799c0d0ee09772fdd337d4f28dc155581951d07082fb19a38aa396b67e77759' vk = VerifyingKey.from_string(bytearray.fromhex(comp_str), curve=NIST256p) print(vk.to_string("uncompressed").hex())

root@kitploit:~
تبادل مفاتيح ECDH مع الطرف البعيد:```python
from ecdsa import ECDH, NIST256p

ecdh = ECDH(curve=NIST256p)
ecdh.generate_private_key()
local_public_key = ecdh.get_public_key()
#send `local_public_key` to remote party and receive `remote_public_key` from remote party
with open("remote_public_key.pem") as e:
    remote_public_key = e.read()
ecdh.load_received_public_key_pem(remote_public_key)
secret = ecdh.generate_sharedsecret_bytes()
تنزيل الأداة
brainpoolP512r1
secp112r1
secp112r2
secp128r1
secp160r1