admin 管理员组

文章数量: 887032


2023年12月17日发(作者:幽梦影视源码)

eCryptfs加密文件系统的概述

eCryptfs(英文:Enterprise Cryptographic Filesystem,企业加密文件系统)从Erez Zadok开发的Cryptfs发展而来,是一种Linux系统下的企业加密文件系统,兼容POSIX文件系统级加密。该加密文件系统是Linux内核2.6.19版本中引入的一个功能强大的企业级加密文件系统(Ubuntu自9.04也开始开始提供eCryptfs包),堆叠在其它文件系统之上(如 Ext2,Ext3,Ext4, ReiserFS,JFS等),为应用程序提供透明、动态、高效和安全的加密功能。eCryptfs默认使用的是AES算法,但是它也支持其它算法,如blowfish、des3、cast5、cast6、md5等。如果是通过手工创建eCryptfs设置,则可以选择其中一种算法。

第一节 加密文件系统的概念及分类

在Linux系统中,基本上有两种不同的方法可以对文件和目录进行加密。一种方法是,文件系统级加密,是对某些文件或目录(比如/home/alice)选择性地加密。这是一种理想的加密方法。文件系统级加密存在一些缺点。比如说,许多现代的应用程序将文件 (或文件的部分内容)缓存在硬盘中的未加密区域,比如交换分区、/tmp和/var文件夹,它们很可能会导致隐私泄密。另一种方法是全磁盘加密,这意味着整个磁盘都经过了加密(主引导记录可能除外)。全磁盘加密在物理磁盘层面实现,写入到磁盘上的每个比特数据都经过了加密,从磁盘读取的任何数据自动实时解密。这可以防止任何人可能未经授权就访问未加密的数据,并且确保整个文件系统里面的所有数据都经过了加密, 包括交换分区或任何临时缓存的数据。

在Linux系统中,文件系统级加密有:(1)EncFS,这是尝试加密的最容易的方法之一。EncFS作为堆叠文件系统来运行,所以你只要创建一个加密的文件夹,将它挂载到文件夹上即可使用。(2)eCryptFS,作为一款与POSIX兼容的加密文件系统,eCryptFS的工作方式与EncFS如出一辙,所以你得挂载它。这也是本文中所用的加密技术。磁盘级加密有:(1)Loop-AES,这是最古老的磁盘加密方法。它运行起来速度很快,可以在旧系统(比如内核2.0分支版本)上使用。(2)DMCrypt,现代Linux内核支持的最常见的磁盘加密方案。(3)CipherShed,这是现已停止开发的TrueCrypt磁盘加密软件的开源分支版本。

文件系统级加密相对磁盘加密既有优点也有不足。磁盘加密工作在块(block)级别,要求另外的文件系统加载到自己的分区上,文件系统级加密能在已存在的分区中工作,不需要划开特定块区域(block area)供其使用。同时也可以选择性的加密单个文件或文件夹。

一、加密文件系统的概念

加密文件系统是指将加密服务和文件系统集成在一起来为数据提供保护,经过对称秘钥算法加密的文件内容以密文的形式存储在物理介质上,如果文件被窃取或者丢失,只要在未泄露加密秘钥的情况下,没有授权的用户是无法破解密文获得文件的明文,确保了数据的高安全性。与此同时,授权用户对加密文件的访问则非常方便。用户通过初始身份认证后,对加密文件的访问和普通文件没有什么区别,就好像该文件并没有被加密过,这是由于相关的加密和解密的工作被加密文件系统在后台自动地完成了了。加密文件系统一般工作在内核态,这样使得普通的攻击难以奏效。

二、加密文件系统的分类

加密文件系统基本上可以分为两大类,两类的实现方式和目标都有比较大的区别。一类是面向网络存储服务的,通常是基于 NFS 客户/服务器模型,通常称为网络加密文件系统。在网络加密文件系统中,数据以密文的方式保存在网络文件系统中,用户通过客户机服务进程与网络文件服务器交互,网络文件服务器负责将用户请求的密文传递到客户机服务进程,由客户机服务进程进行解密再交给应用程序。在这个模型中,只要求客户机操作系统是可信的, 而网络服务器由于不接触明文数据,不要求其可信。另一类是本地加密文件系统,密文数据直接存放在本地物理介质上(硬盘,U盘等),由操作系统或服务进程完成数据的读取、加密/解密工作。本地加密文件系统的目标是应对存储介质失窃的威胁,安全模型同样把加密文件系统所在的操作系统视为可信的。

