• 已删除用户
Administrator
发布于 2022-08-12 / 57 阅读
0

基于SFS原理的门禁人脸权限更新方法

在学习自验证文件系统 SFS的过程中,SFS几个理念给了我一些启发:

  1. 在不依赖任何外部信息的条件下,利用加解密来控制权限。

  2. 通过可以自我证明身份的路径名实现安全地获取文件数据。

在我们的业务里,设备获取人脸开门权限高度依赖中心服务器。网络的不稳定与服务器的异常下,设备需要定期的检查全量的权限,以保证数据最终一致。权限检查的过程与更新的过程都非常的耗时耗性能,尤其是在运营商网络交割的过程中,设备网络的重启会带来大量的访问请求,导致服务器压力巨大。设备进行全量的权限检查,需要在服务器获取全量的用户信息,再进行全量的遍历筛选判断,对设备性能也是一个挑战。

故有了以下设计思考:
利用SFS的启发构建自验证文件系统,实现门禁设备人脸开门权限的更新与中心化服务器解耦与安全验证(这里是参考 SFS 的理念,而非技术或其源码);利用 ID 多次取模构建MerkleTree结构的层级目录,实现全量的权限检查的切割,提高检索的效率。

需注意:
该文章仅是流程的设计思考,不是最终的实现。且该方法已申请专利,如有同行友商阅读到此文章,请查阅专利文件避免侵权。

目录文件结构

/sfs/
    |—— hash($comunity_id)/
        |—— device \
            |—— hash($pub_key) \
                |—— .index
                |—— group_0 \
                    |—— .index
                    |—— subgroup_0 \
                        |—— .index
                    |—— subgroup_1 \
                    |—— subgroup_2 \
                    |—— subgroup_n \
                |—— group_1 \
                |—— group_2 \
                |—— group_n \
        |—— feature \
            |—— hash(user_id_0:expiry_date:feature_str).1
            |—— hash(user_id_1:expiry_date:feature_str).2
            |—— hash(user_id_2:expiry_date:feature_str).3
            |—— hash(user_id_n:expiry_date:feature_str).2

目录文件说明

  1. /sfs/为根目录,权限信息按小区进行分隔,目录名为小区ID的HASH值为hash($comunity_id)。完整路径为/sfs/hash($comunity_id)

    拥有多个小区权限用户仅占3%左右,也就是说在该文件系统里冗余了3%人脸特征值信息

  2. 每个小区各下设一个device目录和feature目录,分别为版本控制文件人脸特征值文件的目录。完整路径为/sfs/hash($comunity_id)/device//sfs/hash($comunity_id)/feature

  3. 99%设备的人脸数是低于 5000 的,设备取遍历 5000 次去对比与服务器数据的偏差,需要消耗设备与服务器大量的性能,而权限在资料录入的稳定期变动是非常小的。故对用户 ID 进行多次取模,设计了多层的目录结构(本示例中使用了 2 层)。

    例如:user_id%100%10,创建group_0~group_9十个目录,group_1下存放有用户有:1、11、21、31、41、51、61、71、81、91、101、111、121...
    在每个group下再取模user_id%100,创建subgroup_0~subgroup_99十个目录(因为 group 中已经取模过,此时不会生成 100 个目录,如group_1下的子目录有subgroup_1、subgroup_11~subgroup_91)。

  4. 设备目录 /sfs/hash($comunity_id)/device/hash($pub_key)/分组目录子分组目录下各有一个版本控制文件.index,共同构建出了一个树结构。版本控制文件.index内容为JSON格式。上一级别的version,是下级子节点 version 集合的 Hash。任何下级的变动必然影响上级的 HASH 值,保证通过根版本文件能够快速的检索到所有的修改内容。
    版本树结构

  5. /sfs/hash($comunity_id)/feature 存放着该小区所有用户的所有用户人脸照片特征值解析值。文件名为文件内容的 HASH 值,即hash(user_id:expiry_date:feature_str),不同算法厂商产生的特征值文件以后缀的形式区分,如xxxxxx.a表示 a 算法厂商计算的值;文件内容包含用户唯一标识、权限有效期、人脸特征值;文件采用国密sm4算法加密,密钥可采用一小区一密钥。

如何保障安全性

刚有讲到自验证文件系统的一个重要的特性,就是在不依赖任何外部信息的条件下,利用加解密来控制权限。在这文件系统中,有两个核心的数据:版本控制文件特征值权限文件

  1. 版本控制文件

    • /sfs/hash($comunity_id)/device/hash($pub_key)作为设备的私有命名空间,目录访问权限控制,通过设备密钥才能访问。任何设备只能访问自己命名空间下的子目录和文件。

    • 设备删除时,只需删除设备自己命名空间的文件夹,所有文件即被销毁。

  2. 特征值权限文件

    • /sfs/hash($comunity_id)/feature作为小区的所有住户的特征值权限库,目录访问权限控制,通过小区密钥才能访问。

    • 小区不在运营时,只需删除小区自己命名空间的文件夹,所有文件即被销毁。

另外,SFS 把身份验证与文件系统分开。例如我们将数据是存放在 OSS 上的,身份验证仍可以保留现有的Ali OSS STS机制,实现设备访问 OSS 的权限管控。

如何更新文件系统

纯后端的逻辑,这里不做分析。

如何实现快速检索

利用构建MerkleTree树形版本结构,设备按预设的规则定期去文件系统获取根版本控制文件,与本地版本进行对比。如版本有变动,则进行下钻分析找到变动的用户。文件系统中多出的用户在设备中新增,缺少的用户在设备中删除,变更的用户在设备中做更新。
检查更新流程