aes加密算法代码(aes加密算法流程图)

2023-02-28 23:30:18 摩斯密码知识 思思

PHP的aes加解密算法

1. php的aes算法,加密时会存在空格,0,\0等方式进行补长,所以解密后需要进行trim操作,才能得到原数据串

2. aes加密后进行base64_encode,但是解密时,直接用aes进行解密,不需要先base64_decode.【这个操作很骚气】

function _decryptData($data,$password, $iv){

    $decryptData=openssl_decrypt($data, 'aes-128-cbc', $password, OPENSSL_ZERO_PADDING, $iv);

    $data =json_decode(trim($decryptData), true);

    return $data;

}

function encryptData($data, $password, $iv){

    $data = json_encode($data);//$data是一个数组,如果是字符串,请忽略此句.

    $result = base64_encode(openssl_encrypt($data, 'aes-128-cbc', $password, OPENSSL_RAW_DATA, $iv));

    return $result;

}

aes加密算法C代码

完整的!

#include "stdio.h"

#include "memory.h"

#include "time.h"

#include "stdlib.h"

#define PLAIN_FILE_OPEN_ERROR -1

#define KEY_FILE_OPEN_ERROR -2

#define CIPHER_FILE_OPEN_ERROR -3

#define OK 1

typedef char ElemType;

/*初始置换表IP*/

int IP_Table[64] = { 57,49,41,33,25,17,9,1,

59,51,43,35,27,19,11,3,

61,53,45,37,29,21,13,5,

63,55,47,39,31,23,15,7,

56,48,40,32,24,16,8,0,

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6};

/*逆初始置换表IP^-1*/

int IP_1_Table[64] = {39,7,47,15,55,23,63,31,

38,6,46,14,54,22,62,30,

37,5,45,13,53,21,61,29,

36,4,44,12,52,20,60,28,

35,3,43,11,51,19,59,27,

34,2,42,10,50,18,58,26,

33,1,41,9,49,17,57,25,

32,0,40,8,48,16,56,24};

/*扩充置换表E*/

int E_Table[48] = {31, 0, 1, 2, 3, 4,

3, 4, 5, 6, 7, 8,

7, 8,9,10,11,12,

11,12,13,14,15,16,

15,16,17,18,19,20,

19,20,21,22,23,24,

23,24,25,26,27,28,

27,28,29,30,31, 0};

/*置换函数P*/

int P_Table[32] = {15,6,19,20,28,11,27,16,

0,14,22,25,4,17,30,9,

1,7,23,13,31,26,2,8,

18,12,29,5,21,10,3,24};

/*S盒*/

int S[8][4][16] =

/*S1*/

{{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},

{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},

{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},

{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},

/*S2*/

{{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},

{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},

{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},

{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},

/*S3*/

{{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},

{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},

{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},

{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},

/*S4*/

{{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},

{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},

{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},

{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},

/*S5*/

{{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},

{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},

{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},

{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},

/*S6*/

{{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},

{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},

{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},

{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},

/*S7*/

{{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},

{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},

{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},

{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},

/*S8*/

{{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},

{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},

{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},

{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};

/*置换选择1*/

int PC_1[56] = {56,48,40,32,24,16,8,

0,57,49,41,33,25,17,

9,1,58,50,42,34,26,

18,10,2,59,51,43,35,

62,54,46,38,30,22,14,

6,61,53,45,37,29,21,

13,5,60,52,44,36,28,

20,12,4,27,19,11,3};

/*置换选择2*/

int PC_2[48] = {13,16,10,23,0,4,2,27,

14,5,20,9,22,18,11,3,

25,7,15,6,26,19,12,1,

40,51,30,36,46,54,29,39,

50,44,32,46,43,48,38,55,

33,52,45,41,49,35,28,31};

/*对左移次数的规定*/

int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

int ByteToBit(ElemType ch,ElemType bit[8]);

int BitToByte(ElemType bit[8],ElemType *ch);

int Char8ToBit64(ElemType ch[8],ElemType bit[64]);

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]);

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]);

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]);

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]);

int DES_ROL(ElemType data[56], int time);

int DES_IP_Transform(ElemType data[64]);

int DES_IP_1_Transform(ElemType data[64]);

int DES_E_Transform(ElemType data[48]);

int DES_P_Transform(ElemType data[32]);

