AES加密中列混合的具体算法
2012-03-03 13:40
507 查看
AES明文在加密过程中涉及到字节代换、行移位、列混合、轮密钥加等过程。这里对列混合的算法做出一些浅显的解释。
列混合其实就是对一个状态的每一列去乘一个矩阵,其中乘法是在有限域GF(2^8)内进行的,不可约多项式为x^8+x^4+x^2+x+1如图:
![](http://pic002.cnblogs.com/images/2010/169108/2010103102021588.png)
先把算法代码列出来:
代码:
void AES::MixColumns(unsigned char state[][4]) //列混合
{
unsigned char t[4];
int r,c;
for(c=0; c< 4; c++) //按列处理
{
for(r=0; r<4; r++)
{
t[r] = state[r][c]; //每一列中的每一个字节拷贝到t[r]中
}
for(r=0; r<4; r++)
{
state[r][c] = FFmul(0x02, t[r]) //矩阵计算,其中加法为异或
^ FFmul(0x03, t[(r+1)%4])
^ FFmul(0x01, t[(r+2)%4])
^ FFmul(0x01, t[(r+3)%4]);
}
}
}
unsigned char AES::FFmul(unsigned char a, unsigned char b) //有限域GF(2^8)上的乘法
{
unsigned char bw[4];
unsigned char res=0;
int i;
bw[0] = b;
for(i=1; i<4; i++)
{
bw[i] = bw[i-1]<<1;
if(bw[i-1]&0x80)
{
bw[i]^=0x1b;
}
}
for(i=0; i<4; i++)
{
if((a>>i)&0x01)
{
res ^= bw[i];
}
}
return res;
}
这里重点是有限域GF(2^8)上的乘法。采用的算法的原理如下:1、 GF(2^8)中任何数乘0x01都不变2、 GF(2^8)中计算乘0x02,可以分两种情况考虑:(1)、原数值小于(1000 0000)2,即0x80的时候,乘2后第8个比特不会溢出,那么结果就是原数值左移一位;(2)、原数值大于(1000 0000)2,即0x80的时候,乘2后第8个比特会溢出,结果需要减去一个不可约多项式(x8+x4+x2+x+1),注意到GF(2^8)中的减法就是加法,那么结果就为原数值左移一位后(乘2)再与(0001 1011)2即0x1b进行异或(这里x8已经减掉了,只需要再减去x4+x2+x+1)。3、类似第2点,可以得到GF(2^8)中计算乘4、乘8的结果;4、GF(2^8)中计算乘其它数时,可以表示为乘1、2、4、8的线性组合。根据以上几点再对有限域GF(2^8)上的乘法源代码进行解释:
代码:
unsigned char AES::FFmul(unsigned char a, unsigned char b) //有限域GF(2^8)上的乘法
{
unsigned char bw[4];
unsigned char res=0;
int i;
bw[0] = b;
for(i=1; i<4; i++) //循环三次,分别得到参数b乘2、4、8后的值,储存到bw[i]里面
{
bw[i] = bw[i-1]<<1; //原数值乘2
if(bw[i-1]&0x80) //判断原数值是否小于0x80
{
bw[i]^=0x1b; //如果大于0x80的话,减去一个不可约多项式
}
}
for(i=0; i<4; i++)
{
if((a>>i)&0x01) //将参数a的值表示为1、2、4、8的线性组合
{
res ^= bw[i];
}
}
return res;
}
列混合其实就是对一个状态的每一列去乘一个矩阵,其中乘法是在有限域GF(2^8)内进行的,不可约多项式为x^8+x^4+x^2+x+1如图:
![](http://pic002.cnblogs.com/images/2010/169108/2010103102021588.png)
先把算法代码列出来:
代码:
void AES::MixColumns(unsigned char state[][4]) //列混合
{
unsigned char t[4];
int r,c;
for(c=0; c< 4; c++) //按列处理
{
for(r=0; r<4; r++)
{
t[r] = state[r][c]; //每一列中的每一个字节拷贝到t[r]中
}
for(r=0; r<4; r++)
{
state[r][c] = FFmul(0x02, t[r]) //矩阵计算,其中加法为异或
^ FFmul(0x03, t[(r+1)%4])
^ FFmul(0x01, t[(r+2)%4])
^ FFmul(0x01, t[(r+3)%4]);
}
}
}
unsigned char AES::FFmul(unsigned char a, unsigned char b) //有限域GF(2^8)上的乘法
{
unsigned char bw[4];
unsigned char res=0;
int i;
bw[0] = b;
for(i=1; i<4; i++)
{
bw[i] = bw[i-1]<<1;
if(bw[i-1]&0x80)
{
bw[i]^=0x1b;
}
}
for(i=0; i<4; i++)
{
if((a>>i)&0x01)
{
res ^= bw[i];
}
}
return res;
}
这里重点是有限域GF(2^8)上的乘法。采用的算法的原理如下:1、 GF(2^8)中任何数乘0x01都不变2、 GF(2^8)中计算乘0x02,可以分两种情况考虑:(1)、原数值小于(1000 0000)2,即0x80的时候,乘2后第8个比特不会溢出,那么结果就是原数值左移一位;(2)、原数值大于(1000 0000)2,即0x80的时候,乘2后第8个比特会溢出,结果需要减去一个不可约多项式(x8+x4+x2+x+1),注意到GF(2^8)中的减法就是加法,那么结果就为原数值左移一位后(乘2)再与(0001 1011)2即0x1b进行异或(这里x8已经减掉了,只需要再减去x4+x2+x+1)。3、类似第2点,可以得到GF(2^8)中计算乘4、乘8的结果;4、GF(2^8)中计算乘其它数时,可以表示为乘1、2、4、8的线性组合。根据以上几点再对有限域GF(2^8)上的乘法源代码进行解释:
代码:
unsigned char AES::FFmul(unsigned char a, unsigned char b) //有限域GF(2^8)上的乘法
{
unsigned char bw[4];
unsigned char res=0;
int i;
bw[0] = b;
for(i=1; i<4; i++) //循环三次,分别得到参数b乘2、4、8后的值,储存到bw[i]里面
{
bw[i] = bw[i-1]<<1; //原数值乘2
if(bw[i-1]&0x80) //判断原数值是否小于0x80
{
bw[i]^=0x1b; //如果大于0x80的话,减去一个不可约多项式
}
}
for(i=0; i<4; i++)
{
if((a>>i)&0x01) //将参数a的值表示为1、2、4、8的线性组合
{
res ^= bw[i];
}
}
return res;
}
相关文章推荐
- Java AES加密解密算法
- 常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
- 常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
- Java加密解密算法-AES加密解密
- iOS开发之Objective-c的AES加密和解密算法的实现
- OpenSSL AES, RSA 算法加密本地文件
- 【转】asp.net(c#)加密解密算法之sha1、md5、des、aes实现源码详解
- eclipse JAVA实现AES的加密和解密算法
- 算法与数据结构---加密系列二(AES)
- java 下的 AES javax.crypto包 加密解密算法示例
- iOS开发之算法加密md5,sha1,AES,base64
- AES加解密算法,使用Base64做转码以及辅助加密
- oc 加密 AES 256算法(EncryptAndDecrypt.h)
- AES加密解密算法---java
- 常见的加密和解密算法—AES
- iOS开发之Objective-c的AES加密和解密算法的实现
- Android接口安全 - RSA+AES混合加密方案
- 典型的网络接口安全机制,AES和RSA混合加密
- Android接口安全 - RSA+AES混合加密方案
- AES算法加密java实现