原标题:Linux加解密支持模块代码总体描述
1.3.4. Linux内核对加密的特性支持分析Linux内核加密特性,就要要根据不同算法所表现出来的特征进行总结。以下通过分组密码、Hash函数、随机数生成器、压缩算法分别进行说明并总结出内核在支持加密方面的特性支持。1.3.4.1.分组密码
分组密码是一种对称密码体制。它的特点是将明文分成多个等长的组,并用相同的密码算法和密钥对各组消息分别进行加密和解密。分组密码应用领域从电子邮件加密到银行交易转帐,非常广泛。
扩散(diffusion)和混淆(confusion)是影响密码安全的主要因素[3]。扩散的目的是让明文中的单个数字影响密文中的多个数字,从而使明文的统计特征在密文中消失,相当于明文的统计结构被扩散。混淆是指使密钥与密文之间的统计关系变得尽可能复杂,从而增加通过统计方法进行攻击的难度。
设计安全的分组加密算法,就要能够抵御差分分析方法和对加密轮数的设置。用软件实现的分组加密要保证每个分组的长度适合软件编程(如8、16、32……),尽量避免置换操作,以及使用加法、乘法、移位等处理器提供的标准指令;从硬件实现的角度,加密和解密要在同一个器件上都可以实现,即加密解密硬件实现的相似性[4]。
内核里面常见的ablkcipher异步分组密码算法、blkcipher分组密码算法、aead认证加密算法都使用了分组密码进行加密,既然都使用了分组密码,每种算法对应的分组长度等特征见表1-2。
表1-2分组算法的特征
加密算法
分组长度函数
加解密函数
ablkcipher
crypto_ablkcipher_blocksize()
crypto_ablkcipher_encrypt()
crypto_ablkcipher_decrypt()
blkcipher
crypto_blkcipher_blocksize()
crypto_blkcipher_encrypt()
crypto_blkcipher_decrypt()
aead
crypto_aead_blocksize()
crypto_aead_encrypt()
crypto_aead_decrypt()
上表中出现的加密函数的实现都是通过crypto_xxx_encrypto()调用crypto_xxx_crt()创 建一个xxx_tfm对象,然后调用xxx_tfm中的钩子函数encrypt(),最后都落实到crypto_tfm对象中。解密的过程和加密调用过程类似。从上面的加解密过程可以看出,算法的加解密实现最终回归到结构体crypto_tfm中成员的操作上,这种统一性有助于算法的扩展。(上文提到的xxx为具体的一种算法名称)。
另外与体系架构相关的算法加解密实现是不一样的,在X86中,AES的加解密是以汇编形式实现的,这就可以看出,这类算法的实现是通过硬件支持实现的。在硬件实现加密时会出现alignmask对齐掩码的概念,在之前的分析中了解到算法上下文的分配是通过密码管理器实现的,密码管理器在分配ctx内存的时候,需要为其进行内存对齐。不同的硬件加密或其他特殊要求的算法,ctx的首地址需要在内存中以多字节形式进行对齐。
下面列举出分组密码中常见的2中算法的一些特性:
在include/crypto/des.h中,DES分组密码的一些基本信息:
#define DES_KEY_SIZE 8
#define DES_EXPKEY_WORDS 32
#define DES_BLOCK_SIZE 8
可以看出,DES密钥长度为64位,密钥可以扩展到128位,分组大小为64位。
DES的加密轮数为16轮。也可以通过cat /proc/crypto查看插入到内核的一些算法特征。
在include/crypto/aes.h中,AES分组密码的一些基本信息:
#define AES_MIN_KEY_SIZE 16
#define AES_MAX_KEY_SIZE 32
#define AES_KEYSIZE_128 16
#define AES_KEYSIZE_192 24
#define AES_KEYSIZE_256 32
#define AES_BLOCK_SIZE 16
可以看出,AES的分组长度为128位,最小密钥长度为128位,最大密钥长度为256位。也就是说128位分组长度的算法,可以支持128、192、256位长度的密钥。
Crypto/aes_generic.c中传统的AES加密采用的加密轮数为10轮:rco_tab[10]。
1.3.4.2.Hash函数
Hash函数可以将任意长度的消息序列映射为较短的且长度固定的函数。常用的MD4对输入消息产生128位的消息摘要;MD5以512位的分组长度处理消息,产生128位的消息摘要;SHA-1以512位的分组长度处理消息,产生160位的消息摘要。
密码学中的hash函数能够保证数据的完整性。对于Hash函数来说,不同的输入可以有相同的输出,也就是说不能通过输出来判断输入的惟一性。
在安全领域应用Hash函数,通常采用三个问题来对Hash函数进行判断。如果三个问题都是难解的,则认为该hash函数是安全的。
其中X为消息集合,Y表示消息摘要集合。
1. 原像问题(Preimage Problem):设H:X→Y是一个Hash函数,y∈Y。是否能够找到,x∈X使得H(x)=y。
2. 第二原像问题(Second Preimage Problem):设H:X→Y是一个Hash函数,x∈X。是否能够找到x′∈X,使得x′≠x,并且H(x′)=H(x)。
3. 碰撞问题(Collision Problem):设H:X→Y是一个Hash函数。是否能够找到x,x′∈X,使得x′≠x,并且H(x′)=H(x)。
Hash算法的特性可以归纳如下:
1. Hash算法能够用于任何大小的数据分组。
2. Hash算法产生定长的输出。
3. 对任意给定的消息x,hash算法H(x)要易于计算,便于软件和硬件实现。
4. 对任意给定的消息摘要y,寻找x使得y=H(x)在计算上是不可行的。
5. 对任意给定的消息x,寻找x′,x′≠x,使得H(x′)=H(x)在计算上是不可行的。
6. 寻找任意的(x,x′),使得H(x′)=H(x)在计算上是不可行的。
1.3.4.3.随机数产生器
随机数产生器在密码学中用密钥流来对明文进行加密,这种加密方式在密码学中称为流密码(Stream Cipher),流密码每次只对明文中的单个位或字节进行加密,是一种对称密码体制。主要用于军事、外交场合使用。
1.3.4.4.压缩算法
压缩算法是一种按照一定编码机制用比未编码少的数据比特表示信息的过程。算法应用于网络通信、节约磁盘空间、消息传输等领域。这里要注意,传输消息时发送方和接收方要使用相同的编码机制对消息进行压缩和解压缩,否则压缩就没有意义。
压缩算法的主要操作是压缩和解压缩操作,即crypto_compress( ),该函数最终调用的是算法操作集compress_alg中的(*coa_compress)()钩子函数,解压缩调用过程和压缩的调用一样。
在Linux内核压缩算法使用zlib函数库,应用于Linux网络数据压缩、开机时解压缩自身的核心;Apache的http 1.1;OpenSSH、OpenSSL加密网络传输;Subversion、Git和CVS等版本控制器与远端仓库的通信流量压缩等等。
从上面分析可以得到,Linux内核对加密算法的特性支持主要表现在以下几个方面,见表1-3。
表1-3 linux内核对加密算法的特性支持
特性
表现作用
分组大小
内核加密算法很多是以分组算法进行消息加密
密钥大小
不论公钥加密还是对称加密都涉及密钥
对其掩码
用于不同体系结构的平台
算法类型
表明算法属于哪一类
摘要长度
对于hash算法,就要涉及消息摘要
加解密函数
加解密函数是加密算法的核心操作
从表1-3可以看出,Linux内核对加密算法的特性支持完全可以从算法注册数据结构crypto_alg里面的成员变量体现出来。通过对特性进行分析,可以对Linux内核中的算法构成有一个基本的了解。返回搜狐,查看更多
责任编辑: