Compare commits
2 commits
d59664198a
...
bb1ff03ac2
Author | SHA1 | Date | |
---|---|---|---|
bb1ff03ac2 | |||
296ff50075 |
1 changed files with 175 additions and 128 deletions
|
@ -13,14 +13,15 @@ add_toc = true
|
||||||
<small>الاصدار: 1.0.0</small>\
|
<small>الاصدار: 1.0.0</small>\
|
||||||
<small>الحالة: مسودة</small>
|
<small>الحالة: مسودة</small>
|
||||||
|
|
||||||
|
## نظرة عامة {#overview}
|
||||||
|
|
||||||
## نظرة عامة
|
|
||||||
بروتوكول OxideTalis هو بروتوكول تواصل بين طرفين بتشفير تام من طرف إلى طرف عبر
|
بروتوكول OxideTalis هو بروتوكول تواصل بين طرفين بتشفير تام من طرف إلى طرف عبر
|
||||||
مفتاح تشفير مشترك بينهم، يهدف البروتوكول إلى توفير سهولة التنقل من خادم إلى أخر
|
مفتاح تشفير مشترك بينهم، يهدف البروتوكول إلى توفير سهولة التنقل من خادم إلى أخر
|
||||||
بشكل إفتراضي وتوفير طريقة للتواصل بين الافراد في خوادم مختلفة بشكل مباشر بدون
|
بشكل إفتراضي وتوفير طريقة للتواصل بين الافراد في خوادم مختلفة بشكل مباشر بدون
|
||||||
تواصل خادم المرسل وخادم المستقبل مع بعضهم البعض.
|
تواصل خادم المرسل وخادم المستقبل مع بعضهم البعض.
|
||||||
|
|
||||||
### الاهداف
|
### الاهداف {#goals}
|
||||||
|
|
||||||
- تواصل آمن بين طرفين مُشفر من ند إلى ند.
|
- تواصل آمن بين طرفين مُشفر من ند إلى ند.
|
||||||
- سهولة التنفيذ.
|
- سهولة التنفيذ.
|
||||||
- امكانية الإنتقال إلى خادم آخر.
|
- امكانية الإنتقال إلى خادم آخر.
|
||||||
|
@ -29,65 +30,84 @@ add_toc = true
|
||||||
- عدم الحاجة ﻷسم مستخدم وكلمة مرور لتخويل المسخدم للمراسلة، والاكتفاء بالعنوان
|
- عدم الحاجة ﻷسم مستخدم وكلمة مرور لتخويل المسخدم للمراسلة، والاكتفاء بالعنوان
|
||||||
العام الخاص به.
|
العام الخاص به.
|
||||||
|
|
||||||
### الاهداف الغير مرغوبة
|
### الاهداف الغير مرغوبة {#non-goals}
|
||||||
|
|
||||||
- التواصل الجماعي.
|
- التواصل الجماعي.
|
||||||
- المكالمات الصوتية أو الفيديو.
|
- المكالمات الصوتية أو الفيديو.
|
||||||
|
|
||||||
## العناوين العامة
|
## العناوين العامة {#public-addresses}
|
||||||
|
|
||||||
العنوان العام هو المفتاح العام الخاص بخوارزمية [Elliptic Curve Diffie-Hellman]
|
العنوان العام هو المفتاح العام الخاص بخوارزمية [Elliptic Curve Diffie-Hellman]
|
||||||
مضغوط وهو يتكون من 33 بايت (264 بت) يتم ترميزه بترميز [base58] على سبيل المثال
|
مضغوط وهو يتكون من 33 بايت (264 بت) يتم ترميزه بترميز [base58] على سبيل المثال
|
||||||
العنوان التالي `becZJsZZqGR7qBG8t1Pm4uy62jDTzJsabxnkARhr2syo`.
|
العنوان التالي `becZJsZZqGR7qBG8t1Pm4uy62jDTzJsabxnkARhr2syo`.
|
||||||
|
|
||||||
يتم وضع العنوان العام في رأس (Header) الطلب (Request) بأسم `X-OTMP-PUBLIC` ويجب ان يكون نص [base58] صحيح مكون من 33 بايت (264 بت).
|
يتم وضع العنوان العام في رأس (Header) الطلب (Request) بأسم `X-OTMP-PUBLIC` ويجب
|
||||||
|
ان يكون نص [base58] صحيح مكون من 33 بايت (264 بت).
|
||||||
|
|
||||||
## أسم الخادم
|
## عنوان دليل الخوادم {#servers-dir-domain}
|
||||||
يكون أسم الخادم عنوان إلكتروني مثل `example.com` ولا يجب أن يكون الخادم نفسه، هو
|
|
||||||
أسم فقط يشير إلى الخادم، على سبيل المثال، أسم الخادم `example.com` ولكن الخادم
|
|
||||||
هو `otmp.example.com:443`، هكذا سوف يتم الإشارة لى مستخدمين هذا الخادم <snap
|
|
||||||
dir='ltr'><code>@becZJsZZqGR7qBG8t1Pm4uy62jDTzJsabxnkARhr2syo/example.com</code></snap>
|
|
||||||
ويمكن إختصاره بالواجهات الرسومية بأخذ أول ثلاث أحرف و أخر ثلاث أحرف ووضع `..`
|
|
||||||
بينهم، ليصبح بهذا الشكل <snap
|
|
||||||
dir='ltr'><code>@bec..syo/example.com</code></snap>.
|
|
||||||
|
|
||||||
### كيفية الإشارة
|
عنوان دليل الخوادم هو نطاق عادي على سبيل المثال `example.com` يحتوي على المسار التالي <span dir='ltr'><code>/.well-known/oxidetalis/servers</code></span> ومحتوى هذا المسار ملف json يوجد به خادم او اكثر يستخدمونها مستخدمين هذا الدليل.
|
||||||
يشير أسم الخادم إلى الخادم عبر المسار التالي <span
|
|
||||||
dir='ltr'><code>/.well-known/oxidetalis/server</code></span>
|
|
||||||
|
|
||||||
سوف يتم إرسال طلب GET إلى هذا المسار و يجب أن يُرجع هذا المسار نص بتنسيق
|
الخادم الذي في هذا الدليل يكون اسمه خادماً إذا كان يقبل التواصل الداخلي، إذا كان يقبل التواصل الخارجي فقط حتى بين مستخدمينه، يصبح اسمه مُرحل.
|
||||||
`application/json` يحتوي على المفتاح `otmp_server` ولذي يحتوي على مكان إستضافة
|
|
||||||
الخادم والمنفذ الذي يستمع إليه، سوف يتم إرسال الطلب ببروتوكول https و يجب أن
|
|
||||||
يدعم الخادم https و يجب ان تكون الشهادة موقعة من جهة موثوقة وليست موقعة
|
|
||||||
ذاتياً[^1]
|
|
||||||
|
|
||||||
### مفتاح `otmp_server`
|
يمكن أن يكون هذا الدليل تابع لمستضيف معين ويضع به خوادمه أو عناوين لنفس الخادم (مثل عنوانه في شبكة Tor) أو يكون تابع لفرد ويضع به الخوادم التي يستخدمها. يجب لكل خادم في الدليل أن يصدر شهادة SSL/TLS من جهة موثوقة
|
||||||
محتوى هذا المفتاح يجب أن يكون نص، يتكون هذا النص من جزئين يفصل بينهم نقطتان
|
لأن الإتصال سيكون HTTPS (يستثنى من هذا خدمات Tor).
|
||||||
رأسيتان، الجزء الأول هو مكان الإستضافة و الجزء الثاني هو المنفذ على سبيل المثال
|
|
||||||
`"example.com:443"` و `"otmp.example.com:7294"` و `"93.184.215.14:7294"` و <snap
|
|
||||||
dir='ltr'><code>"[2606:2800:021f:cb07:6820:80da:af6b:8b2c]:7294"</code></snap>.
|
|
||||||
|
|
||||||
### مثال
|
### مهمة هذا الدليل {#why-dir}
|
||||||
|
|
||||||
|
في الإتصال الخارجي يحتاج المُرسل معرفة خادم المُستقبل لإرسال الرسالة إليه، عبر هذا الدليل سيعرف المُرسل الخوادم التي يوجد بها المُستقبل.
|
||||||
|
|
||||||
|
### الإشارة إلى مستخدمين الدليل {#mention-dir-users}
|
||||||
|
|
||||||
|
للإشارة إلى المستخدمين في أي وسيلة نقل يكون بالطريقة التالية <snap dir='ltr'><code>@becZJsZZqGR7qBG8t1Pm4uy62jDTzJsabxnkARhr2syo/example.com</code></snap> علامة `@` متبوعة بعنوان المستخدم العام متبوعاً بخط مائل
|
||||||
|
وبعد ذلك عنوان الدليل. يمكن لمطوري عملاء OxideTalis إختصار إسم عنوان المستخدم بالشكل التالي عند الإشارة إليه <snap dir='ltr'><code>@bec..syo/example.com</code></snap> بأخذ ثلاث محرفات من البداية ومن النهاية و الفصل بينهم بنقطتين `..`.
|
||||||
|
|
||||||
|
### خوادم الدليل {#servers-dir}
|
||||||
|
|
||||||
|
يوجد نوعين من خوادم الدليل، النوع الأول الخوادم التي على شبكة الإنترنت العامة ولتي يتم جلب عنوانها من النطاق الخاص بها مثل `example.com`، سوف يتم التواصل مع هذه الخوادم بإتصال https و wss لذلك يجب أن يكون لديها شهادة SSL/TLS ويجب ان تكون
|
||||||
|
الشهادة موقعة من جهة موثوقة وليست موقعة ذاتياً[^1]، يتم الإشارة إلى هذا الخوادم بالنطاق الذي تستخدمه و المنفذ، على سبيل المثال `otmp.example.com:443` يتم الفصل بين النطاق الذي سوف يتم جلب العنوان منه و المنفذ بنقطتان رأسيتان.
|
||||||
|
|
||||||
|
النوع الثاني وهو خدمات شبكة Tor المخفية، سوف يتم الإتصال بها بـhttp و ws، يتم الإشارة إليها بوضع عنوانها في شبكة Tor فقط بدون المنفذ، على سبيل المثال <snap dir='ltr'><code>duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion</code></snap>
|
||||||
|
|
||||||
|
يتم وضع خوادم الدليل في المفتاح `otmp_servers` وهي مصفوفة نصية يوجد بها الخوادم
|
||||||
|
|
||||||
|
#### أمثلة {#dir-example}
|
||||||
|
في المثال التالي مُخرج الدليل `example.com` في المسار <span dir='ltr'><code>/.well-known/oxidetalis/servers</code></span> ويتضح به انه لايوجد إلا خادم واحد
|
||||||
<div dir="ltr">
|
<div dir="ltr">
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"otmp_server": "otmp.example.com:443"}
|
{ "otmp_servers": ["otmp.example.com:443"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
> يجب على الخوادم عدم تخزين اسماء خوادم المرسلين الخارجيين، ويتم تحديده في الطلب
|
في المثال التالي مُخرج الدليل `example.net` في المسار <span dir='ltr'><code>/.well-known/oxidetalis/servers</code></span> ويتضح به انه يوجد خادمين، واحد في شبكة الإنترنت العالمية و الأخر في Tor
|
||||||
> المرسل من قبلهم فقط، حيث يعتبر المفتاح العام هو المعرف المشترك بين جميع
|
<div dir="ltr">
|
||||||
> الخوادم. سوف يوفر هذا سهولة إنتقال الافراد من خادم إلى أخر مع بقاء تعرف
|
|
||||||
> الخوادم الاخرى عليهم.
|
|
||||||
|
|
||||||
## مفتاح التشفير المشترك
|
```json
|
||||||
يتم انشاء مفتاح التشفير المشترك عبر خوارزمية [Elliptic Curve Diffie-Hellman] حيث
|
{
|
||||||
سوف يقوم مرسل الرسالة بوضع العنوان العام الخاص بالمستقبِل ليتم انتاج المفتاح
|
"otmp_servers": [
|
||||||
المشترك، بعد إنتاج المفتاح المشترك يتم ادخاله إلى دالة [HKDF] **بدون ملح**
|
"otmp.example.net:7294",
|
||||||
بخوارزمية [Sha256] وبعد ذلك يتم عمل له توسعة (expand) بدون معلومات (info) بطول
|
"duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion"
|
||||||
32 بايت (256 بت).
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
> يجب على الخوادم عدم تخزين دلائل المرسلين، ويتم تحديدها في الطلب المرسل من
|
||||||
|
> قبلهم فقط، حيث أن المفتاح العام هو المعرف المشترك بين جميع الخوادم.
|
||||||
|
|
||||||
|
## مفتاح التشفير المشترك {#shared-encryption-key}
|
||||||
|
|
||||||
|
يتم انشاء مفتاح التشفير المشترك عبر خوارزمية [Elliptic Curve Diffie-Hellman]
|
||||||
|
secp256k1 حيث يقوم مرسل الرسالة بوضع العنوان العام الخاص بالمستقبِل لإنتاج
|
||||||
|
المفتاح المشترك، بعد إنتاج المفتاح المشترك يتم ادخاله إلى دالة [HKDF] **بدون
|
||||||
|
ملح** بخوارزمية [Sha256] وبعد ذلك يتم عمل له توسعة (expand) بدون معلومات (info)
|
||||||
|
بطول 32 بايت (256 بت).
|
||||||
|
|
||||||
|
### التشفير {#encryption}
|
||||||
|
|
||||||
### التشفير
|
|
||||||
سوف يتم استخدام [مفتاح التشفير المشترك] مفتاحاً للتشفير في خوارزمية [AES-256
|
سوف يتم استخدام [مفتاح التشفير المشترك] مفتاحاً للتشفير في خوارزمية [AES-256
|
||||||
CBC]، بعد تشفير الرسالة يتم وضع قيمة التهيئة (iv) في أخر الرسالة، ليكون اخر 16
|
CBC]، بعد تشفير الرسالة يتم وضع قيمة التهيئة (iv) في أخر الرسالة، ليكون اخر 16
|
||||||
بايت (128 بت) هي قيمة التهيئة (iv) التي سوف يستخدمها المستقبِل لفك تشفير
|
بايت (128 بت) هي قيمة التهيئة (iv) التي سوف يستخدمها المستقبِل لفك تشفير
|
||||||
|
@ -96,7 +116,8 @@ CBC]، بعد تشفير الرسالة يتم وضع قيمة التهيئة (i
|
||||||
مثال لمفتاح تشفير مشترك بترميز [base58] <span
|
مثال لمفتاح تشفير مشترك بترميز [base58] <span
|
||||||
dir="ltr"><code>LKGKeuV3SRu1n3fez4SdboM3FT48vbBxHai9MbuWxb3</code></span>
|
dir="ltr"><code>LKGKeuV3SRu1n3fez4SdboM3FT48vbBxHai9MbuWxb3</code></span>
|
||||||
|
|
||||||
## مفتاح الخادم العام
|
## مفتاح الخادم العام {#server-public-key}
|
||||||
|
|
||||||
مفتاح الخادم العام هو مثل العنواين العامة الخاصة بالمستخدمين، ولكنه خاص بالخادم،
|
مفتاح الخادم العام هو مثل العنواين العامة الخاصة بالمستخدمين، ولكنه خاص بالخادم،
|
||||||
حيث ان الخادم سوف يقوم بأنشاء مفتاح مشترك بينه وبين مرسل الطلب (Request) ليتأكد
|
حيث ان الخادم سوف يقوم بأنشاء مفتاح مشترك بينه وبين مرسل الطلب (Request) ليتأكد
|
||||||
من أن المرسل (صاحب العنوان العام) هو مالك هذا العنوان. يتم التأكد عبر مطابقة
|
من أن المرسل (صاحب العنوان العام) هو مالك هذا العنوان. يتم التأكد عبر مطابقة
|
||||||
|
@ -104,27 +125,28 @@ dir="ltr"><code>LKGKeuV3SRu1n3fez4SdboM3FT48vbBxHai9MbuWxb3</code></span>
|
||||||
|
|
||||||
يتم جلب مفتاح الخادم العام من المسار <span
|
يتم جلب مفتاح الخادم العام من المسار <span
|
||||||
dir='ltr'><code>/api/info</code></span> سوف يتم إرسال طلب GET إلى هذا المسار و
|
dir='ltr'><code>/api/info</code></span> سوف يتم إرسال طلب GET إلى هذا المسار و
|
||||||
يجب أن يُرجع هذا المسار نص بتنسيق `application/json` يحتوي على المفتاح
|
يجب أن يُرجع هذا المسار نص بتنسيق `application/json` يحتوي على المفتاح `public_key` ولذي قيمته نص المفتاح العام الخاص بالخادم بترميز [base58].
|
||||||
`public_key` ولذي قيمته نص المفتاح العام الخاص بالخادم بترميز [base58]، سوف يتم
|
|
||||||
إرسال الطلب ببروتوكول https و يجب أن يدعم الخادم https و يجب ان تكون الشهادة
|
|
||||||
موقعة من جهة موثوقة وليست موقعة ذاتياً[^1]
|
|
||||||
|
|
||||||
> تم توضيح المفتاح العام هنا ([العناوين العامة](#l-nwyn-l-m))
|
> تم توضيح المفتاح العام هنا ([العناوين العامة](#public-addresses))
|
||||||
|
|
||||||
> حاول ان لا تقوم بتغيير المفتاح العام الخاص بالخادم بشكل مستمر، لآن العملاء سوف
|
> حاول ان لا تقوم بتغيير المفتاح العام الخاص بالخادم بشكل مستمر، لآن العملاء سوف
|
||||||
> يقومون بتخزينه بالعادة.
|
> يقومون بتخزينه بالعادة.
|
||||||
|
|
||||||
## توقيع الطلب
|
## توقيع الطلب {#request-signature}
|
||||||
|
|
||||||
هو التوقيع الخاص بالطلب يتم وضعه في رأس الطلب (Header) بأسم `X-OTMP-SIGNATURE`
|
هو التوقيع الخاص بالطلب يتم وضعه في رأس الطلب (Header) بأسم `X-OTMP-SIGNATURE`
|
||||||
او في بيانات ال [Websocket] في المفتاح `signature` بترميز [Hex] ويتم أستخدامه
|
او في بيانات ال [Websocket] في المفتاح `signature` بترميز [Hex] ويتم أستخدامه
|
||||||
للتأكد من ان مرسل الطلب هو مالك المفتاح العام.
|
للتأكد من ان مرسل الطلب هو مالك المفتاح العام.
|
||||||
|
|
||||||
### إنشاء التوقيع
|
### إنشاء التوقيع {#create-signature}
|
||||||
|
|
||||||
التوقيع يحتاج إلى ثلاث اشياء ليتم إنشائه
|
التوقيع يحتاج إلى ثلاث اشياء ليتم إنشائه
|
||||||
|
|
||||||
- مفتاح التشفير المشترك.
|
- مفتاح التشفير المشترك.
|
||||||
- جسم الطلب (body) أو بيانات الحدث (data) أو طريقة الطلب+المسار، مثال (GET/ws/chat)
|
- جسم الطلب (body) أو بيانات الحدث (data) أو طريقة الطلب+المسار، مثال
|
||||||
- ثواني الوقت الحالي للمنطقة الزمنية UTC بتنسيق [Unix Time] (8 بايت أي 64 بت
|
(GET/ws/chat)
|
||||||
**big-endian**).
|
- ثواني الوقت الحالي للمنطقة الزمنية UTC+00:00 بتنسيق [Unix Time] (8 بايت أي 64
|
||||||
|
بت **big-endian**).
|
||||||
- 16 بايت عشوائي (128 بت).
|
- 16 بايت عشوائي (128 بت).
|
||||||
|
|
||||||
يتم إدخال جسم الطلب (body) او بيانات الحدث في الـ[Websocket] إلى دالة
|
يتم إدخال جسم الطلب (body) او بيانات الحدث في الـ[Websocket] إلى دالة
|
||||||
|
@ -134,10 +156,10 @@ dir='ltr'><code>/api/info</code></span> سوف يتم إرسال طلب GET إل
|
||||||
```
|
```
|
||||||
مفتاح التشفير المشترك+الوقت الحالي+16 بايت عشوائي
|
مفتاح التشفير المشترك+الوقت الحالي+16 بايت عشوائي
|
||||||
```
|
```
|
||||||
|
|
||||||
بعد ذلك يتم أخذ نتيجة دالة [HMAC-SHA256] و إضافة الوقت المستخدم في الأعلى و
|
بعد ذلك يتم أخذ نتيجة دالة [HMAC-SHA256] و إضافة الوقت المستخدم في الأعلى و
|
||||||
الـ16 بايت المستخدمة في الأعلى و جميعهم بترميز [Hex]، مثال
|
الـ16 بايت المستخدمة في الأعلى و جميعهم بترميز [Hex]، مثال
|
||||||
|
|
||||||
|
|
||||||
<div dir="ltr">
|
<div dir="ltr">
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -147,6 +169,7 @@ bad035084e11bfd266c7b7dfa473d6603be551b3aa215f869776b75bf42ef31900000000665e1a69
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
بعد تحويله إلى بايتات سوف يكون المجموع 56 بايت، وسوف يكون التقسيم كالتالي
|
بعد تحويله إلى بايتات سوف يكون المجموع 56 بايت، وسوف يكون التقسيم كالتالي
|
||||||
|
|
||||||
- مخرج دالة [HMAC-SHA256]: من بايت 0 إلى بايت31. (التوقيع الذي سوف يتحقق منه
|
- مخرج دالة [HMAC-SHA256]: من بايت 0 إلى بايت31. (التوقيع الذي سوف يتحقق منه
|
||||||
الخادم)
|
الخادم)
|
||||||
- الوقت: من بايت 32 إلى بايت 39. (الذي سوف يتم إضافته بعد [مفتاح التشفير
|
- الوقت: من بايت 32 إلى بايت 39. (الذي سوف يتم إضافته بعد [مفتاح التشفير
|
||||||
|
@ -158,17 +181,18 @@ bad035084e11bfd266c7b7dfa473d6603be551b3aa215f869776b75bf42ef31900000000665e1a69
|
||||||
ان ال 16 بايت العشوائي لن يتم إستخدامهم في توقيع أخر، بالتالي ضمان عدم إرسال
|
ان ال 16 بايت العشوائي لن يتم إستخدامهم في توقيع أخر، بالتالي ضمان عدم إرسال
|
||||||
الطلب مرة أخرى من المهاجمين (ضمان أن التوقيع صالح لمرة واحدة فقط).
|
الطلب مرة أخرى من المهاجمين (ضمان أن التوقيع صالح لمرة واحدة فقط).
|
||||||
|
|
||||||
### شكل البيانات داخل إتصال الـWebsocket
|
### شكل البيانات داخل إتصال الـWebsocket {#websocket-data}
|
||||||
بعد الإتصال بـ[Websocket] مع الخادم، يكون تنسيق البيانات التي يتم تبادلها
|
|
||||||
بين المرسل والخادم json ويجب عليها توفر المفاتيح التالية
|
|
||||||
|
|
||||||
- `event`: إسم الحدث، على سبيل المثال إرسال رسالة او تحديث حالة الكتابة (التنسيق PascalCase).
|
بعد الإتصال بـ[Websocket] مع الخادم، يكون تنسيق البيانات التي يتم تبادلها بين
|
||||||
|
المرسل والخادم json ويجب عليها توفر المفاتيح التالية
|
||||||
|
|
||||||
|
- `event`: إسم الحدث، على سبيل المثال إرسال رسالة او تحديث حالة الكتابة (التنسيق
|
||||||
|
PascalCase).
|
||||||
- `data`: البيانات الخاصة بالحدث.
|
- `data`: البيانات الخاصة بالحدث.
|
||||||
- `signature`: توقيع بيانات الحدث (data)، هذا التوقيع يكون بين المرسل وبين
|
- `signature`: توقيع بيانات الحدث (data)، هذا التوقيع يكون بين المرسل وبين
|
||||||
الخادم وليس المُستقبل.
|
الخادم وليس المُستقبل.
|
||||||
|
|
||||||
#### مثال لشكل البيانات في ال websocket
|
#### مثال لشكل البيانات في ال websocket {#websocket-data-example}
|
||||||
|
|
||||||
|
|
||||||
<div dir="ltr">
|
<div dir="ltr">
|
||||||
|
|
||||||
|
@ -185,19 +209,21 @@ bad035084e11bfd266c7b7dfa473d6603be551b3aa215f869776b75bf42ef31900000000665e1a69
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
> يمكن للخادم طلب أي شكل من البيانات، و يجب أن تكون المعلومات الحساسة مثل
|
> يمكن للخادم طلب أي شكل من البيانات، و يجب أن تكون المعلومات الحساسة مثل
|
||||||
> الرسالة او الملف أن مشفر بينك وبين المُستقبل فقط.
|
> الرسالة او الملف مُشفرة بين المُرسل و المُستقبل.
|
||||||
|
|
||||||
|
## طريقة التواصل {#communication}
|
||||||
|
|
||||||
## طريقة التواصل
|
|
||||||
هنا سوف يتم توضيح طريقة التواصل بين طرفين في خادم واحد (تواصل داخلي)، وبين طرفين
|
هنا سوف يتم توضيح طريقة التواصل بين طرفين في خادم واحد (تواصل داخلي)، وبين طرفين
|
||||||
في خوادم مختلفة (تواصل خارجي)
|
في خوادم مختلفة (تواصل خارجي)
|
||||||
|
|
||||||
### مفاهيم مهمة
|
### مفاهيم مهمة {#important-concepts}
|
||||||
|
|
||||||
- التواصل الداخلي: هو تواصل طرفين في الخادم نفسه.
|
- التواصل الداخلي: هو تواصل طرفين في الخادم نفسه.
|
||||||
- التواصل الخارجي: هو تواصل طرفين في خوادم مختلفة.
|
- التواصل الخارجي: هو تواصل طرفين في خوادم مختلفة.
|
||||||
- القائمة البيضاء: هي قائمة يمتلكها كل مستخدم في الخادم يوجد بها المستخدمين
|
- القائمة البيضاء: هي قائمة يمتلكها كل مستخدم في الخادم يوجد بها المستخدمين
|
||||||
المسموح لهم بمراسلته.
|
المسموح لهم بمراسلته.
|
||||||
- القائمة السوداء: هي قائمة يمتلكها كل مستخدم في الخادم يوجد بها المستخدمين
|
- القائمة السوداء: هي قائمة يمتلكها كل مستخدم في الخادم يوجد بها المستخدمين
|
||||||
الغير مسموح لهم بمراسلته.
|
الغير مسموح لهم بإرسال طلب دردشة إليه.
|
||||||
- قائمة الخادم السوداء: هي قائمة يقوم بوضعها مالك الخادم ليمنع خادمه من التواصل
|
- قائمة الخادم السوداء: هي قائمة يقوم بوضعها مالك الخادم ليمنع خادمه من التواصل
|
||||||
مع خوادم محددة او اشخاص محددين.
|
مع خوادم محددة او اشخاص محددين.
|
||||||
- جدول الإتصالات الخارجية: هو جدول يتم حفظ به الرسائل الخارجية التي وصلت إلى
|
- جدول الإتصالات الخارجية: هو جدول يتم حفظ به الرسائل الخارجية التي وصلت إلى
|
||||||
|
@ -207,85 +233,105 @@ bad035084e11bfd266c7b7dfa473d6603be551b3aa215f869776b75bf42ef31900000000665e1a69
|
||||||
مسح الطلب بعد وصول قبوله او رفضه. يتم الإستفادة من هذا الجدول لعدم إستقبال
|
مسح الطلب بعد وصول قبوله او رفضه. يتم الإستفادة من هذا الجدول لعدم إستقبال
|
||||||
إشعارات قبول او رفض مزيفة.
|
إشعارات قبول او رفض مزيفة.
|
||||||
|
|
||||||
> سوف يتم استبدال العنوان العام بأسم Alice و Bob لآن العناوين العامة طويلة
|
> سوف يتم استبدال العنوان العام بأسم **سارة** و **أحمد** لآن العناوين العامة
|
||||||
> نسبياً
|
> طويلة نسبياً
|
||||||
|
|
||||||
### التواصل الداخلي
|
### التواصل الداخلي {#internal-communication}
|
||||||
اولاً **يجب**[^2] عند فتحك لعميل التواصل أن تقوم بإنشاء تواصل [Websocket] بينك
|
|
||||||
|
اولاً **يجب**[^2] عند فتحك لعميل التواصل أن تقوم بإنشاء إتصال [Websocket] بينك
|
||||||
وبين الخادم الخاص بك، عبر هذا الإتصال سوف تستقبل الرسائل الجديدة من الخادم الخاص
|
وبين الخادم الخاص بك، عبر هذا الإتصال سوف تستقبل الرسائل الجديدة من الخادم الخاص
|
||||||
بك، وسوف تقوم بالتواصل من خلاله لإرسال الرسائل إلى افراد الخادم.
|
بك، وسوف تقوم بالتواصل من خلاله لإرسال الرسائل إلى افراد الخادم.
|
||||||
|
|
||||||
لدينا الآن المرسل alice والمستقبِل bob و كلاهم في الخادم نفسه، سوف يقوم alice
|
لدينا الآن المرسلة **سارة** والمستقبِل **أحمد** و كلاهم في الخادم نفسه، سوف تقوم
|
||||||
بإرسال رسالة [Websocket] يطلب من الخادم إرسال طلب الدردشة إلى bob وسوف يرد
|
**سارة** بإرسال حدث [Websocket] تطلب من الخادم إرسال طلب دردشة إلى **أحمد** سوف
|
||||||
الخادم بأحد الأخطأ التالية، او لا يقوم بالرد إذا لم يكن هناك خطأ.
|
يرد الخادم بأحد الأخطأ التالية، او لا يقوم بالرد إذا لم يكن هناك خطأ.
|
||||||
|
|
||||||
#### إذا لم يكن هناك مستخدم بأسم bob في الخادم
|
#### إذا لم يكن هناك مستخدم بأسم **أحمد** في الخادم {#no-user}
|
||||||
سوف يرجع الخادم خطأ ويخبر فيه العميل أنه ليس هناك مستخدم بهذا الأسم.
|
|
||||||
|
|
||||||
#### إذا لم يكن alice في قائمة bob البيضاء ولا السوداء
|
سوف يرجع الخادم خطأ ويخبر فيه **سارة** أنه ليس هناك مستخدم بهذا الأسم.
|
||||||
سوف يقوم الخادم اولاً بإضافة bob إلى قائمة alice البيضاء، وبعد ذلك إضافة الطلب
|
|
||||||
في جدول طلبات الدردشة **المُستقبلة** بالنسبة لـbob إذا كان غير متصل مع الخادم
|
#### إذا لم تكن **سارة** في قائمة **أحمد** البيضاء ولا السوداء {#not-in-white-or-black-list}
|
||||||
وسوف يضيفه إلى **المُرسلة** بالنسبة إلى alice، لا يرجع الخادم أي خطأ في هذه
|
|
||||||
|
سوف يقوم الخادم اولاً بإضافة **أحمد** إلى قائمة **سارة** البيضاء، وبعد ذلك إضافة
|
||||||
|
الطلب في جدول طلبات دردشة **أحمد** **المُستقبلة** إذا كان غير متصل مع الخادم
|
||||||
|
وسوف يضيفه إلى **المُرسلة** بالنسبة إلى **سارة**، لا يرجع الخادم أي خطأ في هذه
|
||||||
الحالة.
|
الحالة.
|
||||||
|
|
||||||
عندما يرد bob بالموافقة ام الرفض (عبر إتصال ال [Websocket])، سوف يُعلم الخادم
|
عندما يرد **أحمد** بالموافقة أو الرفض (عبر إتصال الـ[Websocket])، سوف يُعلم
|
||||||
alice بأن bob وافق او رفض التواصل معه (عبر إتصال الـ [Websocket] او إضافته إلى
|
الخادم **سارة** بأن **أحمد** وافق أو رفض التواصل معها (عبر إتصال الـ[Websocket]
|
||||||
جدول ليعلمه عند تواصله مع الخادم). إذا لم يوافق bob سوف يقوم الخادم بإضافة alice
|
أو إضافتها إلى جدول ليُعلمها عند تواصلها مع الخادم). إذا لم يوافق **أحمد** سوف
|
||||||
إلى قائمة bob السوداء، و إذا وافق سوف يتم إضافته إلى القائمة البيضاء.
|
يقوم الخادم بإضافة **سارة** إلى قائمة **أحمد** السوداء، و إذا وافق سوف يتم
|
||||||
|
إضافتها إلى القائمة البيضاء.
|
||||||
|
|
||||||
#### إذا كان alice في قائمة bob البيضاء
|
#### إذا كانت **سارة** في قائمة **أحمد** البيضاء {#in-white-list}
|
||||||
سوف يرجع الخادم خطأ، يعلم العميل أنه في قائمة bob البيضاء.
|
|
||||||
|
|
||||||
#### إذا كان alice في قائمة bob السوداء
|
سوف يرجع الخادم خطأ، يُعلم **سارة** أنها في قائمة **أحمد** البيضاء (يمكنها
|
||||||
سوف يرجع الخادم خطأ و يُعلم alice انه في قائمة bob السوداء ولا يمكنه الدردشة
|
التواصل معه)
|
||||||
معه.
|
|
||||||
|
#### إذا كانت **سارة** في قائمة **أحمد** السوداء {#in-black-list}
|
||||||
|
|
||||||
|
سوف يرجع الخادم خطأ و يُعلم **سارة** انها في قائمة **أحمد** السوداء ولا يمكنه
|
||||||
|
الدردشة معه.
|
||||||
|
|
||||||
> يتم تخزين رسائل الطرفين مُشفرة في قاعدة البيانات الخاصة بالخادم
|
> يتم تخزين رسائل الطرفين مُشفرة في قاعدة البيانات الخاصة بالخادم
|
||||||
|
|
||||||
### التواصل الخارجي
|
### التواصل الخارجي {#external-communication}
|
||||||
لدينا الآن المرسل alice من `example1.com` والمستقبِل bob من `example2.com` سوف
|
|
||||||
يقوم alice بإرسال طلب Get إلى `example2.com` يطلب فيه الدردشة مع bob، سوف يرد
|
|
||||||
الخادم بأحد الردود التالية
|
|
||||||
|
|
||||||
#### إذا لم ي3كن هناك مستخدم بأسم bob في الخادم
|
لدينا الآن المرسلة **سارة** من `example1.com` والمستقبِل **أحمد** من
|
||||||
سوف يرجع الخادم 404 و يُعلم alice بأنه ليس لديه مستخدم بهذا الأسم.
|
`example2.com` سوف تقوم **سارة** بإرسال طلب Get إلى `example2.com` تطلب فيه
|
||||||
|
الدردشة مع **أحمد**، **يجب** على **سارة** وضع الرأس `X-OTMP-SERVER` يحتوي على
|
||||||
|
أسم الخادم الخاص بها، سوف يستخدم **أحمد** هذا الخادم لإرسال طلب القبول أو الرفض
|
||||||
|
إليه إذا لم تكن **سارة** في قائمته السوداء ولا البيضاء، سوف يرد الخادم بأحد
|
||||||
|
الردود التالية
|
||||||
|
|
||||||
#### إذا لم يكن alice في قائمة bob البيضاء ولا السوداء
|
#### إذا لم يكن هناك مستخدم بأسم **أحمد** في الخادم {#no-user-external}
|
||||||
سوف يقوم خادم bob بإرسال طلب الدردشة إلى bob او يقوم بتخزين الطلب في جدول طلبات
|
|
||||||
الدردشة **المٌستقبلة**، ويرد عليه بـ200، بعد ذلك يقوم alice بطلب الخادم الخاص به
|
|
||||||
من إضافة bob إلى قائمته البيضاء ليستقبل منه الرسائل مستقبلاً بدون حاجة bob إرسال
|
|
||||||
طلب دردشة وإنتظار قبولها، سوف يقوم alice ايضاً بطلب الخادم من إضافة bob إلى جدول
|
|
||||||
طلبات الدردشة **المُرسلة** ويتم تضمين خادم bob الحالي الذي تم إرسال طلب الدردشة
|
|
||||||
إليه[^3]
|
|
||||||
|
|
||||||
إذا قبل/رفض bob الدردشة سوف يُعلم خادم bob خادم alice أن bob قام بقبول/رفض
|
سوف يرجع الخادم 404 و يُعلم **سارة** بأنه ليس لديه مستخدم بهذا الأسم.
|
||||||
الدردشة، سوف يضع الخادم التوقيع الخاص به في `X-OTMP-SIGNATURE` وسوف يتم جلب
|
|
||||||
المفتاح العام الخاص به من مسار الخادم[^4] (لقد قام alice بإضافة bob والخادم
|
|
||||||
الخاص به في جدول طلبات الدردشة **المُرسلة** لذالك خادم alice يعلم ماهو خادم
|
|
||||||
bob).
|
|
||||||
|
|
||||||
بعد ذلك إذا لم يكن لـalice إتصال [Websocket] سابق مع خادم bob، سوف يقوم بإرسال
|
#### إذا لم تكن **سارة** في قائمة **أحمد** البيضاء ولا السوداء {#not-in-white-or-black-list-external}
|
||||||
طلب دردشة ليتم ترقية الإتصال إلى [Websocket]، ونفس المسئلة مع bob إذا اراد
|
|
||||||
التواصل مع alice سوف يقوم بإرسال طلب دردشة ويتم ترقية الإتصال او إعلامه بوجود
|
|
||||||
إتصال [Websocket] مفتوح.
|
|
||||||
|
|
||||||
#### إذا كان alice في قائمة bob البيضاء
|
سوف يقوم خادم **أحمد** بإرسال طلب الدردشة إلى **أحمد** او يقوم بتخزين الطلب في
|
||||||
سوف يقوم الخادم بترقية الإتصال إلى [Websocket] او إذا كان alice متصل معه من قبل،
|
جدول طلبات الدردشة **المٌستقبلة**، ويرد عليها بـ202، بعد ذلك تقوم **سارة** بطلب
|
||||||
سوف يقوم بإرجاع 400 ويخبر alice بالتواصل معه عبر ال [Websocket].
|
الخادم الخاص بها من إضافة **أحمد** إلى قائمتها البيضاء لتستقبل منه الرسائل
|
||||||
|
مستقبلاً بدون حاجة **أحمد** إرسال طلب دردشة وإنتظار قبولها، سوف تقوم **سارة**
|
||||||
|
ايضاً بطلب الخادم من إضافة **أحمد** إلى جدول طلبات الدردشة **المُرسلة**[^3]
|
||||||
|
|
||||||
|
#### قبول أو رفض طلب الدردشة {#accept-or-reject-external}
|
||||||
|
|
||||||
|
بعدما يستقبل **أحمد** طلب دردشة **سارة** و خادمها و عندما يريد قبول أو رفض
|
||||||
|
الطلب سيقوم بالإرسال إلى النقطة <span
|
||||||
|
dir='ltr'><code>/api/chat_response</code></span> في خادم **سارة**، يجب على
|
||||||
|
**أحمد** وضع عنوانه العام في الرأس `X-OTMP-PUBLIC` وتوقيع الطلب في
|
||||||
|
`X-OTMP-SIGNATURE`، يجب أن يرسل طلب POST إلى النقطة مع جسم يوضح من مرسل الطلب
|
||||||
|
(**سارة** في حالتنا) و إذا اراد قبوله أم لا.
|
||||||
|
|
||||||
|
بعد ذلك إذا لم يكن لـ**سارة** إتصال [Websocket] سابق مع خادم **أحمد**، سوف تقوم
|
||||||
|
بإرسال طلب دردشة ليتم ترقية الإتصال إلى [Websocket]، ونفس المسئلة مع **أحمد**
|
||||||
|
إذا اراد التواصل مع **سارة** سوف يقوم بإرسال طلب دردشة ويتم ترقية الإتصال او
|
||||||
|
إعلامه بوجود إتصال [Websocket] مفتوح.
|
||||||
|
|
||||||
|
#### إذا كانت **سارة** في قائمة **أحمد** البيضاء {#in-white-list-external}
|
||||||
|
|
||||||
|
سوف يقوم الخادم بترقية الإتصال إلى [Websocket] او إذا كانت **سارة** متصلة معه من
|
||||||
|
قبل، سوف يقوم بإرجاع 400 ويخبر **سارة** بالتواصل معه عبر ال [Websocket].
|
||||||
|
|
||||||
|
#### إذا كانت **سارة** في قائمة **أحمد** السوداء او كانت هي او خادمها في قائمة الخادم السوداء {#in-black-list-external}
|
||||||
|
|
||||||
#### إذا كان alice في قائمة bob السوداء او كان هو او خادمه في قائمة الخادم السوداء
|
|
||||||
سوف يرجع الخادم 403 مع توضيح السبب.
|
سوف يرجع الخادم 403 مع توضيح السبب.
|
||||||
|
|
||||||
#### أساسيات
|
#### أساسيات التواصل الخارجي {#external-communication-basics}
|
||||||
- يجب على alice فتح إتصال [Websocket] مع جميع الخوادم التي يريد التواصل مع
|
|
||||||
افرادها.
|
- يجب على **سارة** فتح إتصال [Websocket] مع جميع الخوادم التي تريد التواصل مع
|
||||||
- لايتم تخزين الرسائل التي يستقبلها الخادم بشكل دائم، يتم تخزينها فقط إذا لم يكن
|
افرادها.
|
||||||
bob متصل بالخادم، ويتم مسحها بعد إرسالها إلى bob.
|
- لايتم تخزين الرسائل الخارجية التي يستقبلها الخادم بشكل دائم، يتم تخزينها فقط
|
||||||
- الرسائل والملفات بين الطرفين تكون مشفرة وتكون موقعة للخادم المراد التواصل مع
|
إذا لم يكن **أحمد** متصل بالخادم، ويتم مسحها بعد إرسالها إلى **أحمد**.
|
||||||
افراده.
|
- الرسائل والملفات تكون مشفرة بين **سارة** و **أحمد** وتكون موقعة للخادم المراد
|
||||||
|
التواصل مع افراده.
|
||||||
|
|
||||||
|
## شكر و تقدير {#acknowledgment}
|
||||||
|
|
||||||
## شكر و تقدير
|
|
||||||
شكراً للأشخاص التاليين على مراجعة و تحسين البروتوكول.
|
شكراً للأشخاص التاليين على مراجعة و تحسين البروتوكول.
|
||||||
|
|
||||||
- أمجد الشرفي <<me@amjad.alsharafi.dev>>: تحسين طريقة عمل التوقيع، و أقتراح
|
- أمجد الشرفي <<me@amjad.alsharafi.dev>>: تحسين طريقة عمل التوقيع، و أقتراح
|
||||||
الطريقة الحالية.
|
الطريقة الحالية.
|
||||||
|
|
||||||
|
@ -293,16 +339,17 @@ bob).
|
||||||
|
|
||||||
[^1]: لضمان عدم وجود شخص في المنتصف، يقوم بالتلاعب بالبيانات و الإطلاع عليها.
|
[^1]: لضمان عدم وجود شخص في المنتصف، يقوم بالتلاعب بالبيانات و الإطلاع عليها.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
[^2]: طالما انك عضو في الخادم، سوف يعتقد الخادم دائماً انك في إتصال [Websocket] معه، ولن يقوم بترقية أي إتصال إلى [Websocket]
|
[^2]: طالما انك عضو في الخادم، سوف يعتقد الخادم دائماً انك في إتصال [Websocket] معه، ولن يقوم بترقية أي إتصال إلى [Websocket]
|
||||||
|
|
||||||
[^3]: يتم إضافة العنوان الخاص بـbob و الخادم الخاص به في جدول طلبات الدردشة للتاكد من عدم إستقبال إشعارات قبول/رفض من خوادم مزيفة هدفها الإزعاج.
|
<!-- -->
|
||||||
|
|
||||||
[^4]: للتاكد من انه الخادم فعلاً، لن يتم طلب منه المفتاح العام بشكل مباشر، بل سوف يتم جلبه من مسار الخاص به، وهو <span
|
[^3]: يتم إضافة العنوان الخاص بـ**أحمد** في جدول طلبات الدردشة المُرسلة للتاكد من عدم إستقبال إشعارات قبول/رفض مزيفة هدفها الإزعاج.
|
||||||
dir='ltr'><code>/api/info</code></span>
|
|
||||||
|
|
||||||
[Websocket]: https://en.wikipedia.org/wiki/WebSocket
|
[Websocket]: https://en.wikipedia.org/wiki/WebSocket
|
||||||
[HMAC-SHA256]: https://en.wikipedia.org/wiki/HMAC
|
[HMAC-SHA256]: https://en.wikipedia.org/wiki/HMAC
|
||||||
[مفتاح التشفير المشترك]: #mfth-ltshfyr-lmshtrk
|
[مفتاح التشفير المشترك]: #shared-encryption-key
|
||||||
[Hex]: https://en.wikipedia.org/wiki/Hexadecimal
|
[Hex]: https://en.wikipedia.org/wiki/Hexadecimal
|
||||||
[Unix Time]: https://en.wikipedia.org/wiki/Unix_time
|
[Unix Time]: https://en.wikipedia.org/wiki/Unix_time
|
||||||
[AES-256 CBC]: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
|
[AES-256 CBC]: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
|
||||||
|
|
Loading…
Reference in a new issue