您的位置:

aes算法c语言程序,aes算法是哪种算法

本文目录一览:

ASE加密算法,C语言实现

Rijdeal的AES算法吧?

实现:

#include"stdio.h"

typedef unsigned char word8;

typedef unsigned int word32;

word8 Logtable[256] =

{

0,0,25,1,50,2,26,198,75,199,27,104,51,238,223,3,100,4,

224,14,52,141,129,239,76,113,8,200,248,105,28,193,125,194,29,

181,249,185,39,106,77,228,166,114,154,201,9,120,101,47,138,

5,33,15,225,36,18,240,130,69,53,147,218,142,150,143,219,189,

54,208,206,148,19,92,210,241,64,70,131,56,102,221,253,48,

191,6,139,98,179,37,226,152,34,136,145,16,126,110,72,195,163,

182,30,66,58,107,40,84,250,133,61,186,43,121,10,21,155,159,

94,202,78,212,172,229,243,115,167,87,175,88,168,80,244,234,

214,116,79,174,233,213,231,230,173,232,44,215,117,122,235,

22,11,245,89,203,95,176,156,169,81,160,127,12,246,111,23,196,

73,236,216,67,31,45,164,118,123,183,204,187,62,90,251,96,

177,134,59,82,161,108,170,85,41,157,151,178,135,144,97,190,

220,252,188,149,207,205,55,63,91,209,83,57,132,60,65,162,109,

71,20,42,158,93,86,242,211,171,68,17,146,217,35,32,46,137,

180,124,184,38,119,153,227,165,103,74,237,222,197,49,254,

24,13,99,140,128,192,247,112,7,

};

word8 Alogtable[256]=

{

1,3,5,15,17,51,85,255,26,46,114,150,161,248,19,53,95,225,

56,72,216,115,149,164,247,2,6,10,30,34,102,170,229,52,92,

228,55,89,235,38,106,190,217,112,144,171,230,49,83,245,4,12,

20,60,68,204,79,209,104,184,211,110,178,205,76,212,103,169,

224,59,77,215,98,166,241,8,24,40,120,136,131,158,185,208,107,

189,220,127,129,152,179,206,73,219,118,154,181,196,87,249,

16,48,80,240,11,29,39,105,187,214,97,163,254,25,43,125,135,

146,173,236,47,113,147,174,233,32,96,160,251,22,58,78,210,

109,183,194,93,231,50,86,250,21,63,65,195,94,226,61,71,201,

64,192,91,237,44,116,156,191,218,117,159,186,213,100,172,239,

42,126,130,157,188,223,122,142,137,128,155,182,193,88,232,

35,101,175,234,37,111,177,200,67,197,84,252,31,33,99,165,

244,7,9,27,45,119,153,176,203,70,202,69,207,74,222,121,139,

134,145,168,227,62,66,198,81,243,14,18,54,90,238,41,123,141,

140,143,138,133,148,167,242,13,23,57,75,221,124,132,151,162,

253,28,36,108,199,82,246,1,

};

word8 S[256]=

{

99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,

118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,

114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,

49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,

9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,

0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,

170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,

146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,

95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,

34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,

36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,

78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,

180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,

14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,

148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,

104,65,153,45,15,176,84,187,22,

};

word8 Si[256]=

{

82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,

124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,

84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,

46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,

248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,

112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,

216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,

30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,

79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,

34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,

113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,

198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,

136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,

74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,

245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,

214,38,225,105,20,99,85,33,12,125,

};

word32 Rc[30]=

{

0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36,

0x6C,0xD8,0xAB,0x4D,0x9A,0x2F,0x5E,0xBC,0x63,0x97,0x35,

0x6A,0xD4,0xB3,0x7D,0xFA,0xEF,0xC5

};

#define MAXBC 8

#define MAXKC 8

#define MAXROUNDS 14

static word8 shifts[5][4]={

0,1,2,3,

0,1,2,3,

0,1,2,3,

0,1,2,4,

0,1,3,4,};

