مكالمات قليلة.
أي منصة.

Identity Layer يتكامل مع الحد الأدنى من السطح حسب التصميم. MicroPython على وحدة التحكم الدقيقة، Flutter على Android وWindows، أو تم إسقاط PHP bridge في نقاط النهاية الموجودة لديك. نفس البروتوكول. نفس ضمانات التشفير. أربع مكالمات.

Raspberry Pi Pico 2W, PN532 NFC reader, SSD1306 OLED display, NTAG424 DNA card
Boot
Registering
Node exists
Verified
Challenge
Active
أربع مكالمات المنطوق. WiFi، OLED، وتحميل التكوين هي البنية التحتية للجهاز، ليس Identity Layer. الهوية بدائية IdentityIoT, تم التثبيت عبر mip.
MicroPython
# Install via mip — no external dependencies
# import mip; mip.install("github:wide/identity-micropython")

from identity_iot import IdentityIoT

# 1. Init — configure node identity
identity = IdentityIoT(
    base_url  = cfg['base_url'],
    node_type = cfg['node_type'],
    tenant_id = cfg['tenant_id'],
    comm_key  = cfg['comm_key'].encode(),
    comm_iv   = cfg['comm_iv'].encode(),
)

# 2. Register — device-bound key, runs once
identity.ensure_registered()

# 3. Authenticate — Ed25519 challenge / verify / JWT
token = identity.authenticate()

# 4. Authenticated request — AES-256-GCM encrypted payload
response = identity.post_encrypted({'request': 'record_sensor_data', 'value': 42})
عنصر نموذج دور
MCU Raspberry Pi Pico 2W (RP2350) TrustZone، WiFi، device-bound تخزين المفاتيح
NFC reader PN532 واجهة I2C، تقرأ شارات NTAG424 DNA
عرض SSD1306 128x64 OLED تسلسل التمهيد، وحالة التحقق
NFC badge NTAG424 DNA (إن إكس بي) AES-128 مدمجة، مفاتيح غير قابلة للتصدير، ديناميكية CMAC
ESP32 وRP2040 عمليات النشر المرجعية لمراكز البيانات وقطاعات الوصول الفعلي قيد التقدم. البروتوكول وSDK متطابقان عبر جميع الأجهزة المدعومة.

العقد Identity IoT لا تقتصر على الوصول NFC. يمكن لنفس node المصادق عليه أن يحمل أي حمولة مستشعر. يتم نقل جميع القراءات عبر AES-256-GCM المشفرة POST بعد حصول node على JWT.

نوع المستشعرالأجهزة النموذجيةمجال الحمولة
درجة حرارةDHT22، DS18B20، BME280درجة الحرارة (تعويم، °C)
رطوبةDHT22، BME280الرطوبة (تعويم،٪)
ضغطبي إم إي 280، بي إم بي 390الضغط (تعويم، hPa)
حركة شرطة التدخل السريعHC-SR501الحركة (بول)
نظام تحديد المواقعنيو-6M، L76Xخطوط العرض، الطول، الارتفاع (تعويم)
قياس الطاقةPZEM-004T، INA219الجهد، التيار، الطاقة (العائمة)
NFC الوصولPN532 + NTAG424 DNAشارة_uid، مُمنوحة (منطقي)
JSON (تم فك تشفيرها)
{
  "node_uid"   : "273ec83a-84c8-4967-aafa-0780ab161cc1",
  "tenant_id"  : "0b3cfe4d-fdf7-46c2-bd41-b533da415dd9",
  "node_type"  : "sensor",
  "temperature": 24.3,
  "humidity"   : 58.1,
  "pressure"   : 1013.2,
  "updated_at" : "2026-06-09 11:42:07"
}

Badge قراءة. صدر التحدي.
تم التحقق من Ed25519.

Identity Tag هي طبقة التطبيق المبنية فوق Identity IoT. تؤدي كل قراءة badge إلى تشغيل دورة Ed25519 challenge/response كاملة مقابل الواجهة الخلفية. لا توجد أسرار مخزنة على reader. لا توجد هوية نص واضح على badge. متعدد tenant حسب التصميم.

