You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在搭载Scandium的Leshan服务器中实现RPK的TOFU机制?

实现TOFU机制的核心思路

Leshan本身没有内置TOFU支持,但你可以通过自定义RPK信任存储逻辑结合持久化存储来实现,核心逻辑:

  • 首次连接的新客户端,记录它的端点名称(Endpoint Name)和对应公钥,直接信任
  • 后续连接时,校验客户端提供的公钥是否和已记录的一致
  • 公钥不匹配就直接拒绝连接
具体实现步骤

1. 自定义RpkTrustStore

Scandium的RpkTrustStore接口负责验证客户端RPK,你需要实现这个接口,把TOFU逻辑加进去:

  • 实现isTrusted方法处理信任判断
  • 用持久化存储(比如本地文件、轻量数据库)保存端点和公钥的映射关系

示例代码大概是这样:

public class TofuRpkTrustStore implements RpkTrustStore {

    // 先用ConcurrentHashMap做内存存储示例,实际要换成持久化存储
    private final Map<String, PublicKey> endpointKeyMap = new ConcurrentHashMap<>();

    @Override
    public boolean isTrusted(PublicKey clientPublicKey, SocketAddress peerAddr, String endpointName) {
        if (endpointName == null) {
            return false; // 没有端点名称的连接直接拒掉
        }

        synchronized (endpointKeyMap) {
            PublicKey storedKey = endpointKeyMap.get(endpointName);
            if (storedKey == null) {
                // 首次连接,存下公钥并信任
                endpointKeyMap.put(endpointName, clientPublicKey);
                // 这里加持久化操作,比如写入本地文件或数据库
                saveToStorage();
                return true;
            } else {
                // 非首次连接,校验公钥是否一致
                return storedKey.equals(clientPublicKey);
            }
        }
    }

    // 把映射关系持久化到存储的方法,自己实现
    private void saveToStorage() {
        // 比如序列化endpointKeyMap到JSON文件,或者写入SQLite
    }

    // 服务器启动时加载已存储的映射
    public void loadFromStorage() {
        // 从存储读取数据,初始化endpointKeyMap
    }
}

2. 把自定义信任存储集成到Leshan服务器

构建Leshan服务器的时候,把默认的RPK信任存储换成你写的TofuRpkTrustStore:

// 初始化TOFU信任存储,启动时加载已保存的密钥
TofuRpkTrustStore tofuTrustStore = new TofuRpkTrustStore();
tofuTrustStore.loadFromStorage();

// 配置Scandium的DTLS连接器
DtlsConnectorConfig dtlsConfig = new DtlsConnectorConfig.Builder()
        .setAddress(new InetSocketAddress(5684))
        .setRpkTrustStore(tofuTrustStore) // 替换默认的信任存储
        // 这里还要加服务器自身的RPK配置,比如自己的公钥私钥
        .build();

// 构建并启动Leshan服务器
LeshanServer server = new LeshanServerBuilder()
        .setDtlsConfig(dtlsConfig)
        // 其他服务器配置,比如资源、端点等
        .build();

server.start();

3. 几个关键注意点

  • 端点名称要唯一:必须依赖客户端的Endpoint Name作为唯一标识,要确保客户端用固定且唯一的名称
  • 持久化不能省:内存存储重启就没了,一定要实现持久化(比如JSON文件、SQLite这类轻量存储)
  • 并发安全要考虑:多线程环境下,存储操作要加锁或者用线程安全的集合,避免数据混乱
  • 公钥序列化要正确:存储公钥时,要把它转成可序列化的格式(比如Base64编码的字节数组)
  • TOFU的安全风险:首次连接可能被中间人攻击,如果你的场景安全性要求极高,最好加个后续人工确认公钥的环节
标准与最佳实践

目前LwM2M标准没有专门定义TOFU机制,但TOFU是设备认证里常见的零配置信任模式,适合没法预先配置密钥的场景。几个最佳实践:

  • 把首次连接的设备公钥记录日志,方便后续审计
  • 定期备份公钥存储,防止数据丢失
  • 加个手动管理公钥的接口,比如允许删除、更新设备公钥,应对设备更换的情况

内容的提问来源于stack exchange,提问作者Juan Redondo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:43:18