static int numrounds[5][5]={

10,11,12,13,14,

11,11,12,13,14,

12,12,12,13,14,

13,13,13,13,14,

14,14,14,14,14,};

int BC,KC,ROUNDS;

word8 mul(word8 a, word8 b){

//multiply two elements of GF(256)

//required for MixColumns and InvMixColumns

if (ab) return Alogtable[(Logtable[a]+Logtable[b])%255];

else return 0;

}

void AddRoundKey(word8 a[4][MAXBC],word8 rk[4][MAXBC])

{

//XOR corresponding text input and round key input bytes

int i,j;

for(i=0;i4;i++)

for(j=0;jBC;j++)

a[i][j]^=rk[i][j];

}

void SubBytes(word8 a[4][MAXBC],word8 box[256]){

//replace every byte if the input by the byte at that place

//in the non-linear S-box

int i,j;

for(i=0;i4;i++)

for(j=0;iBC;j++)

a[i][j]=box[a[i][j]];

}

void ShiftRows(word8 a[4][MAXBC],word8 d){

//row 0 remains unchanged

//the other three rows are shifted a variable amount

word8 tmp[MAXBC];

int i,j;

if(d==0){

for(i=0;i4;i++){

for(j=0;jBC;j++)

tmp[j]=a[i][(j+shifts[BC-4][i])%BC];

for(j=0;jBC;j++) a[i][j]=tmp[j];

}

}

else {

for (i=0;i4;i++){

for(j=0;jBC;j++)

tmp[j]=a[i][(BC+j-shifts[BC-4][i])%BC];

for(j=0;jBC;j++)

a[i][j]=tmp[j];

}

}

}

int main()

{

return 0;

}

密码制作者Joan Daemen和Vincent Rijmen的书上看到的,版权归出版商和作者,转载请注明出处

如何用C语言编写暴力破解压缩文件解压密码的程序

由于有一个重要的Rar文件,极需解开,首先试用了ARPC,但是解压的速度极慢,每秒只有30个左右,所以断了穷举破解的念头,却仍不死心,因为我从不崇尚穷举破解的方法,除非每秒可以跑几千万次的,我或许可以一试,所以决定研究一下Winrar 3.x密码算法,以期是否可以破解该密码。查看了网络上的资料,包括看雪FAQ里的回答,都声称只能用穷举法破解,起先并不理解,但通过研究,我理解了看雪前辈们在FAQ里所说的原因,不禁让我佩服

Winrar加密思路的成熟。虽然研究的结果没有什么新意,但我还是决定把我的研究结果与大家一起分享,为那些仍然以为winrar密码可以象破解注册码一样的,通过修改winrar弹出框之类的更改文件流程指向可以达到跳过密码检验的朋友,做一个简要的说明。

一、Rar文件生成的流程。

Winrar加密文件时,总的分两个步骤:

 1:先把源文件压缩,压成一段数据段。

 2:再将压缩完的数据段加密。

对于同一个源文件来说,不进行加密,压缩完,其rar文件中的数据段是一模一样的。但是如果对同一个源文件来说,即使使用同一个密码,加密完rar文件中的数据段是不一样的,这是由于加密的密钥是依赖于一个Salt(8个字节的密钥,用来加密时使用,存放在rar文件头中里)

所以要解密rar加密文件关键在于数据解密这一步,那我们接下来研究一下如何加密的。

二、加密“压缩完的数据段”的流程

1、获取密钥:

将明文的密码与Salt一起,通过HASH算法,生成两个16字节的密钥。(一个是KEY(AES算法的参数),一个是initVector)

2、以Key和initVector来加密压缩数据:

这里,是一个循环加密的结构,每16字节作为一个块,进行加密(这可能正是为什么加密完的文件长度总为16倍数的原因)。加密采用AES算法(RAR采用的是AES的rijndael的标准应用)。这里注意:AES加密前,有一个异或运算,是先将每16字节块与上一个16字节块加密结果进行异或,然后再进行AES算法的。我用一个简单的示意代码看说明:

;===============================================

packblock[0]=packblock[i]^initVector

encryptBlock[0]=AES(packblock[0])  ;(KEY为AES的密钥)

for i=1 to 块数量-1

packblock[i]=packblock[i]^encryptBlock[i-1]

encryptBlock[i]=AES(packblock[i]) ;(KEY为AES的密钥)

next

;packblock[i]表示压缩完的每16字节数据

  ;encryptBlock[i]表示加密完的每16字节数据

;===============================================

三、解密的过程

由于AES算法是对称的,所以解密的过程,是加密过程的逆运算。但解密时AES算法过程与加密所用的不一样(是因为解密过程中由KEY生成的子密钥表不一样)。仍然需要我们将密码输入,与salt一起生成两个16字节密钥,KEY和initVector。

;===============================================

packblock[0]=AES1(encryptBlock[0])  ;(KEY为AES的密钥)

packblock[0]=packblock[i]^initVector

for i=1 to 块数量-1

packblock[i]=AES1(encryptBlock[i])  ;(KEY为AES的密钥)

  packblock[i]=packblock[i]^encryptBlock[i-1]

next

;===============================================

那判断密码是否正确的在什么地方呢?

解密的过程是解密后的数据块进行解压缩,然后解成源文件,对该文件进行CRC校验,存在RAR文件中的源文件CRC校验码比较,相同则密码正确,不相同则密码错误。

四、无法秒破的原因

从上面,我们了解了RAR文件的整体思路。地球人都知道,解密时,肯定有个步骤是来判断密码的正确与否。而且,依据以往的经验,我们也许可以将某些判断的点移动,那样可以缩减破解的流程思路。那RAR的这一步在哪里?它把校验放在了最后的一步。如果要秒破,我们该怎么做泥?至少我认为目前是不可能的。

我们从解密过程逆反过来看看:

1、CRC检验这一块修改跳转?根本毫无意义,因为它已经是最后一步了。你可以修改RAR文件头的CRC值,你可以将它改得和你用任意密码解压出来的文件CRC值一样,但你的文件根本就不是原来的文件了。可能已经完全面目全非了。所以,对这一过程不可行。CRC校验本身是不可逆的

2、那么把判断提前到压缩完的数据?

解压的时候,有没有什么来判断压缩数据是否正确?压缩完的数据,有没有固定的特征,是否可以做为解压的判断,在这一步里,我们也无法找到有效的可用的固定特征。因为这一步涉及到RAR的压缩算法。即使一个源文件,即使你的文件前一部分是完全相同的,只对后面的部分进行改过,那么压缩完,数据也是完全一样的。因为压缩完的数据首先是一个压缩表,后面是编码。文件不一样,扫描完的压缩表也不一样,编码又是依赖于压缩表,所以,这里头找不到压缩完的数据有任何的固定特征可以用来判断的。

不管压缩数据是什么样的,Winrar都一如既往地进行解压,没有进行压缩数据是否有效的判断。

3、那假如我们破解了AES了泥?

由于AES只依赖于KEY,如果AES算法被破解了,我们知道了KEY,我们可以解出压缩完的数据,但是这里有一个问题,还有一个initVector密钥,用来第一个16字节块的异或,你没有initVector参数,你第一个16字节块的数据便无法解得出来。

4、那就只能从第一步Hash的算法入手

即使你能破解hash,但hash后的结果泥?没有结果,你怎么返推密码。

所以综上,我发现rar的加密是由hash和AES两种算法互相牵制,而两种算法当前都无法破解,至少目前还没有办法秒破,也理解了看雪高手讲的道理。

五、对穷举提高算法效率的一些设想。

我用汇编写完了RAR穷举解密的算法模块,但是如何提高效率,优化穷举的速度泥?我有如下的想法:

1、从压缩数据里找寻特征,省掉解压缩、CRC检验代码和生成initVector生成代码。目前,通过多次实验,我找到的一个特征(不知道这个是否正确),即解密完的最后一个16字节块的最后一个字节必须为0。因为经过多次的试验,我发现有加密的数据段长度都会比未加密前的数据长,那么,最后一个

16个字节的数据块解密完,多出的部分就都为0,但多出几个字节泥?多次实验,长度不一,我试想着从加密数据段最后一个16个字节块着手,只解这一块,看是否一个字节为0,这样,只解密16个字节的数据,来大大提高效率?如果能进行到这一步了,再通过解全部数据,进行CRC校验的判断。

2、如果第一个特征不成立的话,针对特定格式的压缩文件,比如doc、jpg等,部分数据固定,压缩完的数据是否存在相互牵制的数据?从而把判断提前,这一步,我不知道如何找到压缩完的数据是否存在相互牵制的数据。

求AES算法加密C语言完整程序

恰好我有。能运行的,C语言的。

#include string.h

#include "aes.h"

#include "commonage.h"

#define byte unsigned char

#define BPOLY 0x1b //! Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).

#define BLOCKSIZE 16 //! Block size in number of bytes.

#define KEYBITS 128 //! Use AES128.

#define ROUNDS 10 //! Number of rounds.

#define KEYLENGTH 16 //! Key length in number of bytes.

byte xdata block1[ 256 ]; //! Workspace 1.

byte xdata block2[ 256 ]; //! Worksapce 2.

byte xdata * powTbl; //! Final location of exponentiation lookup table.

byte xdata * logTbl; //! Final location of logarithm lookup table.

byte xdata * sBox; //! Final location of s-box.

byte xdata * sBoxInv; //! Final location of inverse s-box.

byte xdata * expandedKey; //! Final location of expanded key.

void CalcPowLog( byte * powTbl, byte * logTbl )

{

byte xdata i = 0;

byte xdata t = 1;

do {

// Use 0x03 as root for exponentiation and logarithms.

powTbl[i] = t;

logTbl[t] = i;

i++;

// Muliply t by 3 in GF(2^8).

t ^= (t 1) ^ (t 0x80 ? BPOLY : 0);

} while( t != 1 ); // Cyclic properties ensure that i 255.

powTbl[255] = powTbl[0]; // 255 = '-0', 254 = -1, etc.

}

void CalcSBox( byte * sBox )

{

byte xdata i, rot;

byte xdata temp;

byte xdata result;

// Fill all entries of sBox[].

i = 0;

do {

// Inverse in GF(2^8).

if( i 0 ) {

temp = powTbl[ 255 - logTbl[i] ];

} else {

temp = 0;

}

// Affine transformation in GF(2).

result = temp ^ 0x63; // Start with adding a vector in GF(2).

for( rot = 0; rot 4; rot++ ) {

// Rotate left.

temp = (temp1) | (temp7);

// Add rotated byte in GF(2).

result ^= temp;

}

// Put result in table.

sBox[i] = result;

} while( ++i != 0 );

}

void CalcSBoxInv( byte * sBox, byte * sBoxInv )

{

byte xdata i = 0;

byte xdata j = 0;

// Iterate through all elements in sBoxInv using i.

do {

// Search through sBox using j.

cleardog();

do {

// Check if current j is the inverse of current i.

if( sBox[ j ] == i ) {

// If so, set sBoxInc and indicate search finished.

sBoxInv[ i ] = j;

j = 255;

}

} while( ++j != 0 );

} while( ++i != 0 );

}

void CycleLeft( byte * row )

{

// Cycle 4 bytes in an array left once.

byte xdata temp = row[0];

row[0] = row[1];

row[1] = row[2];

row[2] = row[3];

row[3] = temp;

}

void InvMixColumn( byte * column )

{

byte xdata r0, r1, r2, r3;

r0 = column[1] ^ column[2] ^ column[3];

r1 = column[0] ^ column[2] ^ column[3];

r2 = column[0] ^ column[1] ^ column[3];

r3 = column[0] ^ column[1] ^ column[2];

column[0] = (column[0] 1) ^ (column[0] 0x80 ? BPOLY : 0);

column[1] = (column[1] 1) ^ (column[1] 0x80 ? BPOLY : 0);

column[2] = (column[2] 1) ^ (column[2] 0x80 ? BPOLY : 0);

column[3] = (column[3] 1) ^ (column[3] 0x80 ? BPOLY : 0);

r0 ^= column[0] ^ column[1];

r1 ^= column[1] ^ column[2];

r2 ^= column[2] ^ column[3];

r3 ^= column[0] ^ column[3];

column[0] = (column[0] 1) ^ (column[0] 0x80 ? BPOLY : 0);

column[1] = (column[1] 1) ^ (column[1] 0x80 ? BPOLY : 0);

column[2] = (column[2] 1) ^ (column[2] 0x80 ? BPOLY : 0);

column[3] = (column[3] 1) ^ (column[3] 0x80 ? BPOLY : 0);

r0 ^= column[0] ^ column[2];

r1 ^= column[1] ^ column[3];

r2 ^= column[0] ^ column[2];

r3 ^= column[1] ^ column[3];

column[0] = (column[0] 1) ^ (column[0] 0x80 ? BPOLY : 0);

column[1] = (column[1] 1) ^ (column[1] 0x80 ? BPOLY : 0);

column[2] = (column[2] 1) ^ (column[2] 0x80 ? BPOLY : 0);

column[3] = (column[3] 1) ^ (column[3] 0x80 ? BPOLY : 0);

column[0] ^= column[1] ^ column[2] ^ column[3];

r0 ^= column[0];

r1 ^= column[0];

r2 ^= column[0];

r3 ^= column[0];

column[0] = r0;

column[1] = r1;

column[2] = r2;

column[3] = r3;

}

byte Multiply( unsigned char num, unsigned char factor )

{

byte mask = 1;

byte result = 0;

while( mask != 0 ) {

// Check bit of factor given by mask.

if( mask factor ) {

// Add current multiple of num in GF(2).

result ^= num;

}

// Shift mask to indicate next bit.

mask = 1;

// Double num.

num = (num 1) ^ (num 0x80 ? BPOLY : 0);

}

return result;

}

byte DotProduct( unsigned char * vector1, unsigned char * vector2 )

{

byte result = 0;

result ^= Multiply( *vector1++, *vector2++ );

result ^= Multiply( *vector1++, *vector2++ );

result ^= Multiply( *vector1++, *vector2++ );

result ^= Multiply( *vector1 , *vector2 );

return result;

}

void MixColumn( byte * column )

{

byte xdata row[8] = {

0x02, 0x03, 0x01, 0x01,

0x02, 0x03, 0x01, 0x01

}; // Prepare first row of matrix twice, to eliminate need for cycling.

byte xdata result[4];

// Take dot products of each matrix row and the column vector.

result[0] = DotProduct( row+0, column );

result[1] = DotProduct( row+3, column );

result[2] = DotProduct( row+2, column );

result[3] = DotProduct( row+1, column );

// Copy temporary result to original column.

column[0] = result[0];

column[1] = result[1];

column[2] = result[2];

column[3] = result[3];

}

void SubBytes( byte * bytes, byte count )

{

do {

*bytes = sBox[ *bytes ]; // Substitute every byte in state.

bytes++;

} while( --count );

}

void InvSubBytesAndXOR( byte * bytes, byte * key, byte count )

{

do {

// *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.

*bytes = block2[ *bytes ] ^ *key; // Use block2 directly. Increases speed.

bytes++;

key++;

} while( --count );

}

void InvShiftRows( byte * state )