Badge إلى GRANTED في أربع خطوات. reader (Pico 2W + PN532) هو Identity IoT node موثق. يحمل badge جزءًا من المفتاح الخاص المشفر AES-CBC وتقسيم DEK. تُصدر الواجهة الخلفية تحديًا، وتتلقى توقيع Ed25519، وتتحقق منه، وتعيد GRANTED أو DENIED. لا توجد أسرار تعبر السلك بنص واضح. لا توجد قاعدة بيانات الاعتماد.
التدفق: badge قراءة للوصول إلى القرار
# 1. Reader reads NTAG424 DNA NDEF payload
#    Fields: epk (encrypted private key), df2 (DEK fragment 2), mode (STD|HS)

# 2. DEK reconstruction
dek = df1_from_config XOR df2_from_badge

# 3. Decrypt badge private key
badge_privkey = AES_CBC_decrypt(dek, epk)

# 4. Request challenge from backend
challenge = POST identity_tag/it_request_challenge
#    { node_uid, badge_uid, tenant_id }

# 5. Sign challenge with badge key (Ed25519)
signature = ed25519_sign(badge_privkey, challenge_nonce)

# 6. Verify at backend
result = POST identity_tag/it_verify_badge
#    { challenge_id, signature_b64 }  ->  { granted: true }

# 7. Reader actuates relay (GRANTED) or displays DENIED
وضعوصفحالة الاستخدام
STD يعمل Badge على أي محطة في الأسطول المعتمد لذلك tenant. الوصول إلى المكتب، ونقاط الدخول العامة.
HS Badge مرتبط بشكل مشفر بمحطة محددة. يتضمن الاشتقاق DEK hash للمفتاح العام للمحطة. Badge غير صالح على أي reader آخر. غرف أمنية مشددة، ورفوف مركز البيانات، وخزائن المعدات.
يحتوي كل tenant على مساحة اسم معزولة: أسطول node الخاص به، وتسجيل badge، وشجرة المجموعة، وجدول الاستحقاق. لا يمكن التحقق من badge المسجل في Tenant A بواسطة node المنتمي إلى Tenant B. يتم فرض عزل Tenant على مستوى استعلام قاعدة البيانات، وليس عبر منطق التطبيق وحده.
نقطة النهايةطريقةدور
identity_tag/it_request_challengePOSTقم بإصدار رقم قياسي للتحقق من badge
identity_tag/it_verify_badgePOSTالتحقق من توقيع Ed25519، وإرجاع GRANTED/DENIED
identity_tag/it_node_checkinPOSTNode نبضات القلب و JWT التحديث
identity_tag/it_register_badgePOST (manager)اكتب badge المفتاح العام والاستحقاق
identity_tag/it_list_nodesGET (manager)Node حالة الأسطول لـ tenant

يعمل تطبيق التوفير والإدارة على نظام Android. يستخدم NFC الخاص بالجهاز لكتابة حمولات badge ويتصل بالواجهة الخلفية عبر قنوات Identity Layer المصادق عليها.

Dart / Flutter: badge اكتب
// identity_tag package - badge provisioning
final writer = IdentityTagWriter(api: tagApi);

// Generate badge keypair and encrypt private key with split DEK
final payload = await writer.prepareBadgePayload(
  tenantId  : tenant.id,
  mode      : BadgeMode.STD,   // or BadgeMode.HS
  nodeUid   : null,              // required for HS mode
);

// Write NDEF to NTAG424 DNA via flutter_nfc_kit
await writer.writeToTag(payload);

الهوية المرتبطة بالجهاز.
أربع مكالمات.

الحزم المحلية. لا توجد خدمة هوية خارجية. المفتاح الخاص لا يغادر الجهاز أبدًا. تخزين آمن عبر flutter_secure_storage وTEE / Secure Enclave عند توفرها. تشفير الحمولة هو من طرف إلى طرف عبر ITEMSEncrypter.

identity_package identity_std identity_hs items_crypto items_search items_document_body
جميع الباقات محلية. لا توجد تبعيات pub.dev على طبقة الهوية. يتم توزيع SDK كجزء من حزمة الترخيص.
Dart / Flutter
// 1. Init — JWT identity, silent on subsequent boots
final auth = IdentityAuthServiceStd(ITEMSGlobals.authURI);
await auth.ensureJwt(
  preferredLocale: locale.languageCode,
  utcOffsetMin:    DateTime.now().timeZoneOffset.inMinutes,
);