int DES_SBOX(ElemType data[48]);

int DES_XOR(ElemType R[48], ElemType L[48],int count);

int DES_Swap(ElemType left[32],ElemType right[32]);

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]);

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8]);

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);

/*字节转换成二进制*/

int ByteToBit(ElemType ch, ElemType bit[8]){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*(bit+cnt) = (chcnt)1;

}

return 0;

}

/*二进制转换成字节*/

int BitToByte(ElemType bit[8],ElemType *ch){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*ch |= *(bit + cnt)cnt;

}

return 0;

}

/*将长度为8的字符串转为二进制位串*/

int Char8ToBit64(ElemType ch[8],ElemType bit[64]){

int cnt;

for(cnt = 0; cnt 8; cnt++){

ByteToBit(*(ch+cnt),bit+(cnt3));

}

return 0;

}

/*将二进制位串转为长度为8的字符串*/

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){

int cnt;

memset(ch,0,8);

for(cnt = 0; cnt 8; cnt++){

BitToByte(bit+(cnt3),ch+cnt);

}

return 0;

}

/*生成子密钥*/

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){

ElemType temp[56];

int cnt;

DES_PC1_Transform(key,temp);/*PC1置换*/

for(cnt = 0; cnt 16; cnt++){/*16轮跌代,产生16个子密钥*/

DES_ROL(temp,MOVE_TIMES[cnt]);/*循环左移*/

DES_PC2_Transform(temp,subKeys[cnt]);/*PC2置换,产生子密钥*/

}

return 0;

}

/*密钥置换1*/

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]){

int cnt;

for(cnt = 0; cnt 56; cnt++){

tempbts[cnt] = key[PC_1[cnt]];

}

return 0;

}

/*密钥置换2*/

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]){

int cnt;

for(cnt = 0; cnt 48; cnt++){

tempbts[cnt] = key[PC_2[cnt]];

}

return 0;

}

/*循环左移*/

int DES_ROL(ElemType data[56], int time){

ElemType temp[56];

/*保存将要循环移动到右边的位*/

memcpy(temp,data,time);

memcpy(temp+time,data+28,time);

/*前28位移动*/

memcpy(data,data+time,28-time);

memcpy(data+28-time,temp,time);

/*后28位移动*/

memcpy(data+28,data+28+time,28-time);

memcpy(data+56-time,temp+time,time);

return 0;

}

/*IP置换*/

int DES_IP_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/*IP逆置换*/

int DES_IP_1_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_1_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/*扩展置换*/

int DES_E_Transform(ElemType data[48]){

int cnt;

ElemType temp[48];

for(cnt = 0; cnt 48; cnt++){

temp[cnt] = data[E_Table[cnt]];

}

memcpy(data,temp,48);

return 0;

}

/*P置换*/

int DES_P_Transform(ElemType data[32]){

int cnt;

ElemType temp[32];

for(cnt = 0; cnt 32; cnt++){

temp[cnt] = data[P_Table[cnt]];

}

memcpy(data,temp,32);

return 0;

}

/*异或*/

int DES_XOR(ElemType R[48], ElemType L[48] ,int count){

int cnt;

for(cnt = 0; cnt count; cnt++){

R[cnt] ^= L[cnt];

}

return 0;

}

/*S盒置换*/

int DES_SBOX(ElemType data[48]){

int cnt;

int line,row,output;

int cur1,cur2;

for(cnt = 0; cnt 8; cnt++){

cur1 = cnt*6;

cur2 = cnt2;

/*计算在S盒中的行与列*/

line = (data[cur1]1) + data[cur1+5];

row = (data[cur1+1]3) + (data[cur1+2]2)

+ (data[cur1+3]1) + data[cur1+4];

output = S[cnt][line][row];

/*化为2进制*/

data[cur2] = (output0X08)3;

data[cur2+1] = (output0X04)2;

data[cur2+2] = (output0X02)1;

data[cur2+3] = output0x01;

}

return 0;

}

/*交换*/

int DES_Swap(ElemType left[32], ElemType right[32]){

ElemType temp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return 0;

}

