AES算法C语言实现源码(带注释)

合集下载

AES加密算法c语言实现代码

AES加密算法c语言实现代码
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++){
AES加密算法c语言实现代码
/*将二进制位串转为长度为8的字符串*/ int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){ int cnt; memset(ch,0,8); for(cnt = 0; cnt < 8; cnt++){
BitToByte(bit+(cnt<<3),ch+cnt); } return 0; }
/*扩充置换表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};
/*对左移次数的规定*/ 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);

AES加密C语言实现代码

AES加密C语言实现代码

#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 KEY_COUNT 3#if KEY_COUNT == 1#define KEYBITS 128 //!< Use AES128.#elif KEY_COUNT == 2#define KEYBITS 192 //!< Use AES196.#elif KEY_COUNT == 3#define KEYBITS 256 //!< Use AES256.#else#error Use 1, 2 or 3 keys!#endif#if KEYBITS == 128#define ROUNDS 10 //!< Number of rounds.#define KEYLENGTH 16 //!< Key length in number of bytes.#elif KEYBITS == 192#define ROUNDS 12 //!< Number of rounds.#define KEYLENGTH 24 //!< // Key length in number of bytes.#elif KEYBITS == 256#define ROUNDS 14 //!< Number of rounds.#define KEYLENGTH 32 //!< Key length in number of bytes.#else#error Key must be 128, 192 or 256 bits!#endif#define EXPANDED_KEY_SIZE (BLOCKSIZE * (ROUNDS+1)) //!< 176, 208 or 240 bytes.unsigned char AES_Key_Table[32] ={0xd0, 0x94, 0x3f, 0x8c, 0x29, 0x76, 0x15, 0xd8,0x20, 0x40, 0xe3, 0x27, 0x45, 0xd8, 0x48, 0xad,0xea, 0x8b, 0x2a, 0x73, 0x16, 0xe9, 0xb0, 0x49,0x45, 0xb3, 0x39, 0x28, 0x0a, 0xc3, 0x28, 0x3c,};unsigned char block1[256]; //!< Workspace 1.unsigned char block2[256]; //!< Worksapce 2.unsigned char tempbuf[256];unsigned char *powTbl; //!< Final location of exponentiation lookup table.unsigned char *logTbl; //!< Final location of logarithm lookup table. unsigned char *sBox; //!< Final location of s-box.unsigned char *sBoxInv; //!< Final location of inverse s-box. unsigned char *expandedKey; //!< Final location of expanded key.void CalcPowLog(unsigned char *powTbl, unsigned char *logTbl) {unsigned char i = 0;unsigned char 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( unsigned char * sBox ){unsigned char i, rot;unsigned char temp;unsigned char 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 = (temp<<1) | (temp>>7);// Add rotated byte in GF(2).result ^= temp;}// Put result in table.sBox[i] = result;} while( ++i != 0 );}void CalcSBoxInv( unsigned char * sBox, unsigned char * sBoxInv ) {unsigned char i = 0;unsigned char j = 0;// Iterate through all elements in sBoxInv using i.do {// Search through sBox using j.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( unsigned char * row ){// Cycle 4 bytes in an array left once.unsigned char temp = row[0];row[0] = row[1];row[1] = row[2];row[2] = row[3];row[3] = temp;}void InvMixColumn( unsigned char * column ){unsigned char 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;}void SubBytes( unsigned char * bytes, unsigned char count ){do {*bytes = sBox[ *bytes ]; // Substitute every byte in state.bytes++;} while( --count );}void InvSubBytesAndXOR( unsigned char * bytes, unsigned char * key, unsigned char 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( unsigned char * state ){unsigned char 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 InvMixColumns( unsigned char * state ){InvMixColumn( state + 0*4 );InvMixColumn( state + 1*4 );InvMixColumn( state + 2*4 );InvMixColumn( state + 3*4 );}void XORBytes( unsigned char * bytes1, unsigned char * bytes2, unsigned char count ) {do {*bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.bytes1++;bytes2++;} while( --count );}void CopyBytes( unsigned char * to, unsigned char * from, unsigned char count ) {do {*to = *from;to++;from++;} while( --count );}void KeyExpansion( unsigned char * expandedKey ){unsigned char temp[4];unsigned char i;unsigned char Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.unsigned char * key = AES_Key_Table;// 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( unsigned char * block, unsigned char * expandedKey ) {unsigned char 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 aesDecInit(void){powTbl = block1;logTbl = block2;CalcPowLog( powTbl, logTbl );sBox = tempbuf;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );sBoxInv = block2; // Must be block2.CalcSBoxInv( sBox, sBoxInv );}void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock ) {unsigned char temp[ BLOCKSIZE ];CopyBytes( temp, buffer, BLOCKSIZE );InvCipher( buffer, expandedKey );XORBytes( buffer, chainBlock, BLOCKSIZE );CopyBytes( chainBlock, temp, BLOCKSIZE );}unsigned char Multiply( unsigned char num, unsigned char factor ){unsigned char mask = 1;unsigned char 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;}unsigned char DotProduct( unsigned char * vector1, unsigned char * vector2 ) {unsigned char result = 0;result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1++, *vector2++ );result ^= Multiply( *vector1 , *vector2 );return result;}void MixColumn( unsigned char * column ){unsigned char row[8] = {0x02, 0x03, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01};// Prepare first row of matrix twice, to eliminate need for cycling.unsigned char 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 MixColumns( unsigned char * state ){MixColumn( state + 0*4 );MixColumn( state + 1*4 );MixColumn( state + 2*4 );MixColumn( state + 3*4 );}void ShiftRows( unsigned char * state ){unsigned char 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 Cipher( unsigned char * block, unsigned char * expandedKey ) {unsigned char 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 aesEncInit(void){powTbl = block1;logTbl = tempbuf;CalcPowLog( powTbl, logTbl );sBox = block2;CalcSBox( sBox );expandedKey = block1;KeyExpansion( expandedKey );}void aesEncrypt( unsigned char * buffer, unsigned char * chainBlock ) {XORBytes( buffer, chainBlock, BLOCKSIZE );Cipher( buffer, expandedKey );CopyBytes( chainBlock, buffer, BLOCKSIZE );}#include <string.h>void AES_Test(void){unsigned char dat[16]="0123456789ABCDEF";unsigned char chainCipherBlock[16];unsigned char i;for(i=0;i<32;i++) AES_Key_Table[i]=i;//做运算之前先要设置好密钥,这里只是设置密钥的DEMO。

AES加密算法源代码

AES加密算法源代码

AES加密算法源代码AES加密算法源代码//AES.h#define decrypt TRUE#define encrypt FALSE#define TYPE BOOLtypedef struct _AES{int Nb;int Nr;int Nk;unsigned long *Word;unsigned long *State;}AES;/*加密数据byte *input 明文byte *inSize 明文长byte *out 密文存放的地方byte *key 密钥keybyte *keySize 密钥长*/void Cipher(unsigned char* input,int inSize,unsigned char* out,unsigned char* key,int keySize);/*解密数据byte *input 密文int *inSize 密文长byte *out 明文存放的地方byte *key 密钥keyint *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 密钥keybyte *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 密钥keyint *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 wordmemcpy(w,key,Nk<<2);unsigned long temp;for (int c = Nk; c < Nb * (Nr+1); ++c){//把上一轮的最后一行放入temptemp = w[c-1];//判断是不是每一轮密钥的第一行if (c % Nk == 0){//左旋8位temp = (temp<<8)|(temp>>24);//查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");}。

C语言利用OpenSSL实现AES加解密源代码

C语言利用OpenSSL实现AES加解密源代码

#include <stdlib.h>#include <stdio.h>#include <iostream>#include <string>#include <cassert>#include <Windows.h>#include <tchar.h>#include <conio.h>#include <openssl\aes.h>#include <openssl\rand.h>#include <openssl\evp.h>#pragma comment(lib,"libeay32.lib")#pragma comment(lib,"ssleay32.lib")#define BIG_TEST_SIZE 10240using namespace std;std::string EncodeAES( /*const std::string&*/char * strPassword, const std::string& strData){AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8 *//*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;for (unsigned int i = 0; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);unsigned char out[AES_BLOCK_SIZE];AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}return strRet;}std::string EncodeAES_little( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0)assert(false);return "";}unsigned char out[AES_BLOCK_SIZE];AES_encrypt((const unsigned char*)strData.c_str(), out, &aes_key);return std::string((const char*)out);}std::string EncodeAES_Big( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_encrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8 *//*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;unsigned int i = 0;std::string str16;unsigned char out[AES_BLOCK_SIZE];for (; i < strData.length() / AES_BLOCK_SIZE; i++){str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}str16 = strData.substr(i*AES_BLOCK_SIZE, strData.length() - i*AES_BLOCK_SIZE);AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);cout << "*************:" << str16 << endl;cout << "strRet.length() = " << strRet.length() << endl;return strRet;}std::string DecodeAES( /*const std::string&*/char * strPassword, const std::string& strData){AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0)assert(false);return "";}std::string strRet;for (unsigned int i = 0; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);unsigned char out[AES_BLOCK_SIZE];AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}return strRet;}std::string DecodeAES_little( /*const std::string&*/char * strPassword, const std::string& strData) {AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}unsigned char out[AES_BLOCK_SIZE];AES_decrypt((const unsigned char*)strData.c_str(), out, &aes_key);return std::string((const char*)out);}std::string DecodeAES_Big( /*const std::string&*/char * strPassword, const std::string& strData) {cout << "strData.length() = " << strData.length() << endl;AES_KEY aes_key;if (AES_set_decrypt_key((const unsigned char*)strPassword, AES_BLOCK_SIZE * 8/*strlen(strPassword)*8*/ /*strPassword.length() * 8*/, &aes_key) < 0){assert(false);return "";}std::string strRet;unsigned int i = 0;unsigned char out[AES_BLOCK_SIZE];for (; i < strData.length() / AES_BLOCK_SIZE; i++){std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);}std::string str16 = strData.substr(i*AES_BLOCK_SIZE, strData.length() - i*AES_BLOCK_SIZE);AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);strRet += std::string((const char*)out, AES_BLOCK_SIZE);return strRet;}int main(int argc, _TCHAR* argv[]){system("cls");std::string buf;cout << "请输入待加密字符串:" << endl;getline(cin, buf);char userkey[AES_BLOCK_SIZE];//std::string userkey;RAND_pseudo_bytes((unsigned char*)userkey, sizeof userkey);std::string encrypt_data;std::string decrypt_data;cout << "输入的字符串长度与16比较大小:" << endl;if (buf.length() % 16 == 0){cout << "等于16 " << endl;encrypt_data = EncodeAES(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}else{if (buf.length()<16){cout << "小于16 " << endl;encrypt_data = EncodeAES_little(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES_little(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}else{cout << "大于16 " << endl;encrypt_data = EncodeAES_Big(userkey, buf);cout << "加密:" << endl;cout << encrypt_data << endl;decrypt_data = DecodeAES_Big(userkey, encrypt_data);cout << "解密:" << endl;cout << decrypt_data << endl;}}getchar();return 0;}。

AES加解密C语言程序

AES加解密C语言程序

0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d, 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0xe4, 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0, 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26, 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d, }; /*The key schedule rcon table*/ static const unsigned char Rcon[10]={ 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};

AES算法C语言讲解与实现

AES算法C语言讲解与实现

