关于文件透明加密解密

1.windows文件系统概述 
硬盘文档加密系统驱动原理一般有两种:通过HOOK一些底层的系统内核调用对文件目录的访问权限进行控制,在文件系统输入输出驱动上层直接建立一个驱动对文件目录的数据进行加密。由于windows文件系统不是物理设备,其堆栈结构比较特殊,因此文件系统过滤驱动也与一般过滤驱动有一些不同(这一点背景可以参考下楚狂人[1]的文档和IFS的提供的若干文档,除了正常的文件接口,还有一种称为FASTIO),文件系统是针对每一个磁盘卷而不是针对整个磁盘来构造设备堆栈。由于windows文件系统驱动会生成控制设备对象CDO和卷设备对象VDO两种设备对象,所以文件系统过滤驱动就有两种对应的过滤设备对象(FiDO)。另外,文件系统过滤驱动也有它自己的控制设备对象CDO,并不附着到任何设备对象上,只是起到一些控制功能,需要处理的IRP(I/O请求包)也会有所不同。因此,一个文件系统过滤驱动相应地包括了三种设备对象。不同版本的windows操作系统,同一设备的设备堆栈对同一IRP的处理在细节上有很多不同,这点我们需要根据不同的系统进行处理。下面以windows XP为例对硬盘文档加密系统进行一些探讨。
2.如何实现数据加解密
数据加解密的实现在针对卷设备对象的过滤设备对象中来处理。有一些实际的问题需要考虑,列举如下:
(1)到底对什么文件进行加密?
并不是对所有读写请求中的数据进行加密,例如不应该对系统文件加密,也不能对根目录区进行加密,否则会出现一系列问题。因此需要在加密之前对操作的文件对象进行判断,选择性的进行加密。这可以通过文件全路径来进行区分。而需要加解密的文件全路径存放在一个特殊的文件里,通过后面在文件系统过滤驱动里实现的文件访问控制来使该文件不能被除了该文件系统过滤驱动以外的任何程序访问到。这个特殊文件的内容在过滤驱动加载时即会加载一份到权限表缓冲里。
(2)如何获取数据内容?
要对数据进行加密,就需要先获得数据的位置和内容,我们不可能直接对磁盘扇区直接操作,因此需要通过window底下的自定义文件系统驱动获得。XP中Cache管理部分导致在文件系统或者文件系统过滤驱动程序中,读和写操作分为几种不同的类型:Cached I/O、Non-cached user I/O、Paging I/O。我们可以直接对缓存中的数据进行加密吗?比如数据更新的发生,文件读写的发生,都会直接造成数据的改变,因此对缓存中的数据加密会带来不少人品问题。所以我们要选用Non-cached user I/O和Paging I/O两种方式下,因为无论如何最后数据都肯定通过这两种方式写到硬盘上。这样的结果就是:硬盘上的文件数据始终是密文,而缓存中的数据始终是明文。当用一个应用程序把明文读出来后,明文就一直存在缓冲里,其他程序读时也能看到明文,能把明文拷贝出去,会成为一个安全问题。解决该问题的方法之一是在关闭文件的时候对缓存进行清空处理。这两种方式下的数据内容可以在IRP中的MdlAddress结构或者UserBuffer结构中取得。此外,为了解决这个问题,也可以通过自旋锁的一些设置来解决。
(3)加密算法及其密钥处理
对于每一个文件的读写,文件系统会产生很多个IRP_MJ_READ请求或者IRP_MJ_WRITE请求,数据也被分成了很多块。同时由于windows读文件不一定是顺序的, 加密的时候通过IRP中的Write.Length获取明文长度,如果不够分组整数倍用全0填充。不过值得注意的是如果在某个IRP中处理的是文件的最后一块分页,写成功的长度IoStatus.Information通常会小于IRP请求的长度Write.Length,这时候再用Write.Length来作为参考进行分组加密的话就会出问题,需要进行特殊处理。在IRP_MJ_READ请求中解密的时候则不存在这个问题可以每次都按照返回的长度即IoStatus.Information来进行解密。基于以上要点规则,在文件系统过滤驱动的IRP_MJ_WRITE分派函数进行加密的流程如下:
1)判断IRP的读写方式,只处理以下几种IRP_NOCACHE、IRP_PAGING_IO和IRP_SYNCHRONOUS_PAGING_IO;
2)读取文件路径和类型决定是否需要进行加密,不需要则直接把IRP往下层传,否则执行加密;
3)得到Windows传下来的数据缓冲地址,在内核中分配连续的页作为一个新的缓冲区保存数据;
4)用AES对新的缓冲区中的数据加密;
5)设置完成例程,并将IRP原来的参数作为完成函数下文环境变量;
6)调用IoCallDriver把密文向下层驱动传,写入硬盘;
7)在完成例程中设置IRP的MdlAddress及UserBuffer,成功。
解密过程与此相同,现在还有一个问题,如何来保存AES算法的密钥?在底层微软是没有提供加密算法的密钥容器的。这里有一种方法,可以使用动态密钥,而且可以将此密钥放在硬盘上面。使用一个RSA公钥对动态AES密钥进行加密,再使用时候利用私钥进行解密,获得对称密钥。而这个可以使用微软的CryptoAPI和一个USBKEY,私钥就在USBKEY上,我们只要一个USBKEY就够了,也就是银行里面使用的办法,当然我们还可以使用数字签名的方法。有朋友会问,那为什么不直接使用RSA或者ECC加密数据呢?那样会造成在飞机跑道上开拖拉机的后果,速度非常慢。
4 Hook一些IRP,实现对文件的进一步控制。
实现这些目的的关键在于Hook文件系统驱动的一些函数,从IRP中解析出各种目录操作,然后根据操作系统的不同设置返回值将其拦截即可。并可同时进行日志记录。创建文件和打开一个文件都于IRP_MJ_Create,所以这里需要区别一下新建文件和文件。当创建一个文件的时候,系统会首先发送一个标FILE_OPEN的请求,并且判断底层文件系统的返回值,返回成功,则表明文件存在并且已经成功打开,否则如返回结果是NO SUCH FILE,则紧接着创建一个E_OPEN_IF请求,得以将文件创建,所以如果在MJ_Create的Options域当中发现了FILE_CREATE,E_OPEN_IF或者FILE_OVERWRITE_IF的三个标志之一,则是在创建否则就是打开。
(2)如果获取的IRP为IRP_MJ_SET_INFORMATION,获取与该IRP关联的IO_STACK_LOCATION结构指针IrpSp(该结构中包含了该IRP的类型代码和参数信息以及完成函数的地址),然后取出irpSp->Parameters.SetFile.FileInformationClass,若与FileDispositionInformation相等则为删除操作,若与FileRenameInformation相等则是文件重命名操作。
(3)防止拷到U盘之类的方法是查询该新增卷的设备类型, FILE_REMOVABLE_MEDIA则为移动存储产生。得到类型以后保存到该卷的过滤设备对象中。当该过滤设备对象得到一个写请求的IRP时即可判断是否在将文件拷贝U盘,接下来就是禁止或者允许。

 