/*加密单个分组*/

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]){

ElemType plainBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(plainBlock,plainBits);

/*初始置换(IP置换)*/

DES_IP_Transform(plainBits);

/*16轮迭代*/

for(cnt = 0; cnt 16; cnt++){

memcpy(copyRight,plainBits+32,32);

/*将右半部分进行扩展置换,从32位扩展到48位*/

DES_E_Transform(copyRight);

/*将右半部分与子密钥进行异或操作*/

DES_XOR(copyRight,subKeys[cnt],48);

/*异或结果进入S盒,输出32位结果*/

DES_SBOX(copyRight);

/*P置换*/

DES_P_Transform(copyRight);

/*将明文左半部分与右半部分进行异或*/

DES_XOR(plainBits,copyRight,32);

if(cnt != 15){

/*最终完成左右部的交换*/

DES_Swap(plainBits,plainBits+32);

}

}

/*逆初始置换(IP^1置换)*/

DES_IP_1_Transform(plainBits);

Bit64ToChar8(plainBits,cipherBlock);

return 0;

}

/*解密单个分组*/

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8]){

ElemType cipherBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(cipherBlock,cipherBits);

/*初始置换(IP置换)*/

DES_IP_Transform(cipherBits);

/*16轮迭代*/

for(cnt = 15; cnt = 0; cnt--){

memcpy(copyRight,cipherBits+32,32);

/*将右半部分进行扩展置换,从32位扩展到48位*/

DES_E_Transform(copyRight);

/*将右半部分与子密钥进行异或操作*/

DES_XOR(copyRight,subKeys[cnt],48);

/*异或结果进入S盒,输出32位结果*/

DES_SBOX(copyRight);

/*P置换*/

DES_P_Transform(copyRight);

/*将明文左半部分与右半部分进行异或*/

DES_XOR(cipherBits,copyRight,32);

if(cnt != 0){

/*最终完成左右部的交换*/

DES_Swap(cipherBits,cipherBits+32);

}

}

/*逆初始置换(IP^1置换)*/

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return 0;

}