{

byte temp;

// Note: State is arranged column by column.

// Cycle second row right one time.

temp = state[ 1 + 3*4 ];

state[ 1 + 3*4 ] = state[ 1 + 2*4 ];

state[ 1 + 2*4 ] = state[ 1 + 1*4 ];

state[ 1 + 1*4 ] = state[ 1 + 0*4 ];

state[ 1 + 0*4 ] = temp;

// Cycle third row right two times.

temp = state[ 2 + 0*4 ];

state[ 2 + 0*4 ] = state[ 2 + 2*4 ];

state[ 2 + 2*4 ] = temp;

temp = state[ 2 + 1*4 ];

state[ 2 + 1*4 ] = state[ 2 + 3*4 ];

state[ 2 + 3*4 ] = temp;

// Cycle fourth row right three times, ie. left once.

temp = state[ 3 + 0*4 ];

state[ 3 + 0*4 ] = state[ 3 + 1*4 ];

state[ 3 + 1*4 ] = state[ 3 + 2*4 ];

state[ 3 + 2*4 ] = state[ 3 + 3*4 ];

state[ 3 + 3*4 ] = temp;

}

void ShiftRows( byte * state )

{

byte temp;

// Note: State is arranged column by column.

// Cycle second row left one time.

temp = state[ 1 + 0*4 ];

state[ 1 + 0*4 ] = state[ 1 + 1*4 ];

state[ 1 + 1*4 ] = state[ 1 + 2*4 ];

state[ 1 + 2*4 ] = state[ 1 + 3*4 ];

state[ 1 + 3*4 ] = temp;

// Cycle third row left two times.

temp = state[ 2 + 0*4 ];

state[ 2 + 0*4 ] = state[ 2 + 2*4 ];

state[ 2 + 2*4 ] = temp;

temp = state[ 2 + 1*4 ];

state[ 2 + 1*4 ] = state[ 2 + 3*4 ];

state[ 2 + 3*4 ] = temp;

// Cycle fourth row left three times, ie. right once.

temp = state[ 3 + 3*4 ];

state[ 3 + 3*4 ] = state[ 3 + 2*4 ];

state[ 3 + 2*4 ] = state[ 3 + 1*4 ];

state[ 3 + 1*4 ] = state[ 3 + 0*4 ];

state[ 3 + 0*4 ] = temp;

}

void InvMixColumns( byte * state )

{

InvMixColumn( state + 0*4 );

InvMixColumn( state + 1*4 );

InvMixColumn( state + 2*4 );

InvMixColumn( state + 3*4 );

}

void MixColumns( byte * state )

{

MixColumn( state + 0*4 );

MixColumn( state + 1*4 );

MixColumn( state + 2*4 );

MixColumn( state + 3*4 );

}

void XORBytes( byte * bytes1, byte * bytes2, byte count )

{

do {

*bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.

bytes1++;

bytes2++;

} while( --count );

}

void CopyBytes( byte * to, byte * from, byte count )

{

do {

*to = *from;

to++;

from++;

} while( --count );

}

void KeyExpansion( byte * expandedKey )

{

byte xdata temp[4];

byte i;

byte xdata Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.

unsigned char xdata *key;

unsigned char xdata a[16];

key=a;

//以下为加解密密码,共16字节。可以选择任意值

key[0]=0x30;

key[1]=0x30;

key[2]=0x30;

key[3]=0x30;

key[4]=0x30;

key[5]=0x30;

key[6]=0x30;

key[7]=0x30;

key[8]=0x30;

key[9]=0x30;

key[10]=0x30;

key[11]=0x30;

key[12]=0x30;

key[13]=0x30;

key[14]=0x30;

key[15]=0x30;

////////////////////////////////////////////

// Copy key to start of expanded key.

i = KEYLENGTH;

do {

*expandedKey = *key;

expandedKey++;

key++;

} while( --i );

// Prepare last 4 bytes of key in temp.

expandedKey -= 4;

temp[0] = *(expandedKey++);

temp[1] = *(expandedKey++);

temp[2] = *(expandedKey++);

temp[3] = *(expandedKey++);

// Expand key.

i = KEYLENGTH;

while( i BLOCKSIZE*(ROUNDS+1) ) {

// Are we at the start of a multiple of the key size?

if( (i % KEYLENGTH) == 0 ) {

CycleLeft( temp ); // Cycle left once.

SubBytes( temp, 4 ); // Substitute each byte.

XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).

*Rcon = (*Rcon 1) ^ (*Rcon 0x80 ? BPOLY : 0);

}

// Keysize larger than 24 bytes, ie. larger that 192 bits?

#if KEYLENGTH 24

// Are we right past a block size?

else if( (i % KEYLENGTH) == BLOCKSIZE ) {

SubBytes( temp, 4 ); // Substitute each byte.

}

#endif

// Add bytes in GF(2) one KEYLENGTH away.

XORBytes( temp, expandedKey - KEYLENGTH, 4 );

// Copy result to current 4 bytes.

*(expandedKey++) = temp[ 0 ];

*(expandedKey++) = temp[ 1 ];

*(expandedKey++) = temp[ 2 ];

*(expandedKey++) = temp[ 3 ];

i += 4; // Next 4 bytes.

}

}

