很少有电话。
任何平台。

Identity Layer 通过设计与最小表面集成。 微控制器上的 MicroPython,Android 和 Windows 上的 Flutter, 或者将 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})
成分 模型 角色
单片机 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 可以携带任何传感器有效负载。 在 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 DNAbadge_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 注册表、组树和权利表。 注册到 Tenant A 的 badge 无法被属于 Tenant B 的 node 验证。 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)tenant 的 Node 车队状态

配置和管理应用程序在 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 已清除Android 密钥库 / TEE
视窗生产,Microsoft Store 已清除Windows 凭据管理器
Linux生产库秘密
iOS/macOS在路线图上Secure Enclave

5 KB。
你的堆栈,不变。

PHP bridge 是位于现有端点前面的单个需求。 您的路线、您的数据库、您的业务逻辑。没动过.. Identity Layer 处理身份验证和有效负载加密。 按照添加的方式将其删除。

进、退。require_once 和两个函数调用。您的端点开始接收经过验证、解密的有效负载。 无架构迁移。没有用户表更改。没有会话存储。 完整的服务器端堆栈是 225 KB
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 / MariaDB标准架构,无凭证列
缓存/临时Redis质询令牌、消息队列(TTL < 1 分钟)
桥梁尺寸5KB单个 PHP 文件,放入任何 LAMP 堆栈中
全栈大小225 KB身份 STD + HS + 密钥 + 安全通道 + IoT + 标签 + 标签
部署容器/本地/air-gapped没有强制的云连接