很少有电话。
任何平台。
Identity Layer 通过设计与最小表面集成。 微控制器上的 MicroPython,Android 和 Windows 上的 Flutter, 或者将 PHP bridge 放入您现有的端点中。 相同的协议。相同的加密保证。四通电话。
IdentityIoT,
通过安装 mip。
# 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})
| 成分 | 模型 | 角色 |
|---|---|---|
| 单片机 | 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 |
Identity IoT 节点不限于 NFC 访问。相同的经过身份验证的 node 可以携带任何传感器有效负载。 在 node 获取其 JWT 后,所有读数均通过 AES-256-GCM 加密 POST 传输。
| 传感器类型 | 典型硬件 | 有效负载字段 |
|---|---|---|
| 温度 | DHT22、DS18B20、BME280 | 温度(浮点数,°C) |
| 湿度 | DHT22,BME280 | 湿度(浮点数,%) |
| 压力 | BME280、BMP390 | 压力(浮动,hPa) |
| 被动红外运动 | HC-SR501 | 运动(布尔) |
| 全球定位系统 | NEO-6M、L76X | 纬度、经度、海拔高度(浮动) |
| 电能计量 | PZEM-004T,INA219 | 电压、电流、功率(浮点) |
| NFC 访问 | PN532 + NTAG424 DNA | badge_uid,已授予(布尔) |
{ "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。
# 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 无效。 | 高安全性机房、数据中心机架、设备柜。 |
| 端点 | 方法 | 角色 |
|---|---|---|
| identity_tag/it_request_challenge | POST | 发出随机数以进行 badge 验证 |
| identity_tag/it_verify_badge | POST | 验证Ed25519签名,返回GRANTED/DENIED |
| identity_tag/it_node_checkin | POST | Node 心跳和 JWT 刷新 |
| identity_tag/it_register_badge | POST (manager) | 写入 badge 公钥和权利 |
| identity_tag/it_list_nodes | GET (manager) | tenant 的 Node 车队状态 |
配置和管理应用程序在 Android 上运行。它使用设备的 NFC 写入 badge 有效负载 并通过经过身份验证的 Identity Layer 通道连接到后端。
// 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。
// 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'});
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 已清除 | Android 密钥库 / TEE |
| 视窗 | 生产,Microsoft Store 已清除 | Windows 凭据管理器 |
| Linux | 生产 | 库秘密 |
| iOS/macOS | 在路线图上 | Secure Enclave |
5 KB。
你的堆栈,不变。
PHP bridge 是位于现有端点前面的单个需求。 您的路线、您的数据库、您的业务逻辑。没动过.. Identity Layer 处理身份验证和有效负载加密。 按照添加的方式将其删除。
require_once
和两个函数调用。您的端点开始接收经过验证、解密的有效负载。
无架构迁移。没有用户表更改。没有会话存储。
完整的服务器端堆栈是 225 KB。
// 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 小时出口窗口。
日志收集后销毁。请求机关承担法律责任。
// 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 / MariaDB | 标准架构,无凭证列 |
| 缓存/临时 | Redis | 质询令牌、消息队列(TTL < 1 分钟) |
| 桥梁尺寸 | 5KB | 单个 PHP 文件,放入任何 LAMP 堆栈中 |
| 全栈大小 | 225 KB | 身份 STD + HS + 密钥 + 安全通道 + IoT + 标签 + 标签 |
| 部署 | 容器/本地/air-gapped | 没有强制的云连接 |