本地加密文件系统又可以细分为两种,一种是在原有的普通文件系统上直接加入加密功能,如 Reiser4,但是现有的 Ext2, Ext3 等常用文件系统并不支持加密功能,因此用户不得不转换整个文件系统;另一种被称为堆叠式加密文件系统(Stackable Cryptographic File

System)。这种加密文件系统可以看成一个加密/解密的转换层,而并不是一个真实的全功能文件系统。堆叠式加密文件系统没有相应的磁盘布局,也不实现 数据在物理介质上存取的功能。它必须架构在别的普通文件系统之上,读加密文件时先通过下层普通文件系统将文件的密文读入内存,解密后再将明文返回到上层的 用户进程;写加密文件时先将内存中的明文加密,然后传给下层普通文件系统,由它们真正地写入物理介质。堆叠式加密文件的优势在于实现相对容易(因为功能相对简单)且用户可以任意选择下层的普通文件系统来存放加密文件。本文讨论的 eCryptfs 属于本地堆叠式加密文件系统的范畴。

第二节 eCryptfs加密文件系统的特点

eCryptfs加密文件系统是建立在已存在的文件系统之上的Stack,只处理数据的加解密,对于应用程序来说是透明的;具有高级密匙管理和政策的特征;兼容性好,文件的加密元数据与文件一起存储,将加密元数据存储在每一份被操作的文件头中,使得加密文件和普通文件一样,可以在不同主机间的传输,不同存储之间的拷贝,而不要其他附属信息;用户对于加密文件夹的操作是无缝的,和操作正常的文件是一样的;加密级别高,即使硬盘被盗,只要秘钥没有泄露,那么硬盘内的资料也不会泄露;由于是基于Linux内核的,所以与系统的整合性高,整体的安全性也要高于普通软件;易于部署,以模块的形式加载,不需要修改Linux内核的其他部分;易于使用,用户执行mount命令挂载后,就可以透明的使用加解密存储服务。

第三节 eCryptfs加密文件系统的架构

eCryptfs分为内核层部分和用户层部分。内核层仅仅用作数据的加密和解密操作,位于虚拟文件系统与物理文件系统的中间,调用内核密码接口对数据进行加解密,然后继续将虚拟文件系统的操作传递给物理文件系统。加密和解密对用户应用程序是透明的,因为它仍旧

使用原有的系统调用来进行文件相关的操作。eCryptfs用户层主要包含负责密钥管理的模块,包括TPM、OpenSSL、GPGME、PAM等模块。eCryptfs通过随机生成一个会话密钥(FEK)来加密文件的内容并将文件内容存储在磁盘上,然后用用户层密钥管理模块生成秘钥(KEK)来加密FEK,最后将加密后的FEK (EFEK)存入文件头部。解密文件内容需先解密EFEK,然后用解密后的EFEK来解密存储在文件的密文。

下图就是eCryptfs加密文件系统的架构图。

图2-1 eCryptfs 加密文件系统的架构

对于密明管理模块制定的策略主要是利用TPM来进行公钥加密和私钥解密,守护进程通过消息数据包与TPM交互,将TPM新生产的密明写入临时的密钥文件中,ecryptfs从临时密钥文件中读取密胡加密生产的会话密钢然后存入文件中。加密文件内容的生成是利用ecryptfs产生的会话密钥加密文件数据然后存入文件。

第四节 eCryptfs加密文件系统的加密原理

1服务,本质上,eCryptFS就像是一个内核版本的Pretty Good Privacy (PGP)插在VFS(虚拟文件系统层)2和下层物理文件系统之间,充当一个“过滤器”的角色。eCryptfs是以一个单个的内核模块来部署的,同时利用一套用户空间的工具来执行key管理,提供的功能3和GnuPG相似,数据的加解密通过调用内核加密API来实现,其过程对用户透明。eCryptfs

