龙蜥白皮书精选:基于 SM4 算法的文件加密(fscrypt)实践

Posted OpenAnolis小助手

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了龙蜥白皮书精选:基于 SM4 算法的文件加密(fscrypt)实践相关的知识,希望对你有一定的参考价值。

文/张天佳

通常我们会以文件作为数据载体,使用磁盘,USB 闪存,SD 卡等存储介质进行数据存储,即便数据已经离线存储,仍然不能保证该存储介质不会丢失,如果丢失那么对于我们来说有可能是灾难性的事件。因此对这些离线存储的重要数据文件进行加密是非常有必要的,本节将介绍如何使用国密算法加密文件系统中的文件。

01  fscrypt 简介

内核中的 fscrypt 是一个库,文件系统可以使用它以支持文件和目录的透明加密。

与 dm-crypt 不同,fscrypt 在文件系统级别而不是块设备级别运行。这允许它使用不同的密钥加密不同的文件,并在同一文件系统上拥有未加密的文件。这对于多用户系统非常有用,在该系统中,每个用户的静态数据都需要与其他用户进行加密隔离。除了文件名,fscrypt 不加密文件系统的元数据。

与作为栈式文件系统的 eCryptfs 不同,fscrypt 是直接集成到支持的文件系统中,目前支持 fscrypt 的文件系统是 ext4、F2FS 和 UBIFS。fscrypt 允许读取和写入加密文件,而无需在页面缓存中同时缓存解密和加密页面,从而将使用的内存几乎减半并使其与未加密文件保持一致。同样,需要一半的 dentry 和 inode。eCryptfs 还将加密文件名限制为 143 字节,从而导致应用程序兼容性问题;fscrypt 允许完整的 255 个字节 (NAME_MAX)长度的文件名。最后,与 eCryptfs 不同,fscrypt API 可以由非特权用户使用,而无需依赖其它任何组件。

fscrypt 不支持就地加密文件。相反,它支持将空目录标记为已加密。然后,在用户空间提供密钥后,在该目录树中创建的所有常规文件、目录和符号链接都将被透明地加密。

02  支持的加密模式和用法

fscrypt 允许为文件内容指定一种加密模式,为文件名指定一种加密模式。不同的目录树允许使用不同的加密方式。目前支持以下几种加密方式对:

  • AES-256-XTS 算法用于加密内容,AES-256-CTS-CBC 算法用于加密文件名

  • AES-128-CBC 算法用于加密内容,AES-128-CTS-CBC 算法用于加密文件名

  • Adiantum 算法同时用于加密文件内容和文件名

  • AES-256-XTS 算法用于加密内容,AES-256-HCTR2 算法用于加密文件名(仅限 v2 策略)

  • SM4-XTS 算法用于加密内容,SM4-CTS-CBC 算法用于加密文件名(仅限 v2 策略)

AES-128-CBC 仅为具有不支持 XTS 模式的加速器的低功耗嵌入式设备使用。要使用 AES-128-CBC,必须启用 CONFIG_CRYPTO_ESSIV 和 CONFIG_CRYPTO_SHA256(或其他 SHA-256 实现)以便使用 ESSIV。

Adiantum 是一种基于流密码的模式,即使在没有专用加密指令的 CPU 上也很快。与 XTS 不同,它也是真正的宽块模式。要使用 Adiantum,必须启用 CONFIG_CRYPTO_ADIANTUM。此外,应启用 ChaCha 和 NHPoly1305 的快速实现,例如 ARM 架构上的 CONFIG_CRYPTO_CHACHA20_NEON 和 CONFIG_CRYPTO_NHPOLY1305_NEON。

AES-256-HCTR2 是另一种真正的宽块加密模式,旨在用于具有专用加密指令的 CPU。AES-256-HCTR2 具有明文中的位翻转会更改整个密文的属性。由于初始化向量在目录中重复使用,因此此属性使其成为文件名加密的理想选择。要使用 AES-256-HCTR2,必须启用 CONFIG_CRYPTO_HCTR2。此外,应启用 XCTR 和 POLYVAL 的快速实现,例如 用于 ARM64 的 CRYPTO_POLYVAL_ARM64_CE 和 CRYPTO_AES_ARM64_CE_BLK。