AES算法C语言讲解与实现AES(Advanced Encryption Standard)是一种对称加密算法,被广泛应用于各种应用中,如保护通信、数据安全等。

AES算法采用分组密码的方式,将明文数据分成若干个大小相等的分组,然后对每个分组进行加密操作。

1. 密钥扩展(Key Expansion):AES算法中使用的密钥长度分为128位、192位和256位三种,密钥长度不同,密钥扩展的轮数也不同。

根据密钥长度,需要扩展成多少个轮密钥。

扩展过程中需要进行字节代换、循环左移、模2乘法等操作。

2. 子密钥生成(Subkey Generation):根据密钥扩展的结果,生成每一轮需要使用的子密钥。

3. 字节替换(SubBytes):将每个字节替换为S盒中对应的值。

S盒是一个固定的预先计算好的查找表。

4. 行移位(ShiftRows):对矩阵的行进行循环左移,左移的位数根据行数而定。

5. 列混合(MixColumns):将每列的四个字节进行混合。

混合操作包括乘法和异或运算。

6. 轮密钥加(AddRoundKey):将每一轮得到的结果与轮密钥进行异或运算。

以上就是AES算法的六个步骤的实现过程,下面我们来具体讲解一下。

首先,我们需要定义一些辅助函数,如字节代换函数、循环左移函数等。

```cuint8_t substitution(uint8_t byte) return sBox[byte];void shiftRows(uint8_t *state)uint8_t temp;//第二行循环左移1位temp = state[1];state[1] = state[5];state[5] = state[9];state[9] = state[13];state[13] = temp;//第三行循环左移2位temp = state[2];state[2] = state[10];state[10] = temp;temp = state[6];state[6] = state[14];state[14] = temp;//第四行循环左移3位temp = state[15];state[15] = state[11];state[11] = state[7];state[7] = state[3];state[3] = temp;void mixColumns(uint8_t *state)int i;uint8_t temp[4];for(i = 0; i < 4; i++)temp[0] = xTime(state[i * 4]) ^ xTime(state[i * 4 + 1]) ^ state[i * 4 + 1] ^state[i * 4 + 2] ^ state[i * 4 + 3];temp[1] = state[i * 4] ^ xTime(state[i * 4 + 1]) ^xTime(state[i * 4 + 2]) ^state[i * 4 + 2] ^ state[i * 4 + 3];temp[2] = state[i * 4] ^ state[i * 4 + 1] ^ xTime(state[i * 4 + 2]) ^xTime(state[i * 4 + 3]) ^ state[i * 4 + 3];temp[3] = xTime(state[i * 4]) ^ state[i * 4] ^ state[i * 4 + 1] ^state[i * 4 + 2] ^ xTime(state[i * 4 + 3]);state[i * 4] = temp[0];state[i * 4 + 1] = temp[1];state[i * 4 + 2] = temp[2];state[i * 4 + 3] = temp[3];}```接下来,我们实现密钥扩展和子密钥生成的过程。

AES加密算法(C++实现,附源码)

AES加密算法(C++实现,附源码)

AES加密算法(C++实现,附源码)原创作品,转载请注明出⾃博客地址:本⽂地址:快毕业了,最后⼀个课程设计,《基于Windows Socket的安全通信》,内容就是基于AES加密的SOCKET通信,貌似挺简单,不过要⽤VC++6.0开发,C++我确实没有任何代码经验,虽然不是强制性,但由于机房⾥各种纠结,只能⽤它了(⽤Java没有挑战性,封装得太好了...也算熟悉下VC++吧)先搞定AES算法,基本变换包括SubBytes(字节替代)、ShiftRows(⾏移位)、MixColumns(列混淆)、AddRoundKey(轮密钥加)其算法⼀般描述为明⽂及密钥的组织排列⽅式ByteSubstitution(字节替代)⾮线性的字节替代,单独处理每个字节:求该字节在有限域GF(28)上的乘法逆,"0"被映射为⾃⾝,即对于α∈GF(28),求β∈GF(28),使得α·β=β·α=1mod(x 8+x 4+x 2+x+1)。

对上⼀步求得的乘法逆作仿射变换y i =x i + x (i+4)mod8 + x (i+6)mod8 + x (i+7)mod8 + c i(其中c i 是6310即011000112的第i位),⽤矩阵表⽰为本来打算把求乘法逆和仿射变换算法敲上去,最后还是放弃了...直接打置换表12345678910111213141516171819unsigned char sBox[] ={ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, /*0*/0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, /*1*/0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, /*2*/ 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, /*3*/ 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, /*4*/0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, /*5*/0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, /*6*/0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, /*7*/0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, /*8*/ 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, /*9*/ 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, /*a*/0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, /*b*/0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, /*c*/0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, /*d*/ 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, /*e*/ 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 /*f*/};下⾯是逆置换表,解密时使⽤12345678*********unsigned char invsBox[256] ={ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, /*0*/ 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, /*1*/ 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, /*2*/0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, /*3*/0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, /*4*/0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, /*5*/ 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, /*6*/ 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, /*7*/ 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, /*8*/0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, /*9*/0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, /*a*/ 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, /*b*/14 15 16 17 18 19 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, /*c*/ 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, /*d*/ 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, /*e*/ 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d /*f*/ };这⾥遇到问题了,本来⽤纯c初始化数组很正常,封装成类以后发现不能初始化,不管是声明、构造函数都⽆法初始化,百歌⾕度了⼀通后没有任何答案,⽆奈只能在构造函数中声明⼀个局部变量数组并初始化,然后⽤memcpy,(成员变量名为Sbox/InvSbox,局部变量名sBox/invsBox)12 3 4 5 6 7 8 9 10 11void AES::SubBytes(unsigned char state[][4]) {int r,c;for(r=0; r<4; r++){for(c=0; c<4; c++){state[r][c] = Sbox[state[r][c]];}}}ShiftRows(⾏移位变换)⾏移位变换完成基于⾏的循环位移操作,变换⽅法:即⾏移位变换作⽤于⾏上,第0⾏不变,第1⾏循环左移1个字节,第2⾏循环左移2个字节,第3⾏循环左移3个字节。

