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

*/

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/181903.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-23 06:43
下一篇 2024-11-23 06:43

相關推薦

  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • Python程序文件的拓展

    Python是一門功能豐富、易於學習、可讀性高的編程語言。Python程序文件通常以.py為文件拓展名,被廣泛應用於各種領域,包括Web開發、機器學習、科學計算等。為了更好地發揮P…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python購物車程序

    Python購物車程序是一款基於Python編程語言開發的程序,可以實現購物車的相關功能,包括商品的添加、購買、刪除、統計等。 一、添加商品 添加商品是購物車程序的基礎功能之一,用…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29

發表回復

登錄後才能評論