/*加密文件*/

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){

FILE *plain,*cipher;

int count;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((plain = fopen(plainFile,"rb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

if((cipher = fopen(cipherFile,"wb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

/*设置密钥*/

memcpy(keyBlock,keyStr,8);

/*将密钥转换为二进制流*/

Char8ToBit64(keyBlock,bKey);

/*生成子密钥*/

DES_MakeSubKeys(bKey,subKeys);

while(!feof(plain)){

/*每次读8个字节,并返回成功读取的字节数*/

if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

}

if(count){

/*填充*/

memset(plainBlock + count,'\0',7 - count);

/*最后一个字符保存包括最后一个字符在内的所填充的字符数量*/

plainBlock[7] = 8 - count;

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

fclose(plain);

fclose(cipher);

return OK;

}

/*解密文件*/

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){

FILE *plain, *cipher;

int count,times = 0;

long fileLen;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((cipher = fopen(cipherFile,"rb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

if((plain = fopen(plainFile,"wb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

/*设置密钥*/

memcpy(keyBlock,keyStr,8);

/*将密钥转换为二进制流*/

Char8ToBit64(keyBlock,bKey);

/*生成子密钥*/

DES_MakeSubKeys(bKey,subKeys);

/*取文件长度 */

fseek(cipher,0,SEEK_END);/*将文件指针置尾*/

fileLen = ftell(cipher); /*取文件指针当前位置*/

rewind(cipher); /*将文件指针重指向文件头*/

while(1){

/*密文的字节数一定是8的整数倍*/

fread(cipherBlock,sizeof(char),8,cipher);

DES_DecryptBlock(cipherBlock,subKeys,plainBlock);

times += 8;

if(times fileLen){

fwrite(plainBlock,sizeof(char),8,plain);

}

else{

break;

}

}

/*判断末尾是否被填充*/

if(plainBlock[7] 8){

for(count = 8 - plainBlock[7]; count 7; count++){

if(plainBlock[count] != '\0'){

break;

}

}

}

if(count == 7){/*有填充*/

fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);

}

else{/*无填充*/

fwrite(plainBlock,sizeof(char),8,plain);

}

fclose(plain);

fclose(cipher);

return OK;

}

int main()

{

clock_t a,b;

a = clock();

DES_Encrypt("1.txt","key.txt","2.txt");

b = clock();

printf("加密消耗%d毫秒\n",b-a);

system("pause");

a = clock();

DES_Decrypt("2.txt","key.txt","3.txt");

b = clock();

printf("解密消耗%d毫秒\n",b-a);

getchar();

return 0;

}

如何使用java对密码加密 加密方式aes

Java有相关的实现类:具体原理如下

对于任意长度的明文,AES首先对其进行分组,每组的长度为128位。分组之后将分别对每个128位的明文分组进行加密。

对于每个128位长度的明文分组的加密过程如下:

(1)将128位AES明文分组放入状态矩阵中。

(2)AddRoundKey变换:对状态矩阵进行AddRoundKey变换,与膨胀后的密钥进行异或操作(密钥膨胀将在实验原理七中详细讨论)。

(3)10轮循环:AES对状态矩阵进行了10轮类似的子加密过程。前9轮子加密过程中,每一轮子加密过程包括4种不同的变换,而最后一轮只有3种变换,前9轮的子加密步骤如下:

● SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;

● ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;

● MixColumns变换:MixColumns变换对状态矩阵的列进行变换;

● AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作。

最后一轮的子加密步骤如下:

● SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;

● ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;

● AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作;

(4)经过10轮循环的状态矩阵中的内容就是加密后的密文。

AES的加密算法的伪代码如下。

在AES算法中,AddRoundKey变换需要使用膨胀后的密钥,原始的128位密钥经过膨胀会产生44个字(每个字为32位)的膨胀后的密钥,这44个字的膨胀后的密钥供11次AddRoundKey变换使用,一次AddRoundKey使用4个字(128位)的膨胀后的密钥。

三.AES的分组过程

对于任意长度的明文,AES首先对其进行分组,分组的方法与DES相同,即对长度不足的明文分组后面补充0即可,只是每一组的长度为128位。

AES的密钥长度有128比特,192比特和256比特三种标准,其他长度的密钥并没有列入到AES联邦标准中,在下面的介绍中,我们将以128位密钥为例。

四.状态矩阵

状态矩阵是一个4行、4列的字节矩阵,所谓字节矩阵就是指矩阵中的每个元素都是一个1字节长度的数据。我们将状态矩阵记为State,State中的元素记为Sij,表示状态矩阵中第i行第j列的元素。128比特的明文分组按字节分成16块,第一块记为“块0”,第二块记为“块1”,依此类推,最后一块记为“块15”,然后将这16块明文数据放入到状态矩阵中,将这16块明文数据放入到状态矩阵中的方法如图2-2-1所示。

块0

块4

块8

块12

块1

块5

块9

块13

块2

块6

块10

块14

块3

块7

块11

块15

图2-2-1 将明文块放入状态矩阵中

五.AddRoundKey变换

状态矩阵生成以后,首先要进行AddRoundKey变换,AddRoundKey变换将状态矩阵与膨胀后的密钥进行按位异或运算,如下所示。

其中,c表示列数,数组W为膨胀后的密钥,round为加密轮数,Nb为状态矩阵的列数。

它的过程如图2-2-2所示。

图2-2-2 AES算法AddRoundKey变换

六.10轮循环

经过AddRoundKey的状态矩阵要继续进行10轮类似的子加密过程。前9轮子加密过程中,每一轮要经过4种不同的变换,即SubBytes变换、ShiftRows变换、MixColumns变换和AddRoundKey变换,而最后一轮只有3种变换,即SubBytes变换、ShiftRows变换和AddRoundKey变换。AddRoundKey变换已经讨论过,下面分别讨论余下的三种变换。

1.SubBytes变换

SubBytes是一个独立作用于状态字节的非线性变换,它由以下两个步骤组成:

(1)在GF(28)域,求乘法的逆运算,即对于α∈GF(28)求β∈GF(28),使αβ =βα = 1mod(x8 + x4 + x3 + x + 1)。

(2)在GF(28)域做变换,变换使用矩阵乘法,如下所示:

由于所有的运算都在GF(28)域上进行,所以最后的结果都在GF(28)上。若g∈GF(28)是GF(28)的本原元素,则对于α∈GF(28),α≠0,则存在

β ∈ GF(28),使得:

β = gαmod(x8 + x4 + x3 + x + 1)

由于g255 = 1mod(x8 + x4 + x3 + x + 1)

所以g255-α = β-1mod(x8 + x4 + x3 + x + 1)

根据SubBytes变换算法,可以得出SubBytes的置换表,如表2-2-1所示,这个表也叫做AES的S盒。该表的使用方法如下:状态矩阵中每个元素都要经过该表替换,每个元素为8比特,前4比特决定了行号,后4比特决定了列号,例如求SubBytes(0C)查表的0行C列得FE。

表2-2-1 AES的SubBytes置换表

它的变换过程如图2-2-3所示。

图2-2-3 SubBytes变换

AES加密过程需要用到一些数学基础,其中包括GF(2)域上的多项式、GF(28)域上的多项式的计算和矩阵乘法运算等,有兴趣的同学请参考相关的数学书籍。

2.ShiftRows变换

ShiftRows变换比较简单,状态矩阵的第1行不发生改变,第2行循环左移1字节,第3行循环左移2字节,第4行循环左移3字节。ShiftRows变换的过程如图2-2-4所示。

图2-2-4 AES的ShiftRows变换

3.MixColumns变换

在MixColumns变换中,状态矩阵的列看作是域GF(28)的多项式,模(x4+1)乘以c(x)的结果:

c(x)=(03)x3+(01)x2+(01)x+(02)

这里(03)为十六进制表示,依此类推。c(x)与x4+1互质,故存在逆:

d(x)=(0B)x3+(0D)x2+(0G)x+(0E)使c(x)•d(x) = (D1)mod(x4+1)。

设有:

它的过程如图2-2-5所示。

图2-2-5 AES算法MixColumns变换

七.密钥膨胀

在AES算法中,AddRoundKey变换需要使用膨胀后的密钥,膨胀后的密钥记为子密钥,原始的128位密钥经过膨胀会产生44个字(每个字为32位)的子密钥,这44个字的子密钥供11次AddRoundKey变换使用,一次AddRoundKey使用4个字(128位)的膨胀后的密钥。

密钥膨胀算法是以字为基础的(一个字由4个字节组成,即32比特)。128比特的原始密钥经过膨胀后将产生44个字的子密钥,我们将这44个密钥保存在一个字数组中,记为W[44]。128比特的原始密钥分成16份,存放在一个字节的数组:Key[0],Key[1]……Key[15]中。

在密钥膨胀算法中,Rcon是一个10个字的数组,在数组中保存着算法定义的常数,分别为:

Rcon[0] = 0x01000000

Rcon[1] = 0x02000000

Rcon[2] = 0x04000000

Rcon[3] = 0x08000000

Rcon[4] = 0x10000000

Rcon[5] = 0x20000000

Rcon[6] = 0x40000000

Rcon[7] = 0x80000000

Rcon[8] = 0x1b000000

Rcon[9] = 0x36000000

另外,在密钥膨胀中包括其他两个操作RotWord和SubWord,下面对这两个操作做说明:

RotWord( B0,B1,B2,B3 )对4个字节B0,B1,B2,B3进行循环移位,即

RotWord( B0,B1,B2,B3 ) = ( B1,B2,B3,B0 )

SubWord( B0,B1,B2,B3 )对4个字节B0,B1,B2,B3使用AES的S盒,即

SubWord( B0,B1,B2,B3 ) = ( B’0,B’1,B’2,B’3 )

其中,B’i = SubBytes(Bi),i = 0,1,2,3。

密钥膨胀的算法如下:

八.解密过程

AES的加密和解密过程并不相同,首先密文按128位分组,分组方法和加密时的分组方法相同,然后进行轮变换。

AES的解密过程可以看成是加密过程的逆过程,它也由10轮循环组成,每一轮循环包括四个变换分别为InvShiftRows变换、InvSubBytes变换、InvMixColumns变换和AddRoundKey变换;

这个过程可以描述为如下代码片段所示:

九.InvShiftRows变换

InvShiftRows变换是ShiftRows变换的逆过程,十分简单,指定InvShiftRows的变换如下。

Sr,(c+shift(r,Nb))modNb= Sr,c for 0 r 4 and 0 ≤ c Nb

图2-2-6演示了这个过程。

图2-2-6 AES算法InvShiftRows变换

十.InvSubBytes变换

InvSubBytes变换是SubBytes变换的逆变换,利用AES的S盒的逆作字节置换,表2-2-2为InvSubBytes变换的置换表。

表2-2-2 InvSubBytes置换表

十一.InvMixColumns变换

InvMixColumns变换与MixColumns变换类似,每列乘以d(x)

d(x) = (OB)x3 + (0D)x2 + (0G)x + (0E)

下列等式成立:

( (03)x3 + (01)x2 + (01)x + (02) )⊙d(x) = (01)

上面的内容可以描述为以下的矩阵乘法:

十二.AddRoundKey变换

AES解密过程的AddRoundKey变换与加密过程中的AddRoundKey变换一样,都是按位与子密钥做异或操作。解密过程的密钥膨胀算法也与加密的密钥膨胀算法相同。最后状态矩阵中的数据就是明文。

aes加密算法代码(aes加密算法流程图) 第1张

求AES加解/密码密软件程序!!!

有界面,我这里有个,但是是c#语言的,你以为如何?

下面是c版本的

AES加密算法源代码

//AES.h

#define decrypt TRUE

#define encrypt FALSE

#define TYPE BOOL

typedef struct _AES{

int Nb;

int Nr;

int Nk;

unsigned long *Word;

unsigned long *State;

}AES;

/*

加密数据

byte *input 明文

byte *inSize 明文长

byte *out 密文存放的地方

byte *key 密钥key

byte *keySize 密钥长

*/

void Cipher(

unsigned char* input,

int inSize,

unsigned char* out,

unsigned char* key,

int keySize);

/*

解密数据

byte *input 密文

int *inSize 密文长

byte *out 明文存放的地方

byte *key 密钥key

int *keySize 密钥长

*/

void InvCipher(

unsigned char* input,

int inSize,

unsigned char* out,

unsigned char* key,

int keySize);

/*

生成加密用的参数AES结构

int inSize 块大小

byte* 密钥

int 密钥长

unsigned long 属性(标实类型)

返回AES结构指针

*/

AES *InitAES(AES *aes,

int inSize,

unsigned char* key,

int keySize, TYPE type);

/*

生成加密用的参数AES结构

int inSize 块大小

byte* 密钥

int 密钥长

返回AES结构指针

*/

AES *InitAES(

int inSize,

unsigned char* key,

int keySize, BOOL );

/*

加密时进行Nr轮运算

AES * aes 运行时参数

*/

void CipherLoop(

AES *aes);

/*

解密时进行Nr轮逆运算

AES * aes 运行时参数

*/

void InvCipherLoop(

AES *aes);

/*

释放AES结构和State和密钥库word

*/

void freeAES(

AES *aes);

//AES.cpp

#include "stdafx.h"

#include

#include

#include "AES.h"

unsigned char* SubWord(unsigned char* word);

unsigned long* keyExpansion(unsigned char* key, int Nk, int Nr,int);

/*

加密数据

byte *input 明文

byte *inSize 明文长

byte *out 密文存放的地方

byte *key 密钥key

byte *keySize 密钥长

*/

void Cipher(unsigned char* input, int inSize, unsigned char* out, unsigned char* key, int keySize)

{

AES aes ;

InitAES(aes,inSize,key,keySize,encrypt);

memcpy(aes.State,input,inSize);

CipherLoop(aes);

memcpy(out,aes.State,inSize);

}

/*

解密数据

byte *input 密文

int *inSize 密文长

byte *out 明文存放的地方

byte *key 密钥key

int *keySize 密钥长

*/

void InvCipher(unsigned char* input, int inSize, unsigned char* out, unsigned char* key, int keySize)

{

AES aes;

InitAES(aes,inSize,key,keySize,decrypt);

memcpy(aes.State,input,inSize);

InvCipherLoop(aes);

memcpy(aes.State,out,inSize);

}

/*

生成加密用的参数AES结构

int inSize 块大小

byte* 密钥

int 密钥长

返回AES结构指针

*/

AES *InitAES(AES *aes,int inSize, unsigned char *key, int keySize, TYPE type)

{

int Nb = inSize 2,

Nk = keySize 2,

Nr = Nb Nk ? Nk:Nb+6;

aes-Nb = Nb;

aes-Nk = Nk;

aes-Nr = Nr;

aes-Word = keyExpansion(key,Nb,Nr,Nk);

aes-State = new unsigned long[Nb+3];

if(type)

aes-State += 3;

return aes;

}

/*

生成加密用的参数AES结构

int inSize 块大小

byte* 密钥

int 密钥长

返回AES结构指针

*/

AES *InitAES(int inSize, unsigned char* key, int keySize,unsigned long type)

{

return InitAES(new AES(),inSize,key,keySize,type);

}

/*

*/

void CipherLoop(AES *aes)

{

unsigned char temp[4];

unsigned long *word8 = aes-Word,

*State = aes-State;

int Nb = aes-Nb,

Nr = aes-Nr;

int r;

for (r = 0; r Nb; ++r)

{

State[r] ^= word8[r];

}

for (int round =1; round {

word8 += Nb;

/*

假设Nb=4;

---------------------

| s0 | s1 | s2 | s3 |

---------------------

| s4 | s5 | s6 | s7 |

---------------------

| s8 | s9 | sa | sb |

---------------------

| sc | sd | se | sf |

---------------------

| | | | |

---------------------

| | | | |

---------------------

| | | | |

---------------------

*/

memcpy(State+Nb,State,12);

/*

Nb=4;

---------------------

| s0 | | | |

---------------------

| s4 | s5 | | |

---------------------

| s8 | s9 | sa | |

---------------------

| sc | sd | se | sf |

---------------------

| | s1 | s2 | s3 |

---------------------

| | | s6 | s7 |

---------------------

| | | | sb |

---------------------

*/

for(r =0; r {

/*

temp = {Sbox[s0],Sbox[s5],Sbox[sa],Sbox[sf]};

*/

temp[0] = Sbox[*((unsigned char*)State)];

temp[1] = Sbox[*((unsigned char*)(State+1)+1)];

temp[2] = Sbox[*((unsigned char*)(State+2)+2)];

temp[3] = Sbox[*((unsigned char*)(State+3)+3)];

*((unsigned char*)State) = Log_02[temp[0]] ^ Log_03[temp[1]] ^ temp[2] ^ temp[3];

*((unsigned char*)State+1) = Log_02[temp[1]] ^ Log_03[temp[2]] ^ temp[3] ^ temp[0];

*((unsigned char*)State+2) = Log_02[temp[2]] ^ Log_03[temp[3]] ^ temp[0] ^ temp[1];

*((unsigned char*)State+3) = Log_02[temp[3]] ^ Log_03[temp[0]] ^ temp[1] ^ temp[2];

*State ^= word8[r];

State++;

}

State -= Nb;

}

memcpy(State+Nb,State,12);

word8 += Nb;

for(r =0; r {

*((unsigned char*)State) = Sbox[*(unsigned char*)State];

*((unsigned char*)State+1) = Sbox[*((unsigned char*)(State+1)+1)];

*((unsigned char*)State+2) = Sbox[*((unsigned char*)(State+2)+2)];

*((unsigned char*)State+3) = Sbox[*((unsigned char*)(State+3)+3)];

*State ^= word8[r];

State++;

}

}

/*

解密时进行Nr轮逆运算

AES * aes 运行时参数

*/

void InvCipherLoop(AES *aes)

{

unsigned long *Word = aes-Word,

*State = aes-State;

int Nb = aes-Nb,

Nr = aes-Nr;

unsigned char temp[4];

int r =0;

Word += Nb*Nr;

for (r = 0; r Nb; ++r)

{

State[r] ^= Word[r];

}

State -= 3;

for (int round = Nr-1; round 0; --round)

{

/*

假设Nb=4;

---------------------

| | | | |

---------------------

| | | | |

---------------------

| | | | |

---------------------

| s0 | s1 | s2 | s3 |

---------------------

| s4 | s5 | s6 | s7 |

---------------------

| s8 | s9 | sa | sb |

---------------------

| sc | sd | se | sf |

---------------------

*/

memcpy(State,State+Nb,12);

/*

Nb=4;

---------------------

| | | | s7 |

---------------------

| | | sa | sb |

---------------------

| | sd | se | sf |

---------------------

| s0 | s1 | s2 | s3 |

---------------------

| s4 | s5 | s6 | |

---------------------

| s8 | s9 | | |

---------------------

| sc | | | |

---------------------

*/

Word -= Nb;

State += Nb+2;

for(r = Nb-1; r = 0; r--)

{

/*

temp = {iSbox[s0],iSbox[sd],iSbox[sa],iSbox[s7]};

*/

temp[0] = iSbox[*(byte*)State];

temp[1] = iSbox[*((byte*)(State-1)+1)];

temp[2] = iSbox[*((byte*)(State-2)+2)];

temp[3] = iSbox[*((byte*)(State-3)+3)];

*(unsigned long*)temp ^= Word[r];

*(unsigned char*)State = Log_0e[temp[0]] ^ Log_0b[temp[1]] ^ Log_0d[temp[2]] ^ Log_09[temp[3]];

*((unsigned char*)State+1) = Log_0e[temp[1]] ^ Log_0b[temp[2]] ^ Log_0d[temp[3]] ^ Log_09[temp[0]];

*((unsigned char*)State+2) = Log_0e[temp[2]] ^ Log_0b[temp[3]] ^ Log_0d[temp[0]] ^ Log_09[temp[1]];

*((unsigned char*)State+3) = Log_0e[temp[3]] ^ Log_0b[temp[0]] ^ Log_0d[temp[1]] ^ Log_09[temp[2]];

State --;

}

State -= 2;

}

Word -= Nb;

memcpy(State,State+Nb,12);

State += Nb+2;

for(r = Nb-1; r = 0; r--)

{

*(unsigned char*)State = iSbox[*(unsigned char*)State];

*((unsigned char*)State+1) = iSbox[*((unsigned char*)(State-1)+1)];

*((unsigned char*)State+2) = iSbox[*((unsigned char*)(State-2)+2)];

*((unsigned char*)State+3) = iSbox[*((unsigned char*)(State-3)+3)];

*State ^= Word[r];

State --;

}

}

/*

*--------------------------------------------

*|k0|k1|k2|k3|k4|k5|k6|k7|k8|k9|.......|Nk*4|

*--------------------------------------------

*Nr轮密钥库

*每个密钥列长度为Nb

*---------------------

*| k0 | k1 | k2 | k3 |

*---------------------

*| k4 | k5 | k6 | k7 |

*---------------------

*| k8 | k9 | ka | kb |

*---------------------

*| kc | kd | ke | kf |

*---------------------

*/

unsigned long* keyExpansion(byte* key, int Nb, int Nr, int Nk)

{

unsigned long *w =new unsigned long[Nb * (Nr+1)]; // 4 columns of bytes corresponds to a word

memcpy(w,key,Nk2);

unsigned long temp;

for (int c = Nk; c Nb * (Nr+1); ++c)

{

//把上一轮的最后一行放入temp

temp = w[c-1];

//判断是不是每一轮密钥的第一行

if (c % Nk == 0)

{

//左旋8位

temp = (temp8)|(temp24);

//查Sbox表

SubWord((byte*)temp);

temp ^= Rcon[c/Nk];

}

else if ( Nk 6 (c % Nk == 4) )

{

SubWord((byte*)temp);

}

//w[c-Nk] 为上一轮密钥的第一行

w[c] = w[c-Nk] ^ temp;

}

return w;

}

unsigned char* SubWord(unsigned char* word)

{

word[0] = Sbox[ word[0] ];

word[1] = Sbox[ word[1] ];

word[2] = Sbox[ word[2] ];

word[3] = Sbox[ word[3] ];

return word;

}

/*

释放AES结构和State和密钥库word

*/

void freeAES(AES *aes)

{

// for(int i=0;iNb;i++)

// {

// printf("%d\n",i);

// free(aes-State[i]);

// free(aes-Word[i]);

// }

// printf("sdffd");

}

求解释这段安卓代码中的AES加密流程

AES加密过程涉及到 4 种操作,分别是字节替代、行移位、列混淆和轮密钥加。

1.字节替换:字节代替的主要功能是通过S盒完成一个字节到另外一个字节的映射。

2.行移位:行移位的功能是实现一个4x4矩阵内部字节之间的置换。

4.轮密钥加:加密过程中,每轮的输入与轮密钥异或一次(当前分组和扩展密钥的一部分进行按位异或);因为二进制数连续异或一个数结果是不变的,所以在解密时再异或上该轮的密钥即可恢复输入。

5.密钥扩展:其复杂性是确保算法安全性的重要部分。当分组长度和密钥长度都是128位时,AES的加密算法共迭代10轮,需要10个子密钥。AES的密钥扩展的目的是将输入的128位密钥扩展成11个128位的子密钥。AES的密钥扩展算法是以字为一个基本单位(一个字为4个字节),刚好是密钥矩阵的一列。因此4个字(128位)密钥需要扩展成11个子密钥,共44个字。