AES算法C语言讲解与实现

AES算法C语言讲解与实现

AES算法C语言讲解与实现
$$AES(Advanced Encryption Standard,高级加密标准)又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

AES是一种使用密钥加密的对称性算法,可以使用128位、192位、256位三种长度的密钥,其分组处理的块(block)长度分别为128、192、256bit,由10轮、12轮和14轮加密循环组成,每轮加密循环中采用4
个复合的函数,同时增加密钥的长度。

1.生成口令
首先,在实施AES算法之前,需要生成一个口令,口令是一段由字符
组成的字符串,口令长度需要符合以下要求:128位(16字节),192位(24字节)或256位(32字节)。

2.密钥扩展
由口令生成一系列较长的子密钥。

AES使用一个迭代的函数从口令中
派生出4个较长的密码子串,这些子串以256-bit、192-bit或128-bit
形式组成,此处子串的长度与加密块的长度相同,它们是AES算法执行时
所需要的参数,具体派生步骤可参见下图:
3.加密
AES的加密算法分成10轮,每一轮加密分为三个执行步骤:字节代换、行移位和列混合。

AES解密算法与加密算法一样,也分为10轮,但是解密算法的每一
轮的步骤是加密算法的步骤的逆序。

4.结果
接着加密完成后,AES算法会产生一个新的128位的块作为加密的结果。

AES算法的C语言实现

AES算法的C语言实现
( (uint32) MUL( 0x09, y ) << 16 ) ^
( (uint32) MUL( 0x0E, y ) << 24 );
RT0[i] &= 0xFFFFFFFF;
RT1[i] = ROTR8( RT0[i] );
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, uint32 Fra bibliotekT3[256];
/* reverse S-box & tables */
uint32 RSb[256];
uint32 RT0[256];
uint32 RT1[256];
uint32 RT2[256];
uint32 RT3[256];
/* round constants */
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
x ^= y; y = ( y << 1 ) | ( y >> 7 );
x ^= y ^ 0x63;
FSb[i] = x;
RSb[x] = i;
}
/* generate the forward and reverse tables */

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

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

AES算法加密C语言完整程序#包括〈字符串。

"#包括AES。

"#包括“大众。

”#定义字节无符号字符#定义 bpoly OxlB / /!〈下 8 位(x 8X 1 X4+3+1),艮[I (x+4+x + 3 + x+x)。

#定义块16 / /!〈字节大小的块大小。

#定义 keybits 128 / /!〈使用 AES128。

#定义轮10 / /!轮数。

#定义keylength 16 / /!字节长度的键长度。

字节XDATA酒店[256 ]; //!〈工作区1。

字节数据块 2 [ 256 ]; //! < worksapce 2。

字节数据* powtbl; / /!〈最后位置指数表。

字节数据* logtbl; / /!对数查找表的最后位置。

字节数据* S盒;/ /! < S盒的最终位置。

字节数据* sboxinv; / / !〈逆S盒的最终位置。

字节数据* Expandedkey; / /!〈扩展键的最后位置。

