透明加密系统设计及实现-透明加密的关键技术

damone大约 106 分钟工作总结透明加密

在第一章已经详细地介绍了透明解密系统的主要发展状况,目前市面上的透明加密系统,大多存在兼容性差和移植麻烦的情况。最为主要的是目前的透明加密系统,缺乏有效的身份认证机制,导致透明加密系统的安全性受到了极大的影响。本章结合 Minifilter 和 LayerBSD 设计思想,详细地分析了透明加密系统的基本结构和原理,给出了有效的关键信息标识的方法。研究了内核模式与用户模式便捷的通信模型,详细给出了多种透明加密系统核心部分的结构并分析它们之间的优缺点,最后综合透明加密系统的整个架构,给出了一套高度可信的身份验证机制。

1 文件透明加密系统的基本原理

文件透明加密是指用户在操作的时候,虽然后台在自动的进行加解密,但是用户根本不知道加密及解密的存在,就像中间的隔了一层屏幕辐射过滤膜一样,用户感觉到不到它的存在。如图 1,在布置了透明加密的系统中,在进行文件 I/O 操作时,文件透明加密系统进行透明加解密,上层的已经授权的进程能够获取到文件的明文,非授权的进程仍然无法获取到文件的明文,故而防止了通过其它的进程获取文件明文并将其通过网络将文件传递到系统之外。在文件 I/O 过程中,文件透明加密及解密驱动会进行文件 I/O 进行过滤,拦截满足策略的 I/O 进行文件的加密及解密等相关的操作。

图 1 透明加密系统的工作原理图

透明加密不会影响到用户的使用习惯,也不需要改变已有的应用程序,就能够达到透明加密的效果。透明加密是一种被动的加密方式,文件的是否加密不以用户的意愿控制,而是自动根据透明加密系统的配置策略进行文件进行加密和解密。故而文件透明加密在企业,特别是机密机构和核心部门,已经成为了文件保护的最后的最坚固的防护盾。

2 透明加密系统的结构的研究

文件透明加密系统的核心部件工作在内核模式下,第二章我们详细地给出了文件过滤驱动程序及文件小过滤驱动的在操作系统的位置结构,文件透明加密系统中透明加密模块其实是文件过滤驱动或者是文件小过滤驱动程序,在驱动设备栈中位于文件系统驱动程序之上,主要负责文件访问的控制、进程及文件关系的控制、用户识别和控制以及核心的透明加密。但仅仅有透明加密驱动程序是无法满足需求的,因为透明加密大量的策略信息具有很大的灵活性,不同的用户对透明加密的需求存在存在着差异,因此,必须要一个灵活多变且功能强大的透明加密的策略配置端,保证用户的身份的可靠性并进行透明加密的策略配置。

在透明加密系统的总体结构设计时,出于性能、安全、灵活性及实用等多方面的考虑,将透明加密系统分为两个重要部分,分别位于操作系统的的内核模式和用户模式。具体的结构如图 2 所示。

图 2 透明加密系统的总体结构

透明加密系统被分为两个组成部分,一个是位于内核模式的透明加密驱动,由于其承当着透明加密等核心的功能,由于其除了完成透明加解密的功能外,还负责其它的许多文件控制的功能,将其命名为文件控制器。另一个是位于用户模式的客户配置端,客户端以应用程序的形式存在于系统中,承担着用户身份认证及文件保护策略配置的任务,作为文件控制器的辅助,提高了整个系统的灵活性和实用性。由于在系统设计中的两个主要组成部分分别位于不同的操作系统模式下,各个模块都必须提供相应的通信模块以提供信息的交换的桥梁。

采用用户模式及内核模式双模块组成的设计模式,减轻了内核模式模块的开发难度,提高了系统的稳定性,将配置策略端放置在客户端,提高系统的灵活性,但是对用户身份的认证以及系统的完整保护提出了新的要求,简单的基于用户模式的验证是无法达到系统的要求的,需要设计更加严格的身份验证机制,保证系统的完整性和用户身份验证的可靠性。

3 关键对象的有效标识的研究

在进行相关的文件 I/O 的控制时,进行关键信息的有效标识是透明加密系统可靠性的保障。在内核模式获取相关的信息要比用户模式下要复杂得多,因为工作在内核模式下的驱动进程无法直接访问当前用户会话空间的有效的信息。而且工作于内核模式下的驱动程序,特别是文件系统驱动程序,将会处理成百上千的进程发起的 I/O 请求,怎样对这些 I/O 进行有效的标示以完成 I/O 的控制是一个值得思考的问题。在透明加密及文件访问的控制中,相关的主要的信息包括进程的有效标识,发起 I/O 的用户的有效标识,加密文件的有效标识以及磁盘卷的有效标识,下面分别讨论以上信息在文件透明加密系统的标识方法。