// 2. Handshake — silent if identity already present on device
final result = await api.mjHandshake(
  identityHash: identityHash,
  publicKey:    publicKey,
);

// 3. Store JWT — session active, no password, no credential database
await _storage.write(key: 'token', value: result['token']);

// 4. Every request — AES-256-GCM payload, end-to-end encrypted
final response = await api.postEncrypted({'request': 'your_request'});
YAML
dependencies:

  # Identity Layer — local packages, no external registry
  identity_package:
    path: packages/identity_package
  identity_std:
    path: packages/identity_std
  identity_hs:
    path: packages/identity_hs
  items_crypto:
    path: packages/items_crypto
منصةحالةتخزين آمن
أندرويدتم مسح الإنتاج، Google Playمخزن مفاتيح أندرويد / TEE
ويندوزتم مسح الإنتاج، Microsoft Storeمدير اعتماد ويندوز
لينكسإنتاجليبسيكريت
دائرة الرقابة الداخلية / ماكعلى خارطة الطريقSecure Enclave

5 كيلو بايت.
مجموعتك، دون تغيير.

PHP bridge هو متطلب واحد يقع أمام نقاط النهاية الموجودة لديك. مساراتك وقاعدة بياناتك ومنطق عملك. لم يمسها.. يعالج Identity Layer المصادقة وتشفير الحمولة. قم بإزالته بنفس الطريقة التي أضفتها بها.

التسرب، التسرب. واحد require_once واثنين من المكالمات الوظيفية. تبدأ نقاط النهاية الخاصة بك في تلقي حمولات تم التحقق منها وفك تشفيرها. لا يوجد ترحيل للمخطط. لا توجد تغييرات في جدول المستخدم. لا يوجد تخزين للجلسة. المكدس الكامل من جانب الخادم هو 225 كيلو بايت.
PHP
// 1. Include the Identity Layer bridge — 5 KB
require_once 'identity/_mj_auth.php';

// 2. Authenticate — JWT verified, identity_hash extracted
//    identity_hash is a 64-char SHA-256 hex — never a user ID
[$identityHash, $tenantId, $claims, $role] =
    mj_authenticate_identity($encoder);

// 3. Every response — AES-256-GCM encrypted, end-to-end
sendEncryptedResponse($encoder, [
    'status' => 'ok',
    'data'   => $yourData,
], ['ts' => time()], 200);
توجد سجلات التدقيق ولكن لا يمكن الوصول إليها من خلال التشفير. الوصول يتطلب أمر محكمة مصادق عليه. ال mj_mandate_log نقطة النهاية يسجل التفويض ويفتح نافذة تصدير لمدة 72 ساعة. يتم تدمير السجلات بعد جمعها. وتتحمل الجهة الطالبة المسؤولية القانونية.
PHP: mj_mandate_log
// Requires role = admin — never operator
[$userId, $tenantId, $claims, $role] = mj_authenticate($encoder);
mj_require_role($encoder, $claims, 'admin');

// Register mandate — opens 72h export window
// target_identity_hash: 64-char SHA-256, never plaintext identity
// Ciphertext is never stored — metadata only
$connector->executeDatabaseParameterQuery(
    "INSERT INTO audit_log (mandate_number, issuing_country,
     issuing_court, target_identity_hash, export_status)
     VALUES (?, ?, ?, ?, 'PENDING')",
    [$mandateNumber, $issuingCountry, $issuingCourt, $targetHash],
    $db
);
عنصرتكنولوجياملحوظات
وقت التشغيلPHP 8.xالفانيليا، لا يوجد إطار مطلوب
قاعدة البياناتMySQL / ماريا دي بيالمخطط القياسي، لا توجد أعمدة الاعتماد
ذاكرة التخزين المؤقت / سريعة الزوالRedisرموز التحدي وقوائم انتظار الرسائل (TTL < دقيقة واحدة)
حجم الجسر5 كيلو بايتملف PHP فردي، قم بإسقاطه في أي حزمة LAMP
حجم المكدس الكامل225 كيلو بايتالهوية STD + HS + المفاتيح + القناة الآمنة + إنترنت الأشياء + التصنيفات + العلامة
النشرالحاوية / داخل المنشأة / air-gappedلا يوجد اتصال سحابي إلزامي