تسجيل مفتاح
لا يمكنك استدعاء الواجهة البرمجية حتى يصبح أحد مفاتيحك نشطًا. تسجيل المفتاح هو ما يحوّل دعوة من أنيس إلى ذلك المفتاح.
الخطوات
- يرسل إليك موظفو أنيس دعوة — معرّف دعوة ورمز تسجيل صالحًا للاستخدام مرة واحدة.
- تُنشئ زوج مفاتيح P-256. احفظ النصف الخاص أولًا، في المكان الذي تحفظ فيه الأسرار.
- ترسل النصف العام وتتلقّى تحدّيًا.
- تُثبت أنك تحوز النصف الخاص بتوقيع رسالة مبنية من ذلك التحدّي.
- تعطي موظفي أنيس بصمة المفتاح (fingerprint) عبر القناة التي اتفقت عليها معهم — لا عبر الواجهة البرمجية. يسجّلونها ويؤكّدون المفتاح. ومن تلك اللحظة يصبح المفتاح صالحًا لتوقيع الاستدعاءات.
تُفوَّض استدعاءات تسجيل المفتاح الأربعة بالرمز — Authorization: Enrollment <token> — لا بتوقيع. ومع ذلك تبقى
ردودها موقّعة من أنيس، وينبغي أن يتحقق منها برنامجك كأي ردّ آخر.
احفظ المفتاح الخاص قبل أن ترسل المفتاح
تقبل الدعوة مفتاحًا واحدًا بالضبط. إذا أرسلت النصف العام ثم فقدت النصف الخاص، تُستهلك الدعوة على مفتاح لا يملكه أحد، ويجب على موظفي أنيس إعادة بدء تسجيل المفتاح.
باستخدام حزمة SDK لـ .NET
using var key = ECDsa.Create(ECCurve.NamedCurves.nistP256);
await File.WriteAllTextAsync("/secure/partner-key.pem", key.ExportPkcs8PrivateKeyPem(), ct); // first
using var enrollment = AnisEnrollmentClient.Create(authority, invitationId, enrollmentToken);
var submitted = await enrollment.SubmitKeyAsync(new EnrollmentKeyRequest
{
PublicJwk = AnisEnrollmentClient.PublicJwkOf(key),
NotBefore = DateTimeOffset.UtcNow,
ExpiresAt = DateTimeOffset.UtcNow.AddYears(1),
Cidrs = ["203.0.113.0/24"], // the networks you will call from — a proposal
}, ct);
var status = await enrollment.ProveAsync(submitted, key, ct);
if (status.ProofState != "accepted")
throw new InvalidOperationException("The proof failed — check the key and prove again."); // state: pendingApproval
Console.WriteLine($"key id {submitted.KeyId}, fingerprint {submitted.Thumbprint}");
submitted.KeyId هو معرّف المفتاح الذي سيحمله كل توقيع. وsubmitted.Thumbprint هي البصمة التي يسجّلها موظفو
أنيس.
بدون حزمة SDK
أرسل المفتاح — POST /v1/enrollments/{invitationId}/keys:
{
"publicJwk": { "kty": "EC", "crv": "P-256", "x": "<32 bytes, base64url>", "y": "<32 bytes, base64url>" },
"notBefore": "2026-09-24T08:00:00Z",
"expiresAt": "2027-09-24T08:00:00Z",
"cidrs": ["203.0.113.0/24"]
}
أرسل الحقول العامة فقط — يُرفض المفتاح إذا احتوى على d. لا يُستخدم من النافذة الزمنية إلا طولها — ويُحصر
افتراضيًا بين يوم واحد وسنتين — وتبدأ عندما يفعّل موظفو أنيس المفتاح. يحمل الردّ keyId وthumbprint
وchallenge وchallengeGeneration. احتفظ بالتحدّي إلى أن يُقبل الإثبات: فهو لا يُعاد إلا هنا.
ابنِ رسالة الإثبات. ليست التحدّي وحده — بل خمس قيم، يفصل بين كل قيمتين محرف \n واحد، ولا يأتي بعد القيمة
الأخيرة أي محرف:
anis.partners.v2.credential-proof
<keyId, lower-case with hyphens>
<challengeGeneration, as a decimal number>
<SHA-256 of the challenge's UTF-8 bytes, as lower-case hex>
<thumbprint, exactly as returned>
وقّع تلك البايتات باستخدام ECDSA P-256 وSHA-256. يجب أن يكون التوقيع بالصيغة ذات 64 بايت (r ثم s، كلٌّ
منهما 32 بايت)، لا بصيغة DER، ومرمّزًا بـ base64url دون حشو (padding).
أرسل الإثبات — POST /v1/enrollments/{invitationId}/proof:
{ "keyId": "<keyId>", "challengeGeneration": 1, "signature": "<86 base64url characters>" }
افحص قيمة proofState في الردّ. الإثبات الذي يفشل التحقق منه لا يُرفض: بل يقول الردّ "failed"، ويمكنك المحاولة
مرة أخرى. وحدها القيمة "accepted" تنقل المفتاح إلى المرحلة التالية. بعد خمسة إثباتات فاشلة، تُرفض الإثباتات اللاحقة
بالرمز rate_limited إلى أن يعيد موظفو أنيس بدء تسجيل المفتاح.
حالة المفتاح
اقرأ حالة تسجيل المفتاح باستخدام الرمز نفسه:
state |
المعنى |
|---|---|
pendingProof |
أُرسل؛ ولم تُثبت الحيازة بعد |
pendingApproval |
ثبتت الحيازة؛ بانتظار أن يسجّل موظفو أنيس البصمة ويؤكّدوا المفتاح |
active |
مؤكَّد — المفتاح يوقّع الاستدعاءات |
unavailable |
خرج المفتاح من تسجيل المفتاح (أُلغي أو انتهت صلاحيته أو استُبدل)؛ اطلب دعوة جديدة |
المهل الزمنية
- الدعوة صالحة لمدة يوم تقريبًا افتراضيًا. اقرأ الدعوة لمعرفة قيمة
expiresAtالدقيقة. - الإثبات يجب أن يلي إرسال المفتاح خلال 30 دقيقة تقريبًا افتراضيًا؛ والإثبات المتأخر يعود بالنتيجة
"failed". إذا كان مفتاحك محفوظًا في خزنة مفاتيح أو وحدة عتادية يتطلّب التوقيع فيها موافقة، فرتّب تلك الموافقة قبل أن ترسل المفتاح.
عندما يحدث خطأ
| ما حدث | ما تفعله |
|---|---|
رُفضت الدعوة بالرمز invitation_invalid |
الدعوة غير معروفة أو مستخدمة أو منتهية الصلاحية: اطلب من موظفي أنيس دعوة جديدة |
رُفض المفتاح بالرمز key_proof_invalid |
المفتاح العام ليس مفتاح P-256 صالحًا للاستخدام: افحص kty وcrv، وأن كلًّا من x وy بطول 32 بايت |
عاد الإثبات بالقيمة proofState: "failed" |
افحص رسالة الإثبات، وصيغة التوقيع ذات 64 بايت، وجيل التحدّي (challenge generation)، ثم أعد الإثبات — خلال 30 دقيقة تقريبًا من إرسال المفتاح |
رُفضت الإثباتات بالرمز rate_limited |
فشلت خمسة إثباتات: اطلب من موظفي أنيس إعادة بدء تسجيل المفتاح |
رُفض الإثبات بالرمز challenge_expired |
أعاد موظفو أنيس بدء تسجيل المفتاح: سجّل المفتاح مجددًا باستخدام الدعوة الجديدة |
| لم يصل ردّ على إرسال المفتاح | أرسل المفتاح نفسه مرة أخرى. إذا رُفض بالرمز key_duplicate، فهذا يعني أن الإرسال الأول قد استُلم — اطلب من موظفي أنيس إعادة بدء تسجيل المفتاح |
استبدال المفاتيح وإلغاؤها
- استبدال مفتاح. يبدأ موظفو أنيس الاستبدال ويرسلون دعوة جديدة. سجّل المفتاح الجديد تمامًا كما سبق. بمجرد تأكيده، يعمل المفتاحان كلاهما خلال فترة تداخل يحددها أنيس — انقل أداة التوقيع لديك إلى معرّف المفتاح الجديد خلالها.
- إلغاء مفتاح. منذ اللحظة التي يلغي فيها موظفو أنيس مفتاحًا، يُرفض كل استدعاء موقّع به بالرمز
invalid_credentials. إلغاء مفتاح لم تعد تستخدمه لا يؤثر في مفتاحك الحالي.