1 PGP (Pretty Good Privacy)是一个用于对电子邮件和文件进行加密的软件。用PGP加密(Encrypt)的邮件,看起来就是些无意义的乱码 (RandomCharacters),除了收信人可以看到外,没有其它人可以解读。PGP提供了极强的保护功能,即使是最先进的解码分析技术也很难解读 (Decrypt)加密后的文字。

2 VFS(virtual File System)的作用就是采用标准的Unix系统调用读写位于不同物理介质上的不同文件系统,即为各类文件系统提供了一个统一的操作界面和应用编程接口。 VFS是一个可以让open()、read()、write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层。

3 GnuPG(GNU Privacy Guard或GPG)是一个以GNU通用公共许可证释出的开放源码用于加密或签名的软件,可用来取代PGP。大多数gpg软件仅支持命令行方式,一般人较难掌握。由于gpg软件开放源代码,很难隐藏后门,因此比pgp等商业软件安全。

将文件的加密元数据以包的形式存储在文件头中和文件的内容存储在一起。

一、加密文件数据存储格式

eCryptfs采用OpenPGP的文件格式存放加密文件,将加密文件分成多个逻辑块,每个逻辑块称为 extent。并且将整个文件的数据的加密和解密操作当成一次原子操作,没有部分文件被加密或解密的概念,也不可能将文件的最后一个字节读出而不用将文件的开始至最后的内容全部解密。同样写文件的某一个字节也要将文件的开始至写的位置的全部内容全部加密。当下层文件系统读入一个 extent 中的任何部分的密文时,整个 extent 被读入 Page

Cache,通过 Kernel Crypto API 被解密;当 extent 中的任何部分的明文数据被写回磁盘时,需要加密并写回整个 extent。

ecryptfs文件系统中文件由文件头和数据部分组成,其中头部以包的形式存储了整个加密文件的元数据(加密上下文)。数据部分按extent为最小单元来存储,类似于内存按页来组织。extent的大小可以在内核编泽时指定。也就是说数据的处理是一次一个extent。如果对extent中的一小部分的读或者一小部分的写都会使得整个extent的读入和写出。每个extent都唯一关联一个初始化向量简称。一组连续的初始化向量后总是紧跟随有与之相关的一组extent。当要修改某个extent时,和它相关向量也要被修改并在整个extent加密之前回写它的向量。extent加密用的是基于CBC模式的块加密方式。

二、加解密步骤

eCryptFS只处理数据的加解密,数据的存储交给下层文件系统,实现相对简单。用户应用程序对加密文件的写请求,经系统调用层到达 VFS 层,VFS 转给 eCryptfs 文件系统组件(后面会介绍)处理,处理完毕后,再转给下层物理文件系统;读请求(包括打开文件)流程则相反。

当eCryptfs创建一个文件并对其写时,加解密操作流程如下图所示,

图2-2 eCryptfs 加密/解密操作流程图

具体的加解密步骤如下所述:

第一,用户应用发出对文件系统的写系统调用,该写系统调用首先会通过内核虚拟文件系统层VFS,然后VFS会优先将请求传给eCryptfs层并在其挂载点下进行文件操作,这是因为eCryptfs处于VFS层与底层物理文件系统之间且eCryptfs和底层物理文件系统都注册到了内核。

第二,eCryptfs先使用一种对称密钥加密算法来加密文件的内容,如使用AES-128算法,通过随机生成的FEK(File EncryptionKey)加解密文件数据,且每次只能操作一个extent数据块。文件加密数据块的存储按每个(默认为4K)不大于页大小来组织的,对数据块的加密和解密算法是通过内核加密子系统的API完成的。

第三,由于FEK不能以明文的形式存放,因此eCryptfs使用用户提供的口令(Passphrase)、公开密钥算法(如RSA算法)或TPM (Trusted Platform Module)的公钥来加密保护刚才提及的 FEK。 即eCryptfs将用户态下生成的key用来加密FEK生成EFEK(Encrypted File Encryption Key)。

如果使用用户口令, 则口令先被散列函数处理,然后再使用一种对称密钥算法加密FEK。口令/公钥称为FEFEK(FileEncryption Key Encryption Key),加密后的FEK则称为

EFEK(Encrypted File Encryption Key)。由于允许多个授权用户访问同一个加密文件, 因此EFEK可能有多份。这种综合的方式既保证了加密解密文件数据的速度,又极大地提高了安全性。