CalcPowLog (* powtbl 无效字节,字节* logtbl){我二0字节数据;T = 1字节数据;做{/ /使用0x03作为幕和对数根。

powtbl [我]=T;logtbl [T]二我;++;/ / muliply T 3在 GF (2 " 8)。

T " = (t<<l) " (T & 0x80? bpoly: 0);} (t! = 1);循环属性确保i〈 255o powtbl [ 255 ] = powtbl [ 0 ]; / / 255 = - 0, 254 - 1, 虚空CalcSBox (字节* S盒)字节数据我,腐;字节数据的温度;字节的数据结果;/ /填写参赛方法[]o我=0;做{/反转 GF (2X8)。

如果(i = 0) {温度=powtbl [ 255 ] logtbl [我];其他{ }温度=0;}/GF (2)的仿射变换。

AES加密C语言实现代码

AES加密C语言实现代码

AES加密C语言实现代码以下是一个简单的C语言实现AES加密算法的代码:```c#include <stdio.h>#include <stdlib.h>#include <stdint.h>//定义AES加密的轮数#define NR 10//定义AES加密的扩展密钥长度#define Nk 4//定义AES加密的行数和列数#define Nb 4//定义AES加密的状态矩阵typedef uint8_t state_t[4][4];//定义AES加密的S盒变换表static const uint8_t sbox[256] =//S盒变换表};//定义AES加密的轮常量表static const uint8_t Rcon[11] =//轮常量表};//定义AES加密的密钥扩展变换函数void KeyExpansion(const uint8_t* key, uint8_t* expandedKey) uint32_t* ek = (uint32_t*)expandedKey;uint32_t temp;//密钥拷贝到扩展密钥中for (int i = 0; i < Nk; i++)ek[i] = (key[4 * i] << 24) , (key[4 * i + 1] << 16) ,(key[4 * i + 2] << 8) , (key[4 * i + 3]);}//扩展密钥生成for (int i = Nk; i < Nb * (NR + 1); i++)temp = ek[i - 1];if (i % Nk == 0)//对上一个密钥的字节进行循环左移1位temp = (temp >> 8) , ((temp & 0xFF) << 24);//对每个字节进行S盒变换temp = (sbox[temp >> 24] << 24) , (sbox[(temp >> 16) & 0xFF] << 16) , (sbox[(temp >> 8) & 0xFF] << 8) , sbox[temp & 0xFF];// 取轮常量Rcontemp = temp ^ (Rcon[i / Nk - 1] << 24);} else if (Nk > 6 && i % Nk == 4)//对每个字节进行S盒变换temp = (sbox[temp >> 24] << 24) , (sbox[(temp >> 16) & 0xFF] << 16) , (sbox[(temp >> 8) & 0xFF] << 8) , sbox[temp & 0xFF];}//生成下一个密钥ek[i] = ek[i - Nk] ^ temp;}//定义AES加密的字节替换函数void SubBytes(state_t* state)for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[i][j] = sbox[(*state)[i][j]];}}//定义AES加密的行移位函数void ShiftRows(state_t* state) uint8_t temp;//第2行循环左移1位temp = (*state)[1][0];(*state)[1][0] = (*state)[1][1]; (*state)[1][1] = (*state)[1][2]; (*state)[1][2] = (*state)[1][3]; (*state)[1][3] = temp;//第3行循环左移2位temp = (*state)[2][0];(*state)[2][0] = (*state)[2][2]; (*state)[2][2] = temp;temp = (*state)[2][1];(*state)[2][1] = (*state)[2][3]; (*state)[2][3] = temp;//第4行循环左移3位temp = (*state)[3][0];(*state)[3][0] = (*state)[3][3];(*state)[3][3] = (*state)[3][2];(*state)[3][2] = (*state)[3][1];(*state)[3][1] = temp;//定义AES加密的列混淆函数void MixColumns(state_t* state)uint8_t temp, tmp, tm;for (int i = 0; i < 4; i++)tmp = (*state)[i][0];tm = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;temp = (*state)[i][0] ^ (*state)[i][1];(*state)[i][0] ^= temp ^ tm;temp = (*state)[i][1] ^ (*state)[i][2];(*state)[i][1] ^= temp ^ tm;temp = (*state)[i][2] ^ (*state)[i][3];(*state)[i][2] ^= temp ^ tm;temp = (*state)[i][3] ^ tmp;(*state)[i][3] ^= temp ^ tm;}//定义AES加密的轮密钥加函数void AddRoundKey(state_t* state, const uint8_t* roundKey) for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[j][i] ^= roundKey[i * 4 + j];}}//定义AES加密函数void AES_Encrypt(const uint8_t* plainText, const uint8_t* key, uint8_t* cipherText)state_t* state = (state_t*)cipherText;uint8_t expandedKey[4 * Nb * (NR + 1)];//密钥扩展KeyExpansion(key, expandedKey);//初始化状态矩阵for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)(*state)[j][i] = plainText[i * 4 + j];}}//第1轮密钥加AddRoundKey(state, key);//迭代执行第2至第10轮加密for (int round = 1; round < NR; round++) SubBytes(state);ShiftRows(state);MixColumns(state);AddRoundKey(state, expandedKey + round * 16); }//执行第11轮加密SubBytes(state);ShiftRows(state);AddRoundKey(state, expandedKey + NR * 16);int maiuint8_t plainText[16] =//明文数据};uint8_t key[16] =//密钥数据};uint8_t cipherText[16];AES_Encrypt(plainText, key, cipherText);。

AES算法C语言实现源码

AES算法C语言实现源码

AES算法C语言实现源码/*AES-128 bit CBC Encryptionby Jacob Lister - Mar. 2024AES128-CBC Encryption for CNOTE: This is a C implementation with minimal cost checking, designed for embedded systems with tight code space constraintsgcc -Wall -c aes.cDescription:This code is the implementation of the AES128 algorithm,specifically ECB and CBC mode. ECB stands for ElectronicCode Book mode, which is essentially plain AES encryption.CBC (Cipher Block Chaining) is a mode that allows forenhanced security.*/#include <stdio.h>#include <stdlib.h>#include <string.h>typedef unsigned char AES_BYTE;/*constant in AES. Value=4*/#define Nb 4/* The number of 32 bit words in a key. */#define Nk 4/*Key length in bytes [128 bit](Nk * 4), or 16 bytes.*/#define KEYLEN 16/*The number of rounds in AES Cipher.Number of rounds=10, 12, 14.*/#define Nr 14AES_BYTE * AES_Encrypt(AES_BYTE *plainText, AES_BYTE *key); AES_BYTE * AES_Decrypt(AES_BYTE *cipherText, AES_BYTE *key);Function to store the round keysgenerated from the cipher key.*/void AES_KeyExpansion(AES_BYTE key[4*Nk], AES_BYTE roundKey[4*Nb*(Nr+1)]);/*Cipher is the main function that encryptsthe plaintext given the key [128 bit].*/void AES_Cipher(AES_BYTE *in, AES_BYTE *out, AES_BYTE *roundKey);/*The SubBytes Function is usedto substitute each byte of the statewith its corresponding byte in theRijndael S-box.*/void SubBytes(AES_BYTE *state);The ShiftRows function is usedto shift the rows cyclically aroundthe state.*/void ShiftRows(AES_BYTE *state);/*The MixColumns function is usedto mix the columns of the statematrix.*/void MixColumns(AES_BYTE *state);/*The AddRoundKey function is usedto add round key word to thestate matrix to produce the output.*/void AddRoundKey(AES_BYTE *state, AES_BYTE* roundKey); /*The SubBytes Function is usedto substitute each byte of the state with its inverse in the Rijndael S-box. */void InvSubBytes(AES_BYTE *state);/*The InvShiftRows function is usedto shift the rows cyclically aroundthe state in the opposite direction.*/void InvShiftRows(AES_BYTE *state);/*The InvMixColumns function is usedto mix the columns of the statematrix in the opposite direction.*/void InvMixColumns(AES_BYTE *state);/*The AES_Encrypt functionencrypts the plaintext usingthe provided AES_128 encryptionkey.*/AES_BYTE* AES_Encrypt(AES_BYTE *plainText, AES_BYTE *key) //struct to store ciphertextAES_BYTE *cipherText;int stat_len = 4 * Nb;// The KeyExpansion routine must be called// before encryption.AES_BYTE roundKey[4 * Nb * (Nr + 1)];。

AES C-代码

AES C-代码

/* This is an implementation of the RIJNDAEL cryptosystemfor 128 bit plaintext block.This programme only gives the instance of 128 bit key.You can modify a little details to meet your need for 192or 256 bit key input */#include "stdio.h"typedef unsigned char u1byte; /* an 8 bit unsigned character type */typedef unsigned long u4byte; /* a 32 bit unsigned integer type */#define LARGE_TABLESu1byte pow_tab[256];u1byte log_tab[256];u1byte sbx_tab[256];u1byte isb_tab[256];u4byte rco_tab[ 10];u4byte ft_tab[4][256];u4byte it_tab[4][256];#ifdef LARGE_TABLESu4byte fl_tab[4][256];u4byte il_tab[4][256];#endifu4byte tab_gen = 0;u4byte k_len;u4byte e_key[60];u4byte d_key[60];#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) #define byte(x,n) ((u1byte)((x) >> (8 * n)))#define f_rn(bo, bi, n, k) \bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)#define i_rn(bo, bi, n, k) \bo[n] = it_tab[0][byte(bi[n],0)] ^ \it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))#ifdef LARGE_TABLES#define ls_box(x) \( fl_tab[0][byte(x, 0)] ^ \fl_tab[1][byte(x, 1)] ^ \fl_tab[2][byte(x, 2)] ^ \fl_tab[3][byte(x, 3)] )#define f_rl(bo, bi, n, k) \bo[n] = fl_tab[0][byte(bi[n],0)] ^ \fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)#define i_rl(bo, bi, n, k) \bo[n] = il_tab[0][byte(bi[n],0)] ^ \il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)#else#define ls_box(x) \((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \((u4byte)sbx_tab[byte(x, 3)] << 24)#define f_rl(bo, bi, n, k) \bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)#define i_rl(bo, bi, n, k) \bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n) #endifvoid gen_tabs(void){ u4byte i, t;u1byte p, q;/* log and power tables for GF(2**8) finite field with *//* 0x11b as modular polynomial - the simplest prmitive *//* root is 0x11, used here to generate the tables */for(i = 0,p = 1; i < 256; ++i){pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);}log_tab[1] = 0; p = 1;for(i = 0; i < 10; ++i){rco_tab[i] = p;p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);}/* note that the affine byte transformation matrix in *//* rijndael specification is in big endian format with *//* bit 0 as the most significant bit. In the remainder *//* of the specification the bits are numbered from the *//* least significant end of a byte. */for(i = 0; i < 256; ++i){p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;q = (q >> 7) | (q << 1); p ^= q;q = (q >> 7) | (q << 1); p ^= q;q = (q >> 7) | (q << 1); p ^= q;q = (q >> 7) | (q << 1); p ^= q ^ 0x63;sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;}for(i = 0; i < 256; ++i){p = sbx_tab[i];#ifdef LARGE_TABLESt = p; fl_tab[0][i] = t;fl_tab[1][i] = rotl(t, 8);fl_tab[2][i] = rotl(t, 16);fl_tab[3][i] = rotl(t, 24);#endift = ((u4byte)ff_mult(2, p)) |((u4byte)p << 8) |((u4byte)p << 16) |((u4byte)ff_mult(3, p) << 24);ft_tab[0][i] = t;ft_tab[1][i] = rotl(t, 8);ft_tab[2][i] = rotl(t, 16);ft_tab[3][i] = rotl(t, 24);p = isb_tab[i];#ifdef LARGE_TABLESt = p; il_tab[0][i] = t;il_tab[1][i] = rotl(t, 8);il_tab[2][i] = rotl(t, 16);il_tab[3][i] = rotl(t, 24);#endift = ((u4byte)ff_mult(14, p)) |((u4byte)ff_mult( 9, p) << 8) | ((u4byte)ff_mult(13, p) << 16) | ((u4byte)ff_mult(11, p) << 24);it_tab[0][i] = t;it_tab[1][i] = rotl(t, 8);it_tab[2][i] = rotl(t, 16);it_tab[3][i] = rotl(t, 24);}tab_gen = 1;}#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)#define imix_col(y,x) \u = star_x(x); \v = star_x(u); \w = star_x(v); \t = w ^ (x); \(y) = u ^ v ^ w; \(y) ^= rotr(u ^ t, 8) ^ \rotr(v ^ t, 16) ^ \rotr(t,24)/* initialise the key schedule from the user supplied key */#define loop4(i) \{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \}#define loop6(i) \{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \}#define loop8(i) \{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \t = e_key[8 * i + 4] ^ ls_box(t); \e_key[8 * i + 12] = t; \t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \}void set_key(const u4byte in_key[], const u4byte key_len){ u4byte i, t, u, v, w;if(!tab_gen)gen_tabs();k_len = (key_len + 31) / 32;e_key[0] = in_key[0]; e_key[1] = in_key[1];e_key[2] = in_key[2]; e_key[3] = in_key[3];switch(k_len){case 4: t = e_key[3];for(i = 0; i < 10; ++i)loop4(i);break;case 6: e_key[4] = in_key[4]; t = e_key[5] = in_key[5]; for(i = 0; i < 8; ++i)loop6(i);break;case 8: e_key[4] = in_key[4]; e_key[5] = in_key[5];e_key[6] = in_key[6]; t = e_key[7] = in_key[7]; for(i = 0; i < 7; ++i)loop8(i);break;}d_key[0] = e_key[0]; d_key[1] = e_key[1];d_key[2] = e_key[2]; d_key[3] = e_key[3];for(i = 4; i < 4 * k_len + 24; ++i){imix_col(d_key[i], e_key[i]);}}/* encrypt a block of text */#define f_nround(bo, bi, k) \f_rn(bo, bi, 0, k); \f_rn(bo, bi, 1, k); \f_rn(bo, bi, 2, k); \f_rn(bo, bi, 3, k); \k += 4#define f_lround(bo, bi, k) \f_rl(bo, bi, 0, k); \f_rl(bo, bi, 1, k); \f_rl(bo, bi, 2, k); \f_rl(bo, bi, 3, k)void encrypt(const u4byte in_blk[4], u4byte out_blk[4]){ u4byte b0[4], b1[4], *kp;b0[0] = in_blk[0] ^ e_key[0]; b0[1] = in_blk[1] ^ e_key[1]; b0[2] = in_blk[2] ^ e_key[2]; b0[3] = in_blk[3] ^ e_key[3];kp = e_key + 4;if(k_len > 6){f_nround(b1, b0, kp); f_nround(b0, b1, kp);}if(k_len > 4){f_nround(b1, b0, kp); f_nround(b0, b1, kp);}f_nround(b1, b0, kp); f_nround(b0, b1, kp);f_nround(b1, b0, kp); f_nround(b0, b1, kp);f_nround(b1, b0, kp); f_nround(b0, b1, kp);f_nround(b1, b0, kp); f_nround(b0, b1, kp);f_nround(b1, b0, kp); f_lround(b0, b1, kp);out_blk[0] = b0[0]; out_blk[1] = b0[1];out_blk[2] = b0[2]; out_blk[3] = b0[3];}/* decrypt a block of text */#define i_nround(bo, bi, k) \i_rn(bo, bi, 0, k); \i_rn(bo, bi, 1, k); \i_rn(bo, bi, 2, k); \i_rn(bo, bi, 3, k); \k -= 4#define i_lround(bo, bi, k) \i_rl(bo, bi, 0, k); \i_rl(bo, bi, 1, k); \i_rl(bo, bi, 2, k); \i_rl(bo, bi, 3, k)void decrypt(const u4byte in_blk[4], u4byte out_blk[4]){ u4byte b0[4], b1[4], *kp;b0[0] = in_blk[0] ^ e_key[4 * k_len + 24]; b0[1] = in_blk[1] ^ e_key[4 * k_len + 25]; b0[2] = in_blk[2] ^ e_key[4 * k_len + 26]; b0[3] = in_blk[3] ^ e_key[4 * k_len + 27];kp = d_key + 4 * (k_len + 5);if(k_len > 6){i_nround(b1, b0, kp); i_nround(b0, b1, kp);}if(k_len > 4){i_nround(b1, b0, kp); i_nround(b0, b1, kp);}i_nround(b1, b0, kp); i_nround(b0, b1, kp);i_nround(b1, b0, kp); i_nround(b0, b1, kp);i_nround(b1, b0, kp); i_nround(b0, b1, kp);i_nround(b1, b0, kp); i_nround(b0, b1, kp);i_nround(b1, b0, kp); i_lround(b0, b1, kp);out_blk[0] = b0[0]; out_blk[1] = b0[1];out_blk[2] = b0[2]; out_blk[3] = b0[3];}/* use data to test programme */void main( ){ int i;u4byte out_block[4];c onst u4byte in_key[4]={0x11111111,0x22222222,0x33333333,0x44444444};const u4byte plain_block[4]={0x12121212,0x34343434,0x45454545,0x56565656}; const u4byte cipher_block[4]={0x844050f7,0xe346a4ff,0x375104da,0xabb97f8b};printf("--------------------------------------------\n");set_key(in_key, 128);encrypt(plain_block, out_block);printf("Encryptions:\n");for(i=0;i<4;i++)printf("%x ",out_block[i]);decrypt(cipher_block, out_block);printf("\nDecryptions:\n");for(i=0;i<4;i++)printf("%x ",out_block[i]);}。

aes算法c语言实现

aes算法c语言实现

aes算法c语言实现AES(Advanced Encryption Standard)是一种广泛应用于数据加密的算法。

以下是一个使用C语言实现的AES加密算法示例,用于对字符串进行加密和解密。

这个实现是基于ECB模式的,这是一种常用的加密模式,因为它简单且易于实现。

注意:这个实现是为了教学目的而提供的,可能不适合用于生产环境。

生产环境中的加密实现通常需要更复杂和安全的方法。

```c #include <stdio.h> #include <string.h> #include <stdint.h> #include <openssl/aes.h>void AES_encrypt(const uint8_t *key, const uint8_t*plaintext, uint8_t *ciphertext) { AES_KEY aesKey; AES_set_encrypt_key(key, 128, &aesKey);AES_encrypt(plaintext, ciphertext, &aesKey); }void AES_decrypt(const uint8_t *key, const uint8_t*ciphertext, uint8_t *plaintext) { AES_KEY aesKey; AES_set_decrypt_key(key, 128, &aesKey);AES_decrypt(ciphertext, plaintext, &aesKey); }int main() { // 定义密钥和明文/密文缓冲区uint8_t key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE是AES算法的块大小,通常是16字节(128位) uint8_tplaintext[AES_BLOCK_SIZE], ciphertext[AES_BLOCK_SIZE];// 填充密钥和明文/密文缓冲区 // 这里省略了填充代码,因为在实际应用中,你应该使用合适的填充方案来保护数据的完整性。

AES加解密算法的C语言实现(VC版)

AES加解密算法的C语言实现(VC版)
*
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
void encrypt(char *buff)
{
int i,j,k,m;
WORD a[8],b[8],*x,*y,*t;
for (i=j=0;i<Nb;i++,j+=4)
by=by>>4 &0x0f;
if(by >= 0 && by <= 9)
*str++ = by + '0';
else if(by >= 0x0A && by <= 0x0F)
*str++ = by - 10 + 'A';
by = *hex++;
by=by &0x0f;
if(by >= 0 && by <= 9)
else
return 0;
}
static WORD SubByte(WORD a)
{
BYTE b[4];
unpack(a,b);
b[0]=fbsub[b[0]];
b[1]=fbsub[b[1]];
b[2]=fbsub[b[2]];
b[3]=fbsub[b[3]];
return pack(b);
}
static BYTE product(WORD x,WORD y)
{ /* unpack bytes from a word */
b[0]=(BYTE)a; b[1]=(BYTE)(a>>8);

AES算法C语言讲解与实现

AES算法C语言讲解与实现

字节替换Void AES::SubBytes(unsigned char state[][4]) {Int r,c;for(r=0; r<4; r++){for(c=0; c<4; c++){state[r][c] = Sbox[state[r][c]];}}}行移位Void AES::ShiftRows(unsigned char state[][4]) {unsigned char t[4];Int r,c;for(r=1; r<4; r++){for(c=0; c<4; c++){t[c] = state[r][(c+r)%4];}for(c=0; c<4; c++){state[r][c] = t[c];}}}列混淆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];}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) {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;}轮密钥加算法Void AES::AddRoundKey(unsigned char state[][4], unsigned char k[][4]) {Int r,c;for(c=0; c<4; c++){for(r=0; r<4; r++){state[r][c] ^= k[r][c];}}}密钥扩展算法Void AES::KeyExpansion(unsigned char* key, unsigned char w[][4][4]) {Int i,j,r,c;unsigned char rc[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};for(r=0; r<4; r++){for(c=0; c<4; c++){w[0][r][c] = key[r+c*4];}}for(i=1; i<=10; i++){for(j=0; j<4; j++){unsigned char t[4];for(r=0; r<4; r++){t[r] = j ? w[i][r][j-1] : w[i-1][r][3];}if(j == 0){unsigned char temp = t[0];for(r=0; r<3; r++){t[r] = Sbox[t[(r+1)%4]];}t[3] = Sbox[temp];t[0] ^= rc[i-1];}for(r=0; r<4; r++){w[i][r][j] = w[i-1][r][j] ^ t[r]; }}}}解密过程(只有逆字节替换,逆行移位,逆列混淆)Void AES::InvSubBytes(unsigned char state[][4]) {Int r,c;for(r=0; r<4; r++){for(c=0; c<4; c++){state[r][c] = InvSbox[state[r][c]];}}}Void AES::InvShiftRows(unsigned char state[][4]) {unsigned char t[4];Int r,c;for(r=1; r<4; r++){for(c=0; c<4; c++){t[c] = state[r][(c-r+4)%4];}for(c=0; c<4; c++){state[r][c] = t[c];}}}Void AES::InvMixColumns(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];}for(r=0; r<4; r++){state[r][c] = FFmul(0x0e, t[r])^ FFmul(0x0b, t[(r+1)%4])^ FFmul(0x0d, t[(r+2)%4])^ FFmul(0x09, t[(r+3)%4]);}}}整体加密过程unsigned char* AES::Cipher(unsigned char* input){unsigned char state[4][4];int i,r,c;for(r=0; r<4; r++){for(c=0; c<4 ;c++){state[r][c] = input[c*4+r];}}AddRoundKey(state,w[0]);for(i=1; i<=10; i++){SubBytes(state);ShiftRows(state);if(i!=10)MixColumns(state);AddRoundKey(state,w[i]);}for(r=0; r<4; r++){for(c=0; c<4 ;c++){input[c*4+r] = state[r][c];}}return input;}整体解密过程unsigned char* AES::InvCipher(unsigned char* input) {unsigned char state[4][4];Int i,r,c;for(r=0; r<4; r++){for(c=0; c<4 ;c++){state[r][c] = input[c*4+r];}}AddRoundKey(state, w[10]);for(i=9; i>=0; i--){InvShiftRows(state);InvSubBytes(state);AddRoundKey(state, w[i]); if(i)InvMixColumns(state); }for(r=0; r<4; r++){for(c=0; c<4 ;c++){input[c*4+r] = state[r][c]; }}Return input;}。

C语言实现数据加密算法

C语言实现数据加密算法

C语言实现数据加密算法数据加密是对敏感信息进行转换的过程,以保护数据的机密性和完整性。

C语言提供了强大的工具和库来实现各种加密算法,包括对称加密和非对称加密等。

对称加密算法是一种使用相同密钥加密和解密数据的方法。

其中最常见的算法是DES(Data Encryption Standard)和AES(Advanced Encryption Standard)。

下面是一个实现AES算法的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>void encrypt_data(const unsigned char *data, size_t len, const unsigned char *key, unsigned char *encrypted_data) AES_KEY aes_key;AES_set_encrypt_key(key, 128, &aes_key);AES_encrypt(data, encrypted_data, &aes_key);void decrypt_data(const unsigned char *encrypted_data,size_t len, const unsigned char *key, unsigned char *data) AES_KEY aes_key;AES_set_decrypt_key(key, 128, &aes_key);AES_decrypt(encrypted_data, data, &aes_key);int maiunsigned char data[AES_BLOCK_SIZE] = "hello world!";size_t len = sizeof(data);unsigned char encrypted_data[AES_BLOCK_SIZE];encrypt_data(data, len, key, encrypted_data);unsigned char decrypted_data[AES_BLOCK_SIZE];decrypt_data(encrypted_data, len, key, decrypted_data);printf("Original Data: %s\n", data);printf("Encrypted Data: ");for (int i = 0; i < len; i++)printf("%02x ", encrypted_data[i]);}printf("\nDecrypted Data: %s\n", decrypted_data);return 0;```以上代码使用了OpenSSL库中的AES加密算法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档