最后是 SM4 算法,目前仅在 fscrypt v2 策略中启用。

03  使用 SM4 算法加密文件

🟢 准备工作

fscrypt 依赖内核配置 CONFIG_FS_ENCRYPTION=y,这里操作系统选择使用 ANCK 5.10 内核的 Anolis OS,其次,需要支持 fscrypt 特性的文件系统,这里以 ext4 为例,当然,F2FS 或者 UBIFS 也可以。

用户空间是通过 fscrypt API 跟内核完成交互的,对于用户来说,一般是通过 fscryptctl 或者 fscrypt 工具来下达加密策略。

本节内容以 fscryptctl(https://github.com/google/fscryptctl) 工具为例来演示,目前这是一个第三方工具,需要手工安装,按如下常规流程安装:

git clone https://github.com/google/fscryptctl.git

cd fscryptctl

make

make install

其次,选择一块未用到的磁盘格式化为支持 fscrypt 的文件系统 ext4,并挂载。

mkfs.ext4 -O encrypt /dev/vda3

mount /dev/vda3 /mnt

🟢 透明加密文件

fscrypt 所用的加解密钥是关联在超级块上的,运行时是跟挂载点相关联的,添加删除密钥都是针对挂载点的操作,以下对密钥操作的命令都会带上挂载点。

按如下命令所示设置加密策略:

# 生成密钥文件,实际环境中应用使用更复杂的密钥
> echo '1234567812345678' > /tmp/keyfile

# 添加该密钥到文件系统,返回密钥ID,之后对密钥的操作都使用这个ID来索引
> fscryptctl add_key /mnt < /tmp/keyfile
23086a13ed81fd75ca5fe9b8f2ff25c7

# 查看密钥状态(不是必需)
> fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt
Present (user_count=1, added_by_self)

# 创建加密目录 endir,并设置加密策略
# 使用之前添加的密钥和 SM4 算法来加密该目录中的文件和子目录
> mkdir /mnt/endir
> fscryptctl set_policy --contents=SM4-XTS \\
        --filenames=SM4-CTS 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt/endir

# 查看策略是否生效(不是必需)
> fscryptctl get_policy /mnt/endir
Encryption policy for /mnt/endir:
    Policy version: 2
    Master key identifier: 23086a13ed81fd75ca5fe9b8f2ff25c7
    Contents encryption mode: SM4-XTS
    Filenames encryption mode: SM4-CTS
    Flags: PAD_32

此时,endir 已经是支持透明加解密的一个目录,可以像正常目录一样创建删除文件,在该目录下进行一些常规的文件操作,可以看到与普通目录没有区别:

> mkdir /mnt/endir/foo
> echo 'hello' > /mnt/endir/foo/hello

> cp -v /usr/include/curl/* endir
> tree /mnt/endir
/mnt/endir
├── curl.h
├── easy.h
├── foo
│   └── hello
└── websockets.h

🟢 锁定加密目录

之所以能像普通目录一样操作,是因为密钥已经被添加到了文件系统中。接下来删除密钥后,就能看到目录被锁定,里面的所有路径和内容都是加密状态:

# 移除密钥
> fscryptctl remove_key 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt

> fscryptctl key_status 23086a13ed81fd75ca5fe9b8f2ff25c7 /mnt
Absent

# 处于加密状态的目录树
> tree /mnt/endir
/mnt/endir
├── 1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw
├── LvYw6Jl0a1jImKKOFPjtpG3hEDxjjuM6YIYqcMeXaWdzKUdaX0YCNQ
├── QBBz8_qGE4MJY6YVzfqVUkr6YeCSqtoQmbvG04BsR0lAr2oLwO0b2g
│   └── wOYdFlMRACjeBa-eSo3LuO4sE55q1YuFv-S_lVU-n498jdMjAt06JA
└── zoiobWxVG2DLjg8uMXfsVP11159zqQUjozJ8gmt1zyjayJlZ4awOhA

# 目录被锁定,无法进行常规文件操作,即便拔盘,也不能得到明文内容
> cat /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw
cat: /mnt/endir/1H2e0BbS4MGZKAKEu6NVXniaYMWIrWDwbyzX6EVEWEN8tfWcWNgDyw: Required key not available
> mkdir /mnt/endir/hello
mkdir: cannot create directory ‘/mnt/endir/hello’: Required key not available

🟢 再次解锁加密目录

要解锁目录也很简单,重新添加密钥即可,文件系统会搜索到正确的密钥并解锁相应目录:

> fscryptctl add_key /mnt < /tmp/keyfile
23086a13ed81fd75ca5fe9b8f2ff25c7

# 添加密钥后文件内容可正常访问
> cat /mnt/endir/foo/hello
hello

04  后记

fscryptctl 是一个相对原生的工具,更接近内核,可以看到,该工具命令比较复杂,使用中需要记住很长一串密钥 ID,用户体验并不好。

实际环境中,一般会使用 fscrypt 工具来完成加密策略操作,该工具由 Google 开发,用 Go 语言写成,通过在用户层面维护了一些元数据来简化用户操作,命令更易于理解,也更接近用户。

商密软件栈 SIG 主页:

https://openanolis.cn/sig/crypto

附:商用密码技术最佳实践白皮书

https://openanolis.cn/shangmi

—— 完 ——

国密算法

算法分类

国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

SM2算法

SM2算法:SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高
学习sm2算法,首先学习ECC算法
ECC算法描述:
  1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G。
  2、用户A选择一个私有密钥k,并生成公开密钥(公钥PB)K=kG。
  3、用户A将Ep(a,b)和点(公钥)K,G传给用户B。
  4、用户B接到信息后 ,将待传输的明文(M)编码到Ep(a,b)上一点M,并产生一个随机整数r(r<n)。加密开始
  5、用户B计算点C1=M+rK;C2=rG。
  6、用户B将C1、C2传给用户A。
  7、用户A接到信息后,计算C1-kC2,结果就是点M。因为C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
  再对点M进行解码就可以得到明文。
  密码学中,描述一条Fp上的椭圆曲线,常用到六个参量:
  T=(p,a,b,G,n,h)。
  (p 、a 、b 用来确定一条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分)
  这几个参量取值的选择,直接影响了加密的安全性。参量值一般要求满足以下几个条件:
  1、p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一般安全要求;
  2、p≠n×h;
  3、pt≠1 (mod n),1≤t<20;
  4、4a3+27b2≠0 (mod p);
  5、n 为素数;
  6、h≤4。
所以关于sm2算法的流程如图
技术分享图片
SM2算法就是ECC椭圆曲线密码机制,但在签名、密钥交换方面不同于ECDSA、ECDH等国际标准,而是采取了更为安全的机制。另外,SM2推荐了一条256位的曲线作为标准曲线。
SM2标准包括总则,数字签名算法,密钥交换协议,公钥加密算法四个部分,并在每个部分的附录详细说明了实现的相关细节及示例。
SM2算法主要考虑素域Fp和F2m上的椭圆曲线,分别介绍了这两类域的表示,运算,以及域上的椭圆曲线的点的表示,运算和多倍点计算算法。然后介绍了编程语言中的数据转换,包括整数和字节串,字节串和比特串,域元素和比特串,域元素和整数,点和字节串之间的数据转换规则。
详细说明了有限域上椭圆曲线的参数生成以及验证,椭圆曲线的参数包括有限域的选取,椭圆曲线方程参数,椭圆曲线群基点的选取等,并给出了选取的标准以便于验证。最后给椭圆曲线上密钥对的生成以及公钥的验证,用户的密钥对为(s,sP),其中s为用户的私钥,sP为用户的公钥,由于离散对数问题从sP难以得到s,并针对素域和二元扩域给出了密钥对生成细节和验证方式。总则中的知识也适用于SM9算法。
在总则的基础上给出了数字签名算法(包括数字签名生成算法和验证算法),密钥交换协议以及公钥加密算法(包括加密算法和解密算法),并在每个部分给出了算法描述,算法流程和相关示例。
数字签名算法,密钥交换协议以及公钥加密算法都使用了国家密管理局批准的SM3密码杂凑算法和随机数发生器。数字签名算法,密钥交换协议以及公钥加密算法根据总则来选取有限域和椭圆曲线,并生成密钥对。
SM2算法在很多方面都优于RSA算法(RSA发展得早应用普遍,SM2领先也很自然),与RSA安全性对比如下图
技术分享图片

SM3算法

SM3算法:SM3杂凑算法是我国自主设计的密码杂凑算法,适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。为了保证杂凑算法的安全性,其产生的杂凑值的长度不应太短,例如MD5输出128比特杂凑值,输出长度太短,影响其安全性SHA-1算法的输出长度为160比特,SM3算法的输出长度为256比特,因此SM3算法的安全性要高于MD5算法和SHA-1算法。
对长度为l(l<2^64)比特的消息m,SM3杂凑算法经过填充和迭代压缩,生成杂凑值,杂凑值长度为256比特。
假设消息m的长度为l比特。首先将比特“1”添加到消息的末尾,再添加k个“0”,k是满足l+1+k448mod512的最小的非负整数。然后再添加一个64位比特串,该比特串是长度l的二进制表示。
填充后的消息m′的比特长度为512的倍数。
例如:对消息01100001 01100010 01100011,其长度l=24,经填充得到比特串:
01100001 01100010 01100011 1 00...00(423比特)00...011000(64比特l的二进制表示)
下面的是实现了SM3的标准输出
技术分享图片

SM4

此算法是一个分组算法,用于无线局域网产品。该算法的分组长度为128比特,密钥长度为128比特。加密算法与密钥扩展算法都采用32轮非线性迭代结构。解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
此算法采用非线性迭代结构,每次迭代由一个轮函数给出,其中轮函数由一个非线性变换和线性变换复合而成,非线性变换由S盒所给出。其中rki为轮密钥,合成置换T组成轮函数。轮密钥的产生与上图流程类似,由加密密钥作为输入生成,轮函数中的线性变换不同,还有些参数的区别。
过程:
技术分享图片
基本运算:SM4密码算法使用模2加和循环移位作为基本运算。
  基本密码部件:SM4密码算法使用了S盒、非线性变换τ、线性变换部件L、合成变换T基本密码部件。
  轮函数:SM4密码算法采用对基本轮函数进行迭代的结构。利用上述基本密码部件,便可构成轮函数。SM4密码算法的轮函数是一种以字为处理单位的密码函数。
  加密算法:SM4密码算法是一个分组算法。数据分组长度为128比特,密钥长度为128比特。加密算法采用32轮迭代结构,每轮使用一个轮密钥。
  解密算法:SM4密码算法是对合运算,因此解密算法与加密算法的结构相同,只是轮密铝的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
  密钥扩展算法:SM4密码算法使用128位的加密密钥,并采用32轮法代加密结构,每一轮加密使用一个32位的轮密钥,共使用32个轮密钥。因此需要使用密钥扩展算法,从加密密钥产生出32个轮密钥。
  SM4的安全性:SM4密码算法经过我国专业密码机构的充分分析测试,可以抵抗差分攻击、线性攻击等现有攻击,因此是安全的。
SM4实例:
技术分享图片






















































以上是关于龙蜥白皮书精选:基于 SM4 算法的文件加密(fscrypt)实践的主要内容,如果未能解决你的问题,请参考以下文章

国密SM4算法加密解密实现以及与Spring Security集成实现

SM4算法的长数据加密——第二部分

国密SM4分组密码算法(对称加密)的JS和JAVA类库

[密码学]:SM4

龙蜥 Node.js/WebAssembly SIG 重磅发布 Node.js/Noslate 性能优化白皮书

密码算法(SM1SM2SM3SM4同态加密密态计算隐私计算和安全多方计算)