第四,把在用户态生成的key链接入内核的链表中,该链表即会话秘钥环(keyring),同时生成一个用户指定或默认计算得到的signature标记key,即key管理程序通过signature与eCryptfs相关联。eCryptfs通过signature从用户的会话秘钥环中获取key来解密从底层文件头中获取的EFEK,利用解密后的FEK来解密底层文件内容。

第五,最后调用文件系统的写操作讲加密后的内容写入到物理磁盘文件系统中。

三、加密文件上下文

对于每个ecryptfs inode都有一个来自底层文件系统的inode和加密上下文与之对应。加密上下文包括会话秘钥(the session key)、文件是否被加密、指向内核加密API的指针、授权记号的标识(The signatures of the authentication tokens)、extent的大小。ecryptfs能在用户的session keyring上缓存加密上下文以加快对授权符号的重复访问,而不用读取底层文件的头部信息来获取加密上下文。

每个文件都能获得一个系统随机生成的会话key,被ecryptfs用来加密文件的内容。ecryptfs将该key缓存在秘钥环中。当一个应用程序关闭一个新文件时,ecryptfs用和文件相关的授权记号(authentication token)按照一定的策略来加密该key,并将加密后的key以包的形式写入底层文件的头部。当一个应用程序打开这个文件时,ecryptfs读取加过密的key,同时ecryptfs通过搜索所有用户的授权记号找到与相应sinature匹配的授权记号,第一个找到的授权记号中的解密key被用來解密加过密会话key。如果用户会话秘明环中没有找到相应的授权记号,那么ecryptfs将通过消息机制来查询PKI模块从而找到相应的私钥或使得用户输入口令。然而对于安全性要求很高的数据一般不建议用基于口令的方式来保护文件,因为用户所能记住的口令是有限的,容易被攻破。对安全性要求高的数据应尽量用TPM和公钥来加密数据,这样能很好的保护数据。

四、eCryptfs与VFS相关的操作

eCryptfs主要与虚拟文件系统VFS相关的操作有mount操作、open操作、以及读写操作等四个操作。其中mount操作主要是在加密文件在挂载时, 需要指定认证特征的参数, 操作成功后,将认证特征存储在内核密钥环中;open操作分为两种情况,当文件已存在时,会请求下层文件系统从文件头部读取EFEK,然后请求解密以获取FEK, 把它保存在inode节点中。当文件不存在时, 会随机生成FEK,然后用KEK加密生成EFEK,保存到文件头部;读操作是用FEK解密从存储介质读取的文件数据;写操作则是用FEK加密数据,然后再写入[8]存储介质。

第五节 eCryptfs加密文件系统的缺点

假设目录 /ecrypt 为 eCryptfs 加密文件系统根目录, 当未正常挂载时, 用户打开该目录下的文件所看到的是一堆乱码,无法获取文件的真实内容。但是当某个用户使用 mount 命令并提供正确的认证特征挂载了该系统时, 不但他可以看到文件的真实内容, 系统的其他用户也可以看到文件的真实内容。

写操作性能比较差。用 iozone 测试 eCryptfs 的性能,发现读操作的开销不算太大,最多降低 29%,有些小文件测试项目反而性能更好;对于写操作,所有测试项目的结果都很差,普遍下降16倍左右。这是因为 Page Cache 里面只存放明文,因此首次数据的读取需要解密操作,后续的读操作没有开销;而每一次写 x 字节的数据,就会涉及 ((x – 1) /

extent_size + 1) * extent_size 字节的加密操作,因此开销比较大。

有两种情况可能造成信息泄漏:a. 当系统内存不足时,Page Cache 中的加密文件的明文页可能会被交换到 swap 区,目前的解决方法是用 dm-crypt 加密 swap 区。b. 应用程序也有可能在读取加密文件后,将其中某些内容以临时文件的方式写入未挂载 eCryptfs 的目录中(比如直接写到 /tmp 中),解决方案是配置应用程序或修改其实现。

eCryptfs 实现的安全性完全依赖于操作系统自身的安全。如果 Linux Kernel 被攻陷,那么黑客可以轻而易举地获得文件的明文,FEK 等重要信息。


本文标签: 加密 文件 数据