void InvCipher( byte * block, byte * expandedKey )

{

byte round = ROUNDS-1;

expandedKey += BLOCKSIZE * ROUNDS;

XORBytes( block, expandedKey, 16 );

expandedKey -= BLOCKSIZE;

do {

InvShiftRows( block );

InvSubBytesAndXOR( block, expandedKey, 16 );

expandedKey -= BLOCKSIZE;

InvMixColumns( block );

} while( --round );

InvShiftRows( block );

InvSubBytesAndXOR( block, expandedKey, 16 );

}

void Cipher( byte * block, byte * expandedKey ) //完成一个块(16字节,128bit)的加密

{

byte round = ROUNDS-1;

XORBytes( block, expandedKey, 16 );

expandedKey += BLOCKSIZE;

do {

SubBytes( block, 16 );

ShiftRows( block );

MixColumns( block );

XORBytes( block, expandedKey, 16 );

expandedKey += BLOCKSIZE;

} while( --round );

SubBytes( block, 16 );

ShiftRows( block );

XORBytes( block, expandedKey, 16 );

}

void aesInit( unsigned char * tempbuf )

{

powTbl = block1;

logTbl = block2;

CalcPowLog( powTbl, logTbl );

sBox = tempbuf;

CalcSBox( sBox );

expandedKey = block1; //至此block1用来存贮密码表

KeyExpansion( expandedKey );

sBoxInv = block2; // Must be block2. block2至此开始只用来存贮SBOXINV

CalcSBoxInv( sBox, sBoxInv );

}

//对一个16字节块解密,参数buffer是解密密缓存,chainBlock是要解密的块

void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock )

{

//byte xdata temp[ BLOCKSIZE ];

//CopyBytes( temp, buffer, BLOCKSIZE );

CopyBytes(buffer,chainBlock,BLOCKSIZE);

InvCipher( buffer, expandedKey );

//XORBytes( buffer, chainBlock, BLOCKSIZE );

CopyBytes( chainBlock, buffer, BLOCKSIZE );

}

//对一个16字节块完成加密,参数buffer是加密缓存,chainBlock是要加密的块

void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock )

{

CopyBytes( buffer, chainBlock, BLOCKSIZE );

//XORBytes( buffer, chainBlock, BLOCKSIZE );

Cipher( buffer, expandedKey );

CopyBytes( chainBlock, buffer, BLOCKSIZE );

}

//加解密函数,参数为加解密标志,要加解密的数据缓存起始指针,要加解密的数据长度(如果解密运算,必须是16的整数倍。)

unsigned char aesBlockDecrypt(bit Direct,unsigned char *ChiperDataBuf,unsigned char DataLen)