文件系统过滤驱动加密产品,顾名思义是在文件系统过滤驱动中进行透明的加解密,即在应用程序打开文件进行读写操作的过程中进行解密和加密,文件系统过滤驱动在磁盘驱动之上。其具体产品形态,主要是目前流行的透明加解密的文档安全产品。

文件系统过滤驱动加密的优点:
1、与传统的加密工具(如加密文件柜)相比,加解密过程是透明的。这样带来的好处是:
1)文档从产生的第一时刻就是自动加密的,避免作者在编写过程中有意或无意地留下明文,或者后续处理者解密后有意或无意地留下明文,加密带有一定的强制性。
2)加解密过程对用户透明,这样就不需要用户学习如何进行文件加解密。
2、与全盘加密相比,文件系统过滤驱动加密产品通常限定特定进程或文件类型的文件操作才透明加解密;不期望的文件操作,例如用户主动把文件拷贝到USB盘、作为邮件附件发送或者远程用户通过文件共享拷走文件、黑客攻破系统后拷走文件等,将得到的是密文。
3、与全盘加密相比,文件系统过滤驱动加密产品原则上能够支持多用户。

透明加密解密的缺点:
1、因为文件系统过滤驱动之上,合法应用程序得到的文件内容是明文,为了防止这些明文通过各种方式“溜走”,就需要对各种可能输出明文的途径进行“封堵”。这些途径按照是否需要编程分为两大类:
1)不需要编程的,利用应用程序已有的功能或者操作系统的功能,例如内容拷贝、鼠标拖拽复制、打印、邮件发送、第三方软件插件、屏幕录制等等。
2)需要编程的,例如内存读取、API Hook挂接、窗口消息、定制插件等等。
总的来说,各种途径众多,防不胜防。各种产品或多或少堵住了其中一些,很难做到万无一失。
2、与传统的加密工具(如加密文件柜)相比,文件系统过滤驱动加密产品对特定类型的文件进行透明加解密,而不是根据文件是否涉密。假设涉密文件是少数,不涉密文件是多数,这将导致大量的非涉密文件被加密,带来很大的管理负担。如果再考虑解密带出的环节,少量的涉密文件与大量的非涉密文件都要求进行带出审批,这种管理负担就极易产生安全漏洞。
3、文件系统过滤驱动加密产品通常依赖于操作系统的身份鉴别机制,对于通过操作系统认证的用户均进行透明加解密,所以操作系统在身份鉴别上的漏洞也就成了文件系统过滤驱动加密产品的漏洞(众所周知Windows的身份鉴别很容易被突破)。
例如,笔记本电脑丢失的案例,文件系统过滤驱动加密产品对于从其它系统启动试图窃取硬盘上的数据(如把被保护的硬盘挂到其它机器或者从光驱启动)提供了较好保护,但是窃贼可以有N种方法破解或者置空用户密码而直接进入系统,然后该用户的所有密文将对他透明解密。
4、与第3条类似的是,操作系统在其它方面的漏洞也可能对文件系统过滤驱动加密产品形成致命的破坏。
例如,黑客攻破系统的案例,虽然他直接拷贝出去的是密文,但是他控制系统权限后进行远程控制,在被攻击主机上本地打开文件,密文将对他透明解密。如果黑客再在本地主机上进行屏幕录制,就可以把明文转移出去了。

你可能感兴趣的:(VC++编程技术,VisualC++信息安全编程)