أمثلة اختبار التوقيع

التوقيع إمّا صحيح حتى آخر بايت وإمّا مرفوض، والرفض لا يخبرك أبدًا بأي بايت أخطأ. هذه الأمثلة تتيح لك أن تجده بنفسك: كل مثال استدعاء أو ردّ أو إثبات حيازة حقيقي، ومعه النصّ الموقَّع بالضبط والنتيجة المتوقعة بالضبط.

هل تستخدم حزمة SDK لـ ‎.NET؟

استخدم حزمة SDK بالإصدار 2.2.0. هذه الصفحة لعميل مكتوب يدويًا — أو كتبه مساعد ذكاء اصطناعي.

مفاتيح اختبار فقط

المفاتيح في هذه الملفات مفاتيح اختبار — ليست أبدًا مفاتيح حقيقية لأنيس أو لأي شريك — وpartners.anis.ly عنوان للتمثيل فقط. استخدمها للاختبار، ولا تسجّلها أبدًا.

ما الذي هنا

المجموعة ما تختبره عدد الأمثلة
الاستدعاءات نصّ التوقيع الذي تبنيه، بايتًا ببايت، لكل نوع من الاستدعاءات الموقّعة 9
الردود فحوصك للردود: أيّ الردود تقبلها وأيّها تتخلّص منه 50
تسجيل المفتاح رسالة إثبات الحيازة 2
إشعارات Webhook بصمة الإشعار الوارد ووجهته وتطبيقه ووقته وتوقيعه والغرض من مفتاحه راجع الفهرس المنشور

تستخدم أمثلة الإشعارات وقت التحقق والبايتات الأصلية الواردة فيها. قارن نتيجة القبول أو الرفض المتوقعة قبل استخدام أداة التحقق مع إشعارات حقيقية.

يسرد الملف /vectors/index.json كل مثال بعنوانه وملفه، وللردود: هل يجب قبوله أم رفضه. ويذكر الفهرس نفسه الأجزاء الموقّعة في كل نوع من الاستدعاءات.

اختبار توقيع الاستدعاءات

يحمل كل مثال استدعاء: الاستدعاء (request)، ووقتَي التوقيع (signature.created وsignature.expires)، ومفتاح الاختبار (key)، وما يجب أن يخرج (expected).

  1. ابنِ نصّ التوقيع من request.method وrequest.authority وrequest.path وrequest.canonicalQuery (الاستعلام دون علامة ?) وrequest.anisDate وrequest.nonce وrequest.idempotencyKey والمحتوى في request.bodyBase64، مع key.keyId معرّفًا للمفتاح.
  2. قارن Content-Digest لديك بـ expected.contentDigest، وSignature-Input بـ expected.signatureInput، ونصّ التوقيع بـ expected.signatureBaseUtf8 — بايتًا ببايت.
  3. وقّع نصّك بالمفتاح الخاص للاختبار (key.privateKeyPkcs8Base64) وتأكد أن key.publicJwk يتحقق منه. توقيع ECDSA يختلف في كل مرة، فقارن نصّ التوقيع لا بايتات التوقيع.

يعطي المثال RQ-03 اسم الخادم كما قد يكتبه المستدعي (request.authorityAsGiven) وكما يجب أن يُوقَّع (request.authority، بأحرف صغيرة). والمثال RQ-06 كشفٌ: بلا محتوى إطلاقًا، فبصمته بصمة صفر بايت.

اختبار التحقق من الردود

يحمل كل مثال ردّ: الردّ (response.status وresponse.headers وresponse.bodyBase64)، وSignature-Input الخاص بالاستدعاء الذي يجيب عنه (request.signatureInput وrequest.signature)، ومفاتيح أنيس المنشورة في تلك اللحظة (signingKeys)، والوقت الذي تعتمده ساعةً لك (verifyAt، بثواني Unix — استخدمه لا الساعة الحقيقية).

يجب أن يصل فاحصك إلى expected.outcome: ‏accept أو reject. وعند الرفض يذكر expected.reason السبب؛ قد تختلف أسماء الأخطاء لديك، فطابق النتيجة واستعن بالسبب لفهم أي اختلاف. وsignatureBaseForDebugging هو النصّ الذي وقّعته أنيس.

تأتي معظم الردود في عائلات: ردّ يجب قبوله (RS-001-…) ونسخ معدَّلة منه (RS-001-…-M01 فما بعد) يجب رفض كلٍّ منها — بايت واحد تغيّر في المحتوى، أو بصمة أُعيدت كتابتها، أو توقيع بصيغة DER، أو جزء موقَّع ناقص، أو وقت خارج النافذة. وأخرى تختبر المفاتيح المنشورة: الردّ الموقَّع بالمفتاح التالي أو بالمفتاح المُنهى ضمن نافذته يجب قبوله، والردّ الذي أُنشئ قبل notBefore لمفتاحه يجب رفضه، ووثيقة المفاتيح التي تحمل عنصرًا خاصًا يجب رفضها كلها.

يختبر RS-112 مفتاحًا نشطًا، ويختبر RS-113 مفتاحًا مُنهى مع created < notBefore: يجب رفض كليهما بالسبب key_not_yet_valid.

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

اختبار إثبات الحيازة

يعطي كل مثال تسجيل ما أرجعه إرسال المفتاح (keySubmissionResult) ومفتاح الاختبار (key).

  1. ابنِ رسالة الإثبات من keySubmissionResult وقارنها بـ expected.proofMessageUtf8 — وبصمة التحدّي بـ expected.challengeHashHex.
  2. وقّعها بمفتاح الاختبار؛ exampleSignature توقيع صحيح واحد، وkey.publicJwk يتحقق من الاثنين.
  3. expected.proofRequest هو المحتوى الذي ترسله.

بعد اجتياز الأمثلة

استدعِ فحص توقيعك بمفتاحك الحقيقي. إنه يُجري كل فحص تُجريه أنيس على الاستدعاء الموقَّع، ويخبرك بما رأته أنيس، ولا يغيّر شيئًا.

فحص ملف الردّ v2

تتطلب حزم SDK منذ الإصدار 2.0.1 tag="anis-response-v2". ترتيب الأجزاء هو "@status"، "content-digest"، "x-request-id"، ثم "signature-input";req و"signature";req إذا كان الاستدعاء موقَّعًا، ثم location وretry-after وidempotency-replayed وcache-control عند وجودها. قيمة "signature";req هي ترويسة توقيع الاستدعاء كما وصلت بالضبط.

اختبر status وnotBefore وretiredAt في keys[] وقائمة revoked[]: المفتاح المخترق يُرفض بالسبب key_compromised؛ والمفتاح المُنهى مع created > retiredAt بالسبب key_retired؛ وأي مفتاح — active أو next أو retired — مع created < notBefore بالسبب key_not_yet_valid. غياب الوسم أو اختلافه يُرفض بالسبب profile_unexpected، واختلاف قائمة الأجزاء بالسبب covered_components_mismatch. اختبر الحدود الزمنية نفسها أيضًا.

يبقى المفتاح المُنهى مدرجًا لمدة 90 يومًا بعد retiredAt. وتعلن أنيس عن الاختراق خلال 24 ساعة بالبريد الإلكتروني وفي revoked[]، حيث يبقى الإدخال لمدة 90 يومًا. اتبع قواعد التحقق؛ يجب أن تطابق نسخة الأمثلة ملف v2 قبل استخدامها لاعتماد عميلك.