3.1 进程的有效标识

在透明加密系统中,为了进行授权进程及非授权进程的区分,进程的标识是十分必要的。在操作系统中通常区分进程的方法采用的是通过进程 ID 号的方法,但是这在透明加密系统中是不可行的,因为一个进程的 ID 是变动的,不能作为有效的标识。本文给出了三种有效的进程标识方法,具体如下:

  1. 可执行文件名称标识

在进程的创建是,需要指定其具体只想文件的路径及名称,通过进程的 ID 号可以驱动进程的进程描述符地址,取得该文件名,该方法能有效地识别进程,但是不能防止进程欺骗,如果运行程序采用更换名称的方式欺骗系统,系统将无法处理。

  1. 可执行文件内容摘要标识

直接采用可执行文件名称标识进程存在进程欺骗的问题,为了解决进程欺骗的问题,在配置策略时,先根据可执行文件的内容采用有效的摘要算法生成摘要。在进行进程识别时,不单单采取文件名识别的方式,还根据根据可执行文件的内容生成相关的摘要与原本的摘要进行对比用于区分进程,这样便可以有效地解决进程欺骗的问题。采用动态及静态相结合的方法 (进程开始执行时通过提取摘要进行区分,保留进程 ID 及名称作为后续标识使用,只需要进程开始执行时校验一次即可),该方案可以实现可靠且高效的进程区分,是比较理想的解决方案。

  1. 进程运行时环境摘要标识

解决进程欺骗是一个比较麻烦的问题,不是无法实现,而是相关的方法是否具有实用性。考虑到操作系统性能的要求,采集进程的系统运行时环境信息,根据运行时环境信息(进程加载的动态链接库及进程的代码段的信息)生成摘要,然后进行比较识别进程。采用运行时环境摘要标识,实现难度较大。

3.2 加密文件的有效标识

在透明加密系统中,进行加密文件与非加密文件的准确区分决定着透明加密系统的工作是否有效,简单的字节码标识虽然能够区分加密与非加密文件,但是由于其包含的信息量少,远远无法满足透明加密系统的需要。在进行文件标识时常用的文件标识方法有后缀名标识、配置文件标识(通过配置文件指定机密文件)、文件内容标识。三种方法中,后缀名标识和配置文件标识在灵活性和使用性上都存在很大的缺陷。后缀名标识其提供的信息有限,远远不同满足需要,同时后缀存在很大的变动性,改变后缀名称,标识就会失效,稳定性极差。采用配置文件进行标识由于文件的识别依靠具体的配置文件,当文件在系统间迁移时或者配置文件丢失后就会导致标识失效。采用文件内容内容进行文件的标识是最可靠也是最安全的方法,不存在上述的问题,是目前广泛采用的方式。

将文件的标识放入文件中是一种可靠且可行的解决方案,而将文件标识存放在文件中,也有多种不同的选择方案,一种是将文件的标识放在文件的头部,一种是将文件的标识放在文件的尾部,还有一种是将文件标识放在数据流中。

将文件标识放在文件头部,文件的整体内容就会向后偏移,在实现的过程中需要对上层的应用程序隐藏文件头,这是一件十分麻烦的事情,实现难度特别大。但是将文件标识放在头部有许多优点,首先文件位于文件头部,不会轻易遭到损坏,将文件放在文件头部时,当文件的内容改变时,不需要修改文件头的内容,从使用角度来讲,是最好的标识方案。

将文件放在文件的尾部,将文件放在文件的尾部,没有将其放在头部的难度大,不用为上层应用程序隐去文件头,只需要将文件的大小修改即可,但是将文件标识放在尾部,有一个十分麻烦且不稳定的问题,当文件的大小改变时,文件的尾部必须进行移动,耗费资源且不如放在头部稳定。但是实现起来较为简单,也是常用的方案之一。

将文件的标识信息放在输入流中,是最近几年才出现的设计方法,主要针对 NTFS 文件系统,在 FAT 文件系统无法实现该方式,故而采用该方式的使用范围有限,仅仅支持 NTFS 文件系统。但是在文件内容放在文件流中,不需要做任何的文件处理,简单方便稳定度高,在未来应该会成为最主流的设计方案。

3.3 用户及卷的有效标识

在目前的透明加密系统中,进行身份认证都是针对整个操作系统的,只要用户认证成功,整个透明加密系统就没有其它的身份认证措施,灵活性及控制的程度还有提高的空间。为了实现更加严格身份控制,本文将认证的粒度细化到用户级别。经过研究分析,为了实现用户级别的控制,必须对每一个文件 I/O 请求,明确地知道发起该请求的用户到底是系统中的那个成员,在内核中,由于 Windows 操作系统本身是不开放源代码的,且在内核驱动开发文档中,未提供根据相应 I/O 请求获取到用户的标识的接口。通过仔细的分析,发现了在操作系统中有一个和用户是一一对应的概念,被称为会话,在操作系统中,每一个用户登陆时都对用了一个唯一的会话,在会话的环境下运行着属于当前用户的一系列进程,操作系统通过会话管理器来进行用户登陆的管理。在内核部分,我们可以获取到当前发起 I/O 请求的进程 ID,进一步通过进程号便可以得到用户登陆所在的会话 ID。使用会话 ID 就可以作为用户的有效标识,从而完成用户级别的控制。

为了防止非法用户随意将文件通过移动设备将操作系统中的内容拷贝带走,必须实现针对磁盘设备的控制。如何完成对磁盘等存储设备的控制,关键在于如何对磁盘等设备进行有效的标识,采用简单的盘符标识是远远达不到要求的,进过研究分析,有两种可行的方案,一种是直接采用磁盘的序列号作为作为标识,另一种是采用 GUID 编号作为有效的标识。采用磁盘序列号虽然能够准确的达到标识磁盘的要求,但当存储设备不是磁盘时,就不能满足要求了。而采用 GUID 编号这完全没有这个问题,GUID 编号是微软管理设备的一套管理规范,他为每一个设备生成了一个唯一的 GUID 号,采用 GUID 号不仅唯一标识存储设备,也能唯一地标识系统中的其它设备。

4 用户模式与内核模式数据通信的研究

在进程间通信时,一般采用的方式为管道通信和内存共享以及消息机制等等,这些方法在进行用户模式下是是完全没有问题的,但是在内核模式和用户模式之间进行信息的交互方式就不实用。

  1. 普通的通信方式的分析

普通的进程采用管道及内存共享进行数据的交换是最为常用的方法,主要表现在操作简单,且效率高。但是在内核模式下与用户模式下的进程通过这些方式进行数据的交换,达不到要求,因为二者在不同的系统模式下,采用普通的管道技术无法满足安全性的保障,而采用内存共享的方式,必须引入信号量及互斥体才能勉强满足通信的安全及的要求,但仅仅能支持简单的数据通信,对于交互频繁的环境远远达不到要求。

  1. 采用 Minifilter 的端口通信机制

为了满足用户模式和内核模式的通信要求,微软在 Minifilter 的框架中引入了与网络通信机制中的 TCP 通信类似的端口通信机制。采用 Minifilter 的端口通信机制完全不存在普通的进程间通信的问题,而且采用端口通信机制后,由于不同的用户向系统发起的连接请求可以进行有效的标识,给用户的身份认证提供了有效的依据,使更加可靠的基于用户粒度的身份的验证成为了可能,本章将在此基础上进行高可信度的身份认证的算法研究。

5 透明加密的关键技术的研究

透明加密系统的核心部分是以文件系统过滤驱动的方式进行设计的,文件过滤驱动在文件系统设备栈中位于文件系统驱动程序之上,处于文件系统过滤驱动和 I/O 管理器之间。必须对文件 I/O 的流程进行详细的分析才能够了解文件 I/O 操作的具体流程及相关的细节。要想设计出高效率的文件系统过滤驱动程序。必须充分考虑操作系统中文件缓存的作用,同时文件缓存也给文件的透明加密及解密带来很多困扰。在设计透明加密驱动程序时,不仅仅要考虑如何拦截 I/O, 拦截那些 I/O, 还要考虑该怎样处理这些 I/O, 以及缓存带来的各种困扰问题。

5.1 文件 I/O 的详细分析

在当一个文件以非缓存的形式打开的时候,对文件的读写都是非缓存的形式进行的,在操作系统中,将这种文件 I/O 的方式称为 NonCached IO,采用非缓存的形式进行文件的读写是不会涉及到文件缓存问题,处理相对简单,文件 I/O 的请求会直接通过文件系统驱动下发到相关的设备。当文件以缓存的方式进行文件的 I/O 操作是,情况就要复杂得多,不仅要考虑到缓存的问题,还要充分考虑到操作系统中内存管理的页错误,为了更好地分析带缓存文件 I/O 的具体情况,下面将针对读、写文件两种操作进行详细的分析。

