最近项目中设计到了如果保证信息不泄露,所以需要对传输的信息进行加密。
因为需要传输信息,发送方和接收方能够实现一方加密,一方解密。所以需要使用可逆的加密算法。
常见的加密方式主要有两种,对称加密,和非对称加密。
对称加密:加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。
非对称加密:加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal。
因为是和外部合作的项目,相对于非对称加密,对称加密实现起来要相对简单,而且更加快速。
双方通过其他方式传递信息,也不会太担心公共密钥泄密的过程。
关于AES加密原理
AES 在密码学中又称Rijndael加密法,是一种区块加密
的方式。
优点: 软件和硬件上都能够快速的加解密,相对来说较容易实现,且只需要很少的内存。
关于区块加密
原因:
加密过程中,待加密的字符串长度越长,加密代价就越大。
通常将明文进行分段,对每段进行加密,然后将所有的拼接成为一个字符串。问题 :
分块加密中需要解决的就是如何填满最后一块分块。因为,最后一块不一定能够填满整个的区块。
如果待加密字符串为abcdefghijklmnopq,这边一共17的字母,对于AES每个区块为128bit,16个字节,那么abc…op前16字节就为一个区块,下面一个区块只有q一个字符。解决方案:
为了保证每个分块是128bit,引入了padding值。用来填充最后一块字符串。对于解密端,也同样需要padding来找到最后一块数据的真实长度。常见的PADDING模式为PKCS5, PKCS7, NOPADDING。
AES为区块密码,分组密码也就是把明文分成一组一组的,每组长度相等,每一次加密一组数据,直到加密完整个明文。在AES标准规范中,区块长度是128bit,也就是每个区块是16个字节。密钥的长度可以使用128bit,192bit或者256bit。密钥的长度不同,推荐加密轮数也不同。(加密轮数就是执行加密算法的次数)
AES | 密钥长度 | 分组长度 | 加密轮数 |
AES-128 | 4 | 4 | 10 |
AES-192 | 6 | 4 | 12 |
AES-256 | 8 | 4 | 14 |
AES的加密公式C=E(K,P),加密函数E中,会执行一个轮函数,并且执行10次(128bit密码长度的推荐次数)这个轮函数,这个轮函数的前9次执行的操作是一样的。
AES的处理单位是字节。128bit的输入明文和输入密钥K都被分为16字节。分别记为
P = P0,P1,P2,P3…….P15和 K = K0,K1,K2,K3…K15。
假设明文其中一个分组为 P = abcdefghijklmnop,其中
字符 | 对应 |
a | P0 |
b | P1 |
… | … |
o | P14 |
p | P15 |
一般来说,明文分组用字节为单位的正方形矩阵描述,称为状态矩阵。在算法每一轮中,状态矩阵中的内容不断发生变化,最后的结果作为密文输出。改矩阵中字节的排列顺序从上到下,从左至右,依次排列,如下图所示
现在假设明文分组P为”abcdefghijklmnop”,则对应上面生成的状态矩阵图如下:
上图中,0x61为字符a的十六进制表示。
AES加密完整流程
轮密钥加
轮密:每一轮加密会有这一轮的密钥,然后将待加密的内容和加密的密钥进行异或处理。当前加密轮的密钥叫做轮密。
首先,轮密钥加首先需要获取当前轮次密钥。
轮次密钥,一共11个分组(根据加密轮数来判断),因为初始加密的时候 需要先进行轮密钥加,然后在进行N轮加密。
所以,如果推荐是10轮加密,那么就是要组成一个10+1的分组组成的序列。这个轮次密钥是怎么获取的呢?
密钥扩展
。
AES加密的第一步骤,密钥扩展,使用初始密钥转换成的W0~W3对明文区块进行加密,然后进行密钥扩展。扩展到44字节。
密钥扩展过程说明:
1) 将初始密钥以列为主,转化为4个32 bits的字,分别记为w[0…3];
2) 按照如下方式,依次求解w[j],其中j是整数并且属于[4,43];
3) 若j%4=0,则w[j]=w[j-4]⊕g(w[j-1]),否则w[j]=w[j-4]⊕w[j-1];
函数g的流程说明:
4) 将w循环左移一个字节;
5) 分别对每个字节按S盒进行映射;
6) 与32 bits的常量(RC[j/4],0,0,0)进行异或,RC是一个一维数组,其值如下。(RC的值只需要有10个,而此处用了11个,实际上RC[0]在运算中没有用到,增加RC[0]是为了便于程序中用数组表示。由于j的最小取值是4,j/4的最小取值则是1,因此不会产生错误。)
RC = {00, 01, 02, 04, 08, 10, 20, 40, 80, 1B, 36}
通过密钥扩展,就可以获得接下来每一轮次加密的密钥。
上图中的K0,K1….K15是初始的密钥,16字节,如果不足,通过Padding补足。K0~K3 组成 W0,K4~K7组成W1,…K12~K15组成W3。
循环处理
循环处理包括: 字节代换(通过AES定义的S盒和逆S盒),行位移(做循环操作),列混合(固定矩阵相乘)
AES加密模式
1.ECB模式
ECB模式(Electronic Codebook Book)是最简单的工作模式,在该模式下,每一个明文块的加密都是完全独立,互不干涉的。
>优点:
1. 简单
2. 有利于并行计算
缺点:
1. 安全性较差 (相同的明文块进过加密会变成相同的密文块)
- CBC模式
CBC模式(Cipher Block Chaining)引入了一个新的概念:初始向量IV(Initialization Vector)。IV是做什么用的呢?它的作用和MD5的“加盐”有些类似,目的是防止同样的明文块始终加密成同样的密文块。流程参考下图CBC 模式在每一个明文块加密前会让明文块和一个值先做异或操作。IV作为初始化变量。参与第一个明文块的异或,后续的每一个明文块和它的前一个明文块所加密的出的密文块相异或。
优点:
1. 安全性高
缺点:
1. 无法进行并行计算
2. 引入初始向量IV,增加加密的复杂度
总结
在使用AES加密的时候 需要考虑的还是下面的:
- 对于加密端,应该包括:加密秘钥长度,秘钥,IV值,加密模式,PADDING方式。
- 对于解密端,应该包括:解密秘钥长度,秘钥,IV值,解密模式,PADDING方式。
参考连接
- AES加密算法的详细介绍和实现
- 理解AES加密解密的使用方法
- 密码算法详解
- java和php通用的AES加密解密
- 十分钟读懂AES加密算法
- 在PHP中使用AES加密算法加密数据