{

unsigned char xdata i;

unsigned char xdata Blocks;

unsigned char xdata sBoxbuf[256];

unsigned char xdata tempbuf[16];

unsigned long int xdata OrignLen=0; //未加密数据的原始长度

if(Direct==0)

{

*((unsigned char *)OrignLen+3)=ChiperDataBuf[0];

*((unsigned char *)OrignLen+2)=ChiperDataBuf[1];

*((unsigned char *)OrignLen+1)=ChiperDataBuf[2];

*((unsigned char *)OrignLen)=ChiperDataBuf[3];

DataLen=DataLen-4;

}

else

{

memmove(ChiperDataBuf+4,ChiperDataBuf,DataLen);

OrignLen=DataLen;

ChiperDataBuf[0]=OrignLen;

ChiperDataBuf[1]=OrignLen8;

ChiperDataBuf[2]=OrignLen16;

ChiperDataBuf[3]=OrignLen24;

}

cleardog();

aesInit(sBoxbuf); //初始化

if(Direct==0) //解密

{

Blocks=DataLen/16;

for(i=0;iBlocks;i++)

{

cleardog();

aesDecrypt(tempbuf,ChiperDataBuf+4+16*i);

}

memmove(ChiperDataBuf,ChiperDataBuf+4,OrignLen);

cleardog();

return(OrignLen);

}

else //加密

{

if(DataLen%16!=0)

{

Blocks=DataLen/16+1;

//memset(ChiperDataBuf+4+Blocks*16-(DataLen%16),0x00,DataLen%16); //不足16字节的块补零处理

}

else

{

Blocks=DataLen/16;

}

for(i=0;iBlocks;i++)

{

cleardog();

aesEncrypt(tempbuf,ChiperDataBuf+4+16*i);

}

cleardog();

return(Blocks*16+4);

}

}

//#endif

以上是C文件。以下是头文件

#ifndef AES_H

#define AES_H

extern void aesInit( unsigned char * tempbuf );

extern void aesDecrypt(unsigned char *buffer, unsigned char *chainBlock);

extern void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock );

extern void aesInit( unsigned char * tempbuf );

extern void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock );

extern void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock );

extern unsigned char aesBlockDecrypt(bit Direct,unsigned char *ChiperDataBuf,unsigned char DataLen);

#endif // AES_H

这是我根据网上程序改写的。只支持128位加解密。没有使用占内存很多的查表法。故运算速度会稍慢。

AES算法C语言实现,C++不要,求帮助

网上好多嘛

没有做过优化的一抓一大把

随便搜一搜及出来了,还拿100分在这里悬赏

【密码学】C语言实现AES核心步骤

按照AES算法,完成AES算法S盒、行移位、列混合、轮密钥加操作

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES采用对称分组密码体制,密钥的长度最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。

AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。AES加密有很多轮的重复和变换。大致步骤如下:1、密钥扩展(KeyExpansion),2、初始轮(Initial Round),3、重复轮(Rounds),每一轮又包括:字节替代(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)、轮密钥加(AddRoundKey),4、最终轮(Final Round),最终轮没有MixColumns。

AES算法的加密整体结构

字节替代(SubBytes):使用一个S盒进行非线性置换,S盒是一个16×16的矩阵,如表4-9所示。字节替代将输入的状态矩阵的每一个字节通过一个简单查表操作,映射为另外一个字节。

输入字节的前4bits指定S盒的行值,后4bits指定S盒的列值,行和列所确定S盒位置的元素作为输出,例如输入字节“03”,行值为0,列值为3,根据表4-9可知第0行第3列对应的值为 “7B”,因此输出字节为“7B”。

举例

在上面的示例中,第1个基本元素为”F5”,它将被S盒行为第”F行”、列为第”5”列的元素“E6“代替,其余的输出也用相同的方法确定。

状态阵列的4个行循环以字节为基本单位进行左移,而每行循环做移的偏移量是由明文分组的大小和所在行数共同确定,即列数Nb和行号确定。

举例

举例

轮密钥加操作是将密钥与明文按比特异或,轮密钥通过密钥扩展得到

和fips-192(AES)的标准一样

初学者,求高手给一个完整的AES加密解密算法的程序(C/C++) 希望能满足如下要求

/*128bits密钥长度及分组长度AES加解密代码

*作者:Jeffrey.zhu

*/