图 3 详细地分析了带缓存的文件 I/O 的具体流程,当对带缓存的文件进行读操作时,当请求达到文件系统驱动时,如果是首次进行读操作,文件系统驱动将会调用缓存管理器的接口为文件进行缓存环境的创建,如果缓存已经创建完成则向缓存管理器发起读请求,如果文件读写的位置对应的段视图不存在,缓存管理器为创建相关的段视图。当段视图存在后,文件缓存管理器将会从段视图中复制数据到用户缓冲区。这时如果视图对应的文件内容并未读入,缓存管理器将向内存管理器发起页错误,内存管理器向文件系统驱动发起分页 I/O 读请求,文件系统驱动在接到分页 I/O 的请求时,将会直接下发请求给下层驱动设备并等待请求返回,文件系统驱动将分页 I/O 的结果返回给内存管理器,内存管理器完成页面错误的处理,将文件内容加载到段视图中。缓存管理器从段视图中得到文件内容,复制到用户缓冲区中,将请求结果返回给文件系统驱动,文件系统驱动返回给 I/O 管理器,I/O 管理器将结果返回给应用程序便完成了整个读请求。

图 3 带缓存的文件读的详细流程

当进行带缓存的文件写操作时,其它的流程基本相识,只有部分区别。如图 4,在文件写操作时,对段视图的操作与读请求时相反,是将用户缓冲区中的内容复制到段视图中。在处理页面错误时,内存管理器并不发起写请求,而是释放部分的物理页面,为指定的段视图对应的虚拟地址分配物理页面,缓冲管理器完成数据的复制后直接返回。整个写操作中并未直接将数据写到磁盘外存中,而是操作系统闲暇或者需要时,在段视图中的内容写入外设存储中。

图 4 带缓存的文件写操作的详细流程

5.2 文件缓存的处理

在文件的读写操作中,文件的缓存有着巨大的作用,大幅度地提高了操作系统的效率。涉及文件缓存的 I/O 处理极其复杂,任何的弊漏都可能会导致整个操作系统崩溃,造成不可估量的后果,在进行相关处理时,必须小心谨慎。在透明加密的过程中,如果关闭文件的缓存,虽然能够解决缓存带来的各种困扰问题,但是会对操作系统的性能造成巨大的负面影响。在设计中这种设计思路已被淘汰。

在以往透明加密系统的设计时,有三种主流的设计思路。分别是缓存存放密文,缓存存放明文,双缓存的设计模式。下面本章将结合 Miniflter 文件小过滤驱动的特点,充分考虑文件的缓存作用,针对三种设计思路给出相应的透明加密的设计模型,并分析其优缺点。

1、文件缓存密文设计方式

前文已经讲到,Minifilter 文件过滤驱动程序可以完成文件 I/O 的拦截,可以拦截 FAST_IO,NONCACHED_IO,PAGEING_IO 等 I/O 请求。这些 I/O 中有带缓存的文件 I/O, 也有不带缓存的文件 I/O。其中 FAST_IO 是带缓存的 I/O, 其它的都是不带缓存的 I/O, 在设计时必须区分处理。图 5 简要地阐述了基于密文的缓存的设计思想,当授权进程直接读取磁盘文件时,采用 NOCACHE_IO 进行文件的读写时,直接进行加解密。当授权进程以缓存的方式读取文件时,文件读到缓存中不进行处理,缓存中便存放密文,在进程通过 FAST_IO 读写缓存中的内容时,进行解密或加密,这样授权进程便可得到明文。而非授权进程读取文件时不进行任何的处理,因此无法得到文件的明文。但是,采用该种设计方式存在一个很大的问题,当授权的进程以文件内存映射的方式打开文件时,其操作流程和缓存类似,采用 PAGEING_IO 从文件中读取内容到内存中,由于透明加密驱动未对 PAGEING_IO 做任何的处理,因此内存中的内容是密文,当授权进程文件以内存映射的方式打开时也无法得到明文。

图 5 密文缓存的设计方式

2、文件缓存明文的设计方式

如图 6 ,文件缓存为明文的方式与文件缓存为密文的情况十分相似,不同的是,在进行 PAGEING_IO 时进行加密或解密,缓存中存放明文,进行 FAST_IO 时,对授权的进程不进行处理,而对非授权的进程进行读加密,禁止写的限制防止数据的泄漏。该种设计方式与方式 1 也存在相同的问题,当未授权的进程以内存文件映射的方式打开文件时,由于采用 PAGEING_IO 进行了加密和解密,故而其能够得到文件的具体明文,造成了数据的泄密。为了防止泄密,可以在 PAGEING_IO 时进行区分进程的处理,这样便造成了文件缓存中可能是密文也可能是明文,当多个进程同时打开文件时,容易造成数据的混乱,需要进行互斥处理并刷新缓存内容,对操作系统的性能有一定影响。

