Linux下一种ELF文件代码签名验证机制( 二 )


3.4 公钥管理
在解密签名数据时 , 需要用到签名者的证书公钥 。由于可能存在多个签名者签发的代码 , 因此也就存在多个签名者的证书 。为了节省系统开销 , 尽量减小对系统性能的影响 , 我们必须高效地管理这些证书公钥 。为此 , 我们在系统核心空间中维护了一个信任公钥链表 , 所有被信任者的公钥都将被放在该公钥链表中 。当系统验证代码的签名值时 , 就可以直接从公钥链表中取得相应的公钥 。如果公钥链表中没有相应的公钥 , 则表示该代码的签名者不被信任 , 因而验证失败 。系统中的被信任公钥是可配置的 , 系统在启动时将根据配置文件自动初始化核心公钥链表 , 系统管理员也可以随时对其刷新或者修改 。3.5 软件结构 本机制的实现主要包括用户空间的签名验证工具和核心空间的签名验证机制模块两个部分 。其中 , 用户空间的签名验证工具是本机制的辅助工具 , 其主要功能是对 ELF 文件进行签名和设置 , 同时也可对 ELF 文件的签名值进行验证 , 在此不再赘述;核心空间的签名验证机制模块可以分为验证策略模块以及公钥管理模块 。
3.5.1 验证策略模块 验证策略模块负责执行签名值的验证策略 , 同时负责管理已验证文件的缓存链表 。当用户请求执行 ELF 文件时 , 该模块就会执行如图 3-2 所示的验证策略 。验证签名值时 , 系统将首先查询已验证文件缓存链表 , 如果发现被验证文件已经被验证过 , 那么就不必再进行重复验证 , 直接采用上次的验证结果 。如果缓存链表中没有被执行文件 , 那么就向公钥管理模块请求签名者公钥 , 然后再验证其签名值 。如果验证正确 , 则说明被执行文件是完整和可信的 , 就让其执行;否则就禁止执行 。另外 , 为了保证已验证文件缓存链表和实际文件的一致性 , 我们必须监视 ELF 文件的修改情况 , 当某一 ELF 文件被修改时 , 我们应当立即清除已验证文件缓存链表中与该文件相关的验证结果 。3.5.2 公钥管理模块 公钥管理模块主要负责对信任公钥链表进行管理 , 如:初始化链表 , 获取、添加以及删除公钥节点等 。信任公钥链表由一系列的公钥节点组成 , 如图 3-3 所示 。图 3-3 核心公钥链表 其中 key_id 是对应公钥的 MD5 哈希值 , 长度为 16 个字节 。从理论上说 , 不同公钥的 key_id 相同的概率接近于 2 128 分之一 。在很大范围内 , 我都可以认为 key_id 和公钥是一一对应的 。因此 , 我们将 key_id 作为每个公钥的唯一标识 。3.6 性能测试 表 3-3 是一组简单的测试数据 , 这些数据是通过多次执行后取得的平均值 。从中可以看出 , 通过使用分级机制和缓存机制 , 系统开销增加不到 5% , 大大减小了对系统性能的影响 。4、结束语 代码签名及验证的主要目的是防止执行病毒以及木马程序等恶意代码 , 提高操作系统的安全性;同时也是为了保护软件开发者以及使用者的利益 , 软件开发者可以防止他人冒名顶替 , 而软件使用者也可以确认软件的真实性和完整性 。【Linux下一种ELF文件代码签名验证机制】目前 , 也有很多系统采用安装时验证代码签名的机制 , 如微软的 windows 系列操作系统 。但是 , 仅仅在安装时验证代码签名存在很大的局限性 , 它无法检测程序安装后对代码的任何修改 。因此 , 采用执行时验证代码签名的机制将大大提高系统的安全性 。但安全性增强的同时却导致了系统效率的降低 。为了取得安全性与效率的平衡 , 本文提出了分级验证的机制 。对安全要求高的系统 , 则牺牲一定的效率来提高系统安全性;对安全性要求较低的系统 , 则牺牲一定的安全性来提高系统效率 。

推荐阅读