图 6 明文缓存的设计方式

3、双缓存的设计方式

由于采用密文缓存存在文件映射导致授权进程以内存文件映射的方式打开文件无法取得明文,而明文缓存设计模式需要反复的刷新缓存来保证数据的一致性。可以采用双缓存的方式来解决缓存带来的各种困扰。

图 7 双缓存的设计方式

如图 7,双缓存的设计模式,引入双缓存的概念,在系统中存在两份缓存,一份是明文缓存,另一份是密文缓存,当向密文缓存中通过 PAGEING_IO 操作文件时不进行任何处理,其中存在的是密文,而向明文缓存中操作文件时进行加密和解密,缓存中存放的时明文,当授权进程采用 FAST_IO 进行文件的读写时,操作的是明文缓存,不需要任何的处理,同样当非授权的进程读写文件时操作的是密文缓存,也不要任何的处理,采用双缓存的方式完全不存在密文缓存和明文缓存设计方式的问题,但是采用双缓存也存在问题,需要维护两个缓存,需要保证二者内容的一致性,额外维护缓存增大了内存耗费,而且难度大,不易实现。

5.3 文件 I/O 请求缓冲区的替换

要进行文件加密及解密,驱动读写的数据是问题的关键,如何获取读取或写入的内容,关键在与根据 I/O 的方式得到文件 I/O 操作的缓冲区。文件 I/O 的方式主要有三种方式,包括缓冲方式、直写方式、及其它方式。

图 8 缓冲方式和直写方式的使用

其它方式直接将用户空间的指针传递到用户空间,不做任何处理。下面主要分析缓冲方式和直接写方式。如图 8,图中显示了两种 I/O 在驱动中的使用方式。

(1)缓冲方式在文件的读写请求中基本不出现,从发起文件 I/O 请求的进程的用户空间拷贝一份数据到内核空间,不同进程空间的内存各自独立,互不干涉。但是需要进行拷贝,效率较低。

(2)直写方式采用 MDL 来传递缓冲区,直接修改页表属性将用户空间的缓冲区的地址范围映射到内核空间,不需要拷贝数据,效率较高。

5.4  结合透明加密驱动后的 I/O 流程分析

在加入透明加密驱动程序后,FAST_IO 和 IRP_IO 请求都会被文件过滤驱动拦截处理,进行相关的过滤工作。文件过滤驱动位于文件系统驱动之上,可以完成缓存及文件读写的内容的控制。

图 9 结合透明加密过滤驱动的 I/O 流程

6 高度可信的身份验证的研究

目前的透明加密系统其控制粒度较大,控制力度受到了很大的限制。为了实现更为精确的控制,进一步细化控制的粒度是有必要的。上文已经给出了基于用户程度的控制思路,采用会话 ID 作为 I/O 请求的有效的标识来进行基于用户的 I/O 控制。为了保证系统的安全性,采用多重的验证机制来进行用户的身份认证是有必要的,在分析各种验证机制的基础上,本章给出了一套多重的身份验证机制。

如图 10 所示,为了更好的进行验证过程的说明,将用户的状态分成了 7 种,分别是客户端启动、用户注册情况、密码验证、USB Key 插入状态、内核模式验证、验证成功以及验证注销。具体的相互变换方式图中给出了详细的说明。

图 10 高可信度的身份验证的状态转换图

可以看出,该方法有如下特点:

(1)采用了三重验证机制,包括密码验证、USB_Key 验证及内核模式验证,保障验证的可靠性,增加了破解的难度。

(2)采用了软件和硬件相结合的方式,避免了通过单一的软验证密码泄漏的问题。

(3)采用了内核模式及用户相互结合思想,身份的验证将用户模式及内核模式集合起来,保证了系统的完整性,任何模块的破环都会导致验证的失效。

(4)采用动态实时监测,系统时刻监测用户 USB Key 的情况,只要用户的 USB 失效,用户就会被强制下线,防止非法用户通过非法手段入侵系统。

7 本章小结

本章主要进行透明加密系统的主要技术的研究,从透明加密系统结构的研究到关键对象的标识,内核模式及用户模式的通信、透明加解密的关键技术及高可信度的用户身份验证,本章在经过详细的分析之后给出了相应的合理研究方案,为透明加密系统的整体设计和实现奠定了坚实的基础。