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/S模式的通信设计任务:掌握AES的加密算法原理;掌握用socket编程实现C/S模式的加密通信。
设计内容:Socket编程实现客户端和服务器模式的通信;编程实现AES加解密的过程;将AES应用在C/S的通信中,对信息进行加密传输。
设计原理:1、socket编程实现C/S模式的通信,当用户在客户端发出请求时,会在服务器端做出相应的反应,并给出应答信息返回给客户端。
2、AES――对称密码新标准:高级加密标准。
对称密码体制的发展趋势将以分组密码为重点。
分组密码算法通常由密钥扩展算法和加密(解密)算法两部分组成。
密钥扩展算法将b字节用户主密钥扩展成r个子密钥。
加密算法由一个密码学上的弱函数f与r个子密钥迭代r次组成。
混乱和密钥扩散是分组密码算法设计的基本原则。
抵御已知明文的差分和线性攻击,可变长密钥和分组是该体制的设计要点。
AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。
AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。
1998年NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。
1999年3月完成了第二轮AES 2的分析、测试。
最终将Rijndael数据加密算法作为高级加密标准AES。
在应用方面,尽管DES在安全上是脆弱的,但由于快速DES芯片的大量生产,使得DES仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级DES。
但是DES迟早要被AES代替。
3、AES的主要算法原理:AES 算法是基于置换和代替的。
置换是数据的重新排列,而代替是用一个单元数据替换另一个。
AES 使用了几种不同的技术来实现置换和替换。
为了阐明这些技术,让我们用 Figure 1 所示的数据讨论一个具体的 AES 加密例子。
下面是你要加密的128位值以及它们对应的索引数组:00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15192位密钥的值是:00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 170 1 2 3 4 5 6 7 8 9 10 1112 13 14 15 16 17 18 19 20 21 22 23Figure 2 S-盒( Sbox )当 AES 的构造函数(constructor)被调用时,用于加密方法的两个表被初始化。
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算法的C语言实现
( (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。
"#包括“大众。
”#定义字节无符号字符#定义 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语言实现代码以下是一个简单的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-128,192,256C语言实现第一版
分组密码算法AES-128,192,256C语⾔实现第⼀版AES的C语⾔实现⼊门版AES分组密码算法中明⽂分组位128bits,密钥分组可以为128,192,256bits。
AES也是由最基本的变换单位——“轮”多次迭代⽽成的。
我们将 AES 中的轮变换计为 Round(State, RoundKey),State 表⽰消息矩阵;RoundKey 表⽰轮密钥矩阵。
⼀轮的完成将改变 State 矩阵中的元素,称为改变它的状态。
对于加密来说,输⼊到第⼀轮中的 State 就是明⽂消息矩阵,最后⼀轮输出的 State 就是对应的密⽂消息矩阵。
AES 的轮(除最后⼀轮外)变换有四个不同的变换组成,这些变化我们称之为内部轮函数, AES 的轮可表⽰成如下形式:Round(State, RoundKey){SubBytes(State);ShiftRows(State):MixColumns(State);AddRoundKey(State,RoundKey);}其中:ByteSub(State)称为字节代替变换、ShiftRow(State)称为⾏移位变、MixColumn(State)为列混合变换以及 AddRoundKey (State, RoundKey )为与⼦密钥与。
最后⼀轮略微的不同,将其记作 FinalRoundKey(State, RoundKey),相当于前⾯的Round(State, RoundKey)去掉 MixColumns(State)。
:加密过程:加密过程加密过程的伪代码:解密过程的伪代码:其中密钥长度不同,轮数不同,密钥编排扩展过程有所不同:下⾯是完整代码:#include "aes.h"const unsigned char sBox[16][16] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};const unsigned char inv_sBox[16][16] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,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};const unsigned char Rcon[16] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0xd8, 0xab, 0x4d, 0x9a, 0x2f };//轮常量表void SubBytes(unsigned char* in, const unsigned char table[16][16]){//字节替换for (int i = 0; i < 16; i++)in[i] = table[in[i] >> 4][in[i] & 0x0F];}void ShiftRows(unsigned char* in){//进⾏⾏移位unsigned char buffer[4] = { 0 };for (int i = 1; i < 4; i++){for (int j = 0; j < 4; j++)buffer[j] = in[((i + j) * 4 + i) % 16];for (int j = 0; j < 4; j++)in[4 * j + i] = buffer[j];}}void InvShiftRows(unsigned char* in){unsigned char buffer[4] = { 0 };for (int i = 1; i < 4; i++){for (int j = 0; j < 4; j++)buffer[j] = in[(4 * (4 - i + j) + i) % 16];for (int j = 0; j < 4; j++)in[4 * j + i] = buffer[j];}}unsigned char x2time(unsigned char a){//有限域*2乘法 The x2time() functionunsigned char res = (a << 1) ^ ((a & 0x80) ? 0x1b : 0x00);return res;}unsigned char x3time(unsigned char a){//3:0011return (x2time(a) ^ a);}unsigned char x4time(unsigned char a){//4:0100return (x2time(x2time(a)));}unsigned char x8time(unsigned char a){//8:1000return (x2time(x2time(x2time(a))));}unsigned char x9time(unsigned char a){//9:1001return (x8time(a) ^ a);unsigned char xBtime(unsigned char a){//B:1011return (x8time(a) ^ x3time(a));}unsigned char xDtime(unsigned char a){//D:1101return (x8time(a) ^ x4time(a) ^ a);}unsigned char xEtime(unsigned char a){//E:1110return (x8time(a) ^ x4time(a) ^ x2time(a));}void MixColumn(unsigned char* in){//进⾏列混合unsigned char tmp[4] = { 0 };for (int i = 0; i < 4; i++, in += 4){tmp[0] = x2time(in[0]) ^ x3time(in[1]) ^ in[2] ^ in[3];tmp[1] = in[0] ^ x2time(in[1]) ^ x3time(in[2]) ^ in[3];tmp[2] = in[0] ^ in[1] ^ x2time(in[2]) ^ x3time(in[3]);tmp[3] = x3time(in[0]) ^ in[1] ^ in[2] ^ x2time(in[3]);memcpy(in, tmp, 4);}}void InvMixColumn(unsigned char* in){//逆向列混合unsigned char tmp[4] = { 0 };for (int i = 0; i < 4; i++, in += 4){tmp[0] = xEtime(in[0]) ^ xBtime(in[1]) ^ xDtime(in[2]) ^ x9time(in[3]);tmp[1] = x9time(in[0]) ^ xEtime(in[1]) ^ xBtime(in[2]) ^ xDtime(in[3]);tmp[2] = xDtime(in[0]) ^ x9time(in[1]) ^ xEtime(in[2]) ^ xBtime(in[3]);tmp[3] = xBtime(in[0]) ^ xDtime(in[1]) ^ x9time(in[2]) ^ xEtime(in[3]);memcpy(in, tmp, 4);}}void AddRoundKey(unsigned char* in, const unsigned char* key){for (int i = 0; i < 16; i++)in[i] ^= key[i];}void rotWord(unsigned char* in){//将⼀个字进⾏左移循环⼀个单位unsigned char tmp = in[0];memcpy(in, in + 1, 3);in[3] = tmp;}void subWord(unsigned char* in){//每⼀个字进⾏字节替换for (int i = 0; i < 4; i++)in[i] = sBox[in[i] >> 4][in[i] & 0x0F];}static unsigned char roundKey[240] = { 0 };//最多是256bits,进⾏14轮迭代,roundKey中有15组,每⼀组16byte,最多是240bytes void SetKey(const unsigned char* key, const int Nk){int Nr = Nk + 6;memcpy(roundKey, key, 4 * Nk);//将最初的key拷贝到roundKey数组的最开始,每⼀个乘上4因为按字来计算,1字=4bytefor (int i = Nk; i < (Nr + 1) * 4; i++){unsigned char buffer[4] = { 0 };memcpy(buffer, roundKey + (i - 1) * 4, 4);if (i%Nk == 0){rotWord(buffer);subWord(buffer);buffer[0] ^= Rcon[i / Nk];}if ((i%Nk == 4) && Nk>6)subWord(buffer);for (int j = 0; j < 4; j++)roundKey[4 * i + j] = buffer[j] ^ roundKey[(i - Nk) * 4 + j];}}void encryptAES(unsigned char* out, const unsigned char* in, const unsigned char* key, const int keyLen){int Nk = keyLen >> 2;int Nr = Nk + 6;SetKey(key, Nk);memcpy(out, in, 16);AddRoundKey(out, roundKey);for (int i = 1; i <= Nr; i++){//进⾏Nr轮变换,最后⼀个Nr轮不进⾏列混合SubBytes(out, sBox);ShiftRows(out);if (i != Nr)MixColumn(out);AddRoundKey(out, roundKey + 16 * i);}void decryptAES(unsigned char* out, const unsigned char* in, const unsigned char* key, const int keyLen){ int Nk = keyLen >> 2;int Nr = Nk + 6;SetKey(key, Nk);memcpy(out, in, 16);AddRoundKey(out, roundKey + Nr * 16);for (int i = Nr - 1; i >= 0; i--){InvShiftRows(out);SubBytes(out, inv_sBox);AddRoundKey(out, roundKey + 16 * i);if (i != 0)InvMixColumn(out);}}aes.h头⽂件:#pragma once#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#ifdef __cplusplusextern"C"{#endifvoid encryptAES(unsigned char* out, const unsigned char* in, const unsigned char* key, const int keyLen);void decryptAES(unsigned char* out, const unsigned char* in, const unsigned char* key, const int keyLen); #ifdef __cplusplus}#endif运⾏结果:密钥是128Bits时:密钥是192bits时:密钥是256bits时:。
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);
基于C语言实现的aes256加密算法示例
基于C语⾔实现的aes256加密算法⽰例本⽂实例讲述了基于C语⾔实现的aes256加密算法。
分享给⼤家供⼤家参考,具体如下:aes256.h:#ifndef uint8_t#define uint8_t unsigned char#endif#ifdef __cplusplusextern "C" {#endiftypedef struct {uint8_t key[32];uint8_t enckey[32];uint8_t deckey[32];} aes256_context;void aes256_init(aes256_context *, uint8_t * );void aes256_done(aes256_context *);void aes256_encrypt_ecb(aes256_context *, uint8_t * );void aes256_decrypt_ecb(aes256_context *, uint8_t * );#ifdef __cplusplus}#endifaes256.c:#include "aes256.h"#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b))#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))// #define BACK_TO_TABLES#ifdef BACK_TO_TABLESconst uint8_t sbox[256] = {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};const uint8_t sboxinv[256] = {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,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};#define rj_sbox(x) sbox[(x)]#define rj_sbox_inv(x) sboxinv[(x)]#elseuint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3{uint8_t atb = 1, z;while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;} return atb;}uint8_t gf_log(uint8_t x) // calculate logarithm gen 3{uint8_t atb = 1, i = 0, z;do {if (atb == x) break;z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;} while (++i > 0);return i;}uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse{return (x) ? gf_alog(255 - gf_log(x)) : 0;}uint8_t rj_sbox(uint8_t x){uint8_t y, sb;sb = y = gf_mulinv(x);y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;return (sb ^ 0x63);}uint8_t rj_sbox_inv(uint8_t x){uint8_t y, sb;y = x ^ 0x63;sb = y = (y<<1)|(y>>7);y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y;return gf_mulinv(sb);}#endifuint8_t rj_xtime(uint8_t x){return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);}void aes_subBytes(uint8_t *buf){register uint8_t i = 16;while (i--) buf[i] = rj_sbox(buf[i]);}void aes_subBytes_inv(uint8_t *buf){register uint8_t i = 16;while (i--) buf[i] = rj_sbox_inv(buf[i]);}void aes_addRoundKey(uint8_t *buf, uint8_t *key){register uint8_t i = 16;while (i--) buf[i] ^= key[i];}void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk){register uint8_t i = 16;while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i];}void aes_shiftRows(uint8_t *buf){register uint8_t i, j;i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i;i = buf[10]; buf[10] = buf[2]; buf[2] = i;j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j; j = buf[14]; buf[14] = buf[6]; buf[6] = j;}void aes_shiftRows_inv(uint8_t *buf){register uint8_t i, j;i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i;i = buf[2]; buf[2] = buf[10]; buf[10] = i;j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j; j = buf[6]; buf[6] = buf[14]; buf[14] = j;}void aes_mixColumns(uint8_t *buf){register uint8_t i, a, b, c, d, e;for (i = 0; i < 16; i += 4){a = buf[i];b = buf[i + 1];c = buf[i + 2];d = buf[i + 3];e = a ^ b ^ c ^ d;buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c);buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a);}}void aes_mixColumns_inv(uint8_t *buf){register uint8_t i, a, b, c, d, e, x, y, z;for (i = 0; i < 16; i += 4){a = buf[i];b = buf[i + 1];c = buf[i + 2];d = buf[i + 3];e = a ^ b ^ c ^ d;z = rj_xtime(e);x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d));buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c);buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a);}}void aes_expandEncKey(uint8_t *k, uint8_t *rc){register uint8_t i;k[0] ^= rj_sbox(k[29]) ^ (*rc);k[1] ^= rj_sbox(k[30]);k[2] ^= rj_sbox(k[31]);k[3] ^= rj_sbox(k[28]);*rc = F( *rc);for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];k[16] ^= rj_sbox(k[12]);k[17] ^= rj_sbox(k[13]);k[18] ^= rj_sbox(k[14]);k[19] ^= rj_sbox(k[15]);for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];}void aes_expandDecKey(uint8_t *k, uint8_t *rc){uint8_t i;for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];k[16] ^= rj_sbox(k[12]);k[17] ^= rj_sbox(k[13]);k[18] ^= rj_sbox(k[14]);k[19] ^= rj_sbox(k[15]);for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];*rc = FD(*rc);k[0] ^= rj_sbox(k[29]) ^ (*rc);k[1] ^= rj_sbox(k[30]);k[2] ^= rj_sbox(k[31]);k[3] ^= rj_sbox(k[28]);}void aes256_init(aes256_context *ctx, uint8_t *k){uint8_t rcon = 1;register uint8_t i;for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon);}void aes256_done(aes256_context *ctx){register uint8_t i;for (i = 0; i < sizeof(ctx->key); i++)ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;}void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf){uint8_t i, rcon;aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);for(i = 1, rcon = 1; i < 14; ++i){aes_subBytes(buf);aes_shiftRows(buf);aes_mixColumns(buf);if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key); }aes_subBytes(buf);aes_shiftRows(buf);aes_expandEncKey(ctx->key, &rcon);aes_addRoundKey(buf, ctx->key);}void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf){uint8_t i, rcon;aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);aes_shiftRows_inv(buf);aes_subBytes_inv(buf);for (i = 14, rcon = 0x80; --i;){if( ( i & 1 ) ){aes_expandDecKey(ctx->key, &rcon);aes_addRoundKey(buf, &ctx->key[16]);}else aes_addRoundKey(buf, ctx->key);aes_mixColumns_inv(buf);aes_shiftRows_inv(buf);aes_subBytes_inv(buf);}aes_addRoundKey( buf, ctx->key);}demo.c:#include#include#include "aes256.h"#define DUMP(s, i, buf, sz) {printf(s); /for (i = 0; i < (sz);i++) /printf("x ", buf[i]); /printf("/n");}int main (int argc, char *argv[]){aes256_context ctx;uint8_t key[32];uint8_t buf[16], i;for (i = 0; i < sizeof(buf);i++) buf[i] = i * 16 + i;for (i = 0; i < sizeof(key);i++) key[i] = i;DUMP("txt: ", i, buf, sizeof(buf));DUMP("key: ", i, key, sizeof(key));printf("---/n");aes256_init(&ctx, key);aes256_encrypt_ecb(&ctx, buf);DUMP("enc: ", i, buf, sizeof(buf));printf("tst: 8e a2 b7 ca 51 67 45 bf ea fc 49 90 4b 49 60 89/n");aes256_init(&ctx, key);aes256_decrypt_ecb(&ctx, buf);DUMP("dec: ", i, buf, sizeof(buf));aes256_done(&ctx);return 0;}PS:关于加密解密感兴趣的朋友还可以参考本站在线⼯具:希望本⽂所述对⼤家C语⾔程序设计有所帮助。
c语言 aes256 ecb 算法
一、介绍C语言是一种广泛应用的计算机编程语言,而AES256 ECB算法是一种高级加密标准,也是一种对称加密算法。
本文将详细介绍C语言中实现AES256 ECB算法的方式及其原理。
二、AES256 ECB算法AES256 ECB算法是一种对称加密算法,使用256位的密钥进行加密和解密。
ECB(Electronic Codebook)模式是AES加密算法中最简单的模式,它将整个消息分割成固定长度的块,然后对每个块进行加密。
1. 加密过程- 对明文进行填充,使其长度为块的整数倍。
- 将填充后的明文分割成若干块,每个块的长度与密钥长度相同。
- 接下来,对每个块使用AES256算法进行加密,并将加密结果拼接在一起,得到密文。
2. 解密过程- 将密文分割成若干块,每个块的长度与密钥长度相同。
- 对每个块使用AES256算法进行解密,并将解密结果拼接在一起。
- 去除填充得到明文。
三、C语言中实现AES256 ECB算法的方式在C语言中实现AES256 ECB算法可以借助开源的加密库,例如openssl库。
以下是使用openssl库实现AES256 ECB算法的示例代码:```#include <openssl/aes.h>void aes_encrypt_ecb(const unsigned char *pl本人ntext, const unsigned char *key, unsigned char *ciphertext) {AES_KEY aes_key;AES_set_encrypt_key(key, 256, aes_key);AES_encrypt(pl本人ntext, ciphertext, aes_key);}void aes_decrypt_ecb(const unsigned char *ciphertext, const unsigned char *key, unsigned char *pl本人ntext) {AES_KEY aes_key;AES_set_decrypt_key(key, 256, aes_key);AES_decrypt(ciphertext, pl本人ntext, aes_key);}```以上代码中,aes_encrypt_ecb函数用于对明文进行加密,aes_decrypt_ecb函数用于对密文进行解密。
AES原理及其在c语言上的实现
AES加密解密算法及其在c语言上的实现引言对称密码算法主要用于保证数据的机密性,通信双方在加密/ 解密过程中使用它们共享的单一密钥。
对称密码算法的使用相当广泛,密码学界已经对它们进行了深入的研究[1] 。
最常用的对称密码算法是数据加密标准(DES) 算法,它是由IBM在美国国家安全局(NSA) 授意之下研制的一种使用56 位密钥的分组密码算法。
自1977 年公布成为美国政府的商用加密标准以来已使用20 多年[2] 。
DES 的主要问题是其密钥长度较短,已不适合于当今分布式开放网络对数据加密安全性的要求。
在DES 每隔五年的评估会议中,最后一次在1998 年美国政府终于决定不再继续延用DES作为联邦加密标准,也就表明了DES 将退出加密标准的舞台,而新的标准AES(AdvancedEncryptionStandard ) 将粉墨登场[3] 。
AES是美国国家标准技术研究所NIST旨在取代DES的新一代的加密标准[3~5] 。
NIST对AES候选算法的基本要求是:对称分组密码体制;密钥长度支持128,192,256位;明文分组长度128 位;算法应易于各种硬件和软件实现。
1998年NIST开始AES第一轮征集、分析、测试,共产生了15 个候选算法。
1999 年3 月完成了第二轮AES 的分析、测试。
1999 年8 月NIST公布了五种算法(MARS,RC6,Rijndael,Serpent,Twofish) 成为候选算法。
最后,Rijn2dael[5] ,这个由比利时人设计的算法与其它候选算法在成为高级加密标准(AES) 的竞争中取得成功,于2000 年10月被NIST宣布成为取代DES的新一代的数据加密标准,即AES。
尽管人们对AES还有不同的看法[6~8] ,但总体来说,Rijndael作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。
AES设计有三个密钥长度:128,192,256 比特, 相对而言,AES 的128 比特密钥比DES的56 比特密钥强1021倍[4] 。
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加密算法。
密码学c语言aes实验代码
以下是一个简单的AES加密和解密的C语言实验代码:```c#include <stdio.h>#include <string.h>#include <stdlib.h>#include <openssl/aes.h>void aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *ciphertext) {AES_KEY encryptKey;AES_set_encrypt_key(key, 128, &encryptKey);AES_encrypt(plaintext, ciphertext, &encryptKey);}void aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *plaintext) {AES_KEY decryptKey;AES_set_decrypt_key(key, 128, &decryptKey);AES_decrypt(ciphertext, plaintext, &decryptKey);}int main() {unsigned char key[16] = "0123456789abcdef"; // 128位密钥unsigned char plaintext[] = "Hello, World!"; // 明文unsigned char ciphertext[16]; // 密文unsigned char decryptedtext[17]; // 解密后的明文aes_encrypt(plaintext, strlen((char *)plaintext), key, ciphertext);aes_decrypt(ciphertext, sizeof(ciphertext), key, decryptedtext);printf("原文:%s", plaintext);printf("密文:");for (int i = 0; i < sizeof(ciphertext); i++) {printf("%02x", ciphertext[i]);}printf("");printf("解密后的明文:%s", decryptedtext);return 0;}```注意:这个代码使用了OpenSSL库,所以在编译时需要链接OpenSSL库。
AES加密的C语言实现
AES加密的C语⾔实现摘抄⾃⽹络上,稍作修改。
只能加密数据量⽐较⼩的,数据量超过⼀定长度存在错误。
⽤16字节密钥加密,加密数据长度估计最多是txt⽂件的⼀⾏,64字节;也可能和⽂件读写⽅法fread/fwrite等有关,导致读出的和写⼊的不同。
1//AES23 #include <stdio.h>4 #include <string.h>5 #include <stdlib.h>6 #include <conio.h>7 #include <iostream>89using namespace std;1011/*S盒*/12const unsigned char s[16][16] =13 {140x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,150xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,160xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,170x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,180x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,190x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,200xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,210x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,220xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,230x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,240xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,250xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,260xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,270x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,280xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,290x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x1630 };3132/*逆S盒*/33const unsigned char inv_s[16][16] =34 {350x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,360x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,370x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,380x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,390x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,400x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,410x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,420xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,430x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,440x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,450x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,460xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,470x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,480x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,490xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,500x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D51 };5253/*Rcon变换*/54const unsigned char Rcon[11][4] =55 {560x00, 0x00, 0x00, 0x00,570x01, 0x00, 0x00, 0x00,580x02, 0x00, 0x00, 0x00,590x04, 0x00, 0x00, 0x00,600x08, 0x00, 0x00, 0x00,610x10, 0x00, 0x00, 0x00,620x20, 0x00, 0x00, 0x00,630x40, 0x00, 0x00, 0x00,640x80, 0x00, 0x00, 0x00,650x1b, 0x00, 0x00, 0x00,660x36, 0x00, 0x00, 0x0067 };6869/*函数声明*/70int SumBytes(FILE *fp);//171void ByteToBits(unsigned char ch, unsigned char bit[]);//272void SubBytes(unsigned char status[][4], unsigned char bit[]);//373void Inv_SubBytes(unsigned char status[][4], unsigned char bit[]);//474void ShiftRows(unsigned char status[][4]);//575void Inv_ShiftRows(unsigned char status[][4]);//676 unsigned char ByteMultiply(unsigned char c);//777void MixColumns(unsigned char status[][4]);//878void Inv_MixColumns(unsigned char status[][4]);//979void RotWord(unsigned char c[], unsigned char temp[]);//1080void SubWord(unsigned char temp[], unsigned char bit[]);//1181void KeyExpansion(char *k, unsigned char key[][4], unsigned char bit[]);//1282void RoundKeyChoice(unsigned char key[][4], unsigned char RoundKey[][4], int cnt); //1383void AddRoundKey(unsigned char RoundKey[][4], unsigned char status[][4]);//1484void BytesWrite(FILE *fp, unsigned char status[][4]);//1585void DataEncrypt(char *k, unsigned char key[][4], unsigned char bit[], FILE *fp1, FILE *fp2, unsigned char RoundKey[][4], unsigned char status[][4]); 86void DataDecrypt(char *k1, unsigned char key[][4], FILE *fp1, FILE *fp2, unsigned char status[][4], unsigned char RoundKey[][4], unsigned char bit[]); 8788/*1、计算被加密⽂件数据的字节数⽬*/89int SumBytes(FILE *fp){90int num = 0;91char ch = fgetc(fp);92while (ch != EOF){93 num++;94 ch = fgetc(fp);95 }96return num;97 }9899/*2、字节转换为⼆进制位存放在数组中*/100void ByteToBits(unsigned char ch, unsigned char bit[]){101for (int i = 0; i < 8; i++)102 bit[i] = (ch >> i) & 1;103 }104105/*3、S盒变换*/106void SubBytes(unsigned char status[][4], unsigned char bit[]){107for (int i = 0; i < 4; i++)108for (int j = 0; j < 4; j++){109 ByteToBits(status[i][j], bit);110 status[i][j] = s[(bit[7] * 8 + bit[6] * 4 + bit[5] * 2 + bit[4])][(bit[3] * 8 + bit[2] * 4 + bit[1] * 2 + bit[0])];111 }112 }113114/*4、逆S盒变换*/115void Inv_SubBytes(unsigned char status[][4], unsigned char bit[]){116for (int i = 0; i < 4; i++)117for (int j = 0; j < 4; j++){118 ByteToBits(status[i][j], bit);119 status[i][j] = inv_s[(bit[7] * 8 + bit[6] * 4 + bit[5] * 2 + bit[4])][(bit[3] * 8 + bit[2] * 4 + bit[1] * 2 + bit[0])];120 }121 }122123/*5、⾏变换*/124void ShiftRows(unsigned char status[][4]){125 unsigned char temp1 = status[1][0];126 unsigned char temp2 = status[2][0];127 unsigned char temp3 = status[2][1];128 unsigned char temp4 = status[3][0];129 unsigned char temp5 = status[3][1];130 unsigned char temp6 = status[3][2];131for (int i = 0; i < 3; i++)132 status[1][i] = status[1][(i + 1)];133 status[1][3] = temp1;134for (int i = 0; i < 2; i++)135 status[2][i] = status[2][(i + 2)];136 status[2][2] = temp2;137 status[2][3] = temp3;138 status[3][0] = status[3][3];139 status[3][1] = temp4;140 status[3][2] = temp5;141 status[3][3] = temp6;142 }143144/*6、逆⾏变换*/145void Inv_ShiftRows(unsigned char status[][4]){146 unsigned char temp1 = status[1][3];147 unsigned char temp2 = status[2][2];148 unsigned char temp3 = status[2][3];149 unsigned char temp4 = status[3][1];150for (int i = 3; i > 0; i--)151 status[1][i] = status[1][i - 1];152 status[1][0] = temp1;153for (int i = 3; i > 1; i--)154 status[2][i] = status[2][i - 2];155 status[2][0] = temp2;156 status[2][1] = temp3;157for (int i = 1; i < 4; i++)158 status[3][i] = status[3][(i + 1) % 4];159 status[3][0] = temp4;160 }161162/*7、列变换被调⽤函数x乘法(02乘法)*/163 unsigned char ByteMultiply(unsigned char c){164 unsigned char temp;165 temp = c << 1;166if (c & 0x80){167 temp ^= 0x1b;168 }169return temp;170 }171172/*8、列变换*/173void MixColumns(unsigned char status[][4]){174 unsigned char temp[4][4];175for (int j = 0; j < 4; j++)176for (int i = 0; i < 4; i++)177 temp[i][j] = ByteMultiply(status[i % 4][j]) //0x02乘法178 ^ (status[(i + 1) % 4][j] ^ ByteMultiply(status[(i + 1) % 4][j])) //0x03乘法179 ^ status[(i + 2) % 4][j] //0x01乘法180 ^ status[(i + 3) % 4][j]; //0x01乘法181for (int i = 0; i < 4; i++)182for (int j = 0; j < 4; j++)183 status[i][j] = temp[i][j];184 }185186/*9、逆列变换*/187void Inv_MixColumns(unsigned char status[][4]){188 unsigned char temp[4][4];189for (int j = 0; j< 4; j++)190for (int i = 0; i<4; i++)191 temp[i][j] = (ByteMultiply(ByteMultiply(ByteMultiply(status[i % 4][j]))) ^ ByteMultiply(ByteMultiply(status[i % 4][j])) ^ ByteMultiply(status[i % 4][j])) //0x0E乘法192 ^ (ByteMultiply(ByteMultiply(ByteMultiply(status[(i + 1) % 4][j]))) ^ ByteMultiply(status[(i + 1) % 4][j]) ^ status[(i + 1) % 4][j]) //0x0B乘法193 ^ (ByteMultiply(ByteMultiply(ByteMultiply(status[(i + 2) % 4][j]))) ^ ByteMultiply(ByteMultiply(status[(i + 2) % 4][j])) ^ status[(i + 2) % 4][j]) //0x0D乘法194 ^ (ByteMultiply(ByteMultiply(ByteMultiply(status[(i + 3) % 4][j]))) ^ status[(i + 3) % 4][j]); //0x09乘法195for (int i = 0; i < 4; i++)196for (int j = 0; j < 4; j++)197 status[i][j] = temp[i][j];198 }199200/*10、位置变换*/201void RotWord(unsigned char c[], unsigned char temp[]){202for (int i = 1; i < 4; i++)203 temp[i - 1] = c[i];204 temp[3] = c[0];205 }206207/*11、⼩S盒变换*/208void SubWord(unsigned char temp[], unsigned char bit[]){209for (int i = 0; i < 4; i++){210 ByteToBits(temp[i], bit);211 temp[i] = s[(bit[7] * 8 + bit[6] * 4 + bit[5] * 2 + bit[4])][(bit[3] * 8 + bit[2] * 4 + bit[1] * 2 + bit[0])];212 }213 }214215/*12、密钥扩展函数*/216void KeyExpansion(char *k, unsigned char key[][4], unsigned char bit[]){217int i, j;218 unsigned char temp[4];219for (i = 0; i < 44; i++)220for (j = 0; j < 4; j++){221if (i < 4) key[i][j] = *(k + 4 * i + j);222else if ((i != 0) && (i % 4 == 0)){223 RotWord(key[i - 1], temp);224 SubWord(temp, bit);225 key[i][j] = key[i - 4][j] ^ temp[j] ^ Rcon[i / 4][j];226 }227else key[i][j] = key[i - 1][j] ^ key[i - 4][j];228 }229 }230231/*13、从扩展密钥中选择轮密钥的函数*/232void RoundKeyChoice(unsigned char key[][4], unsigned char RoundKey[][4], int cnt){233int cnt1 = 4 * cnt;234for (int i = 0; i < 4; i++){235for (int j = 0; j < 4; j++){236 RoundKey[i][j] = key[cnt1][j];237 }238 cnt1++;239 }240 }241242/*14、与扩展密钥的异或运算*/243void AddRoundKey(unsigned char RoundKey[][4], unsigned char status[][4]){244for (int j = 0; j < 4; j++)245for (int i = 0; i < 4; i++)246 status[i][j] = status[i][j] ^ RoundKey[j][i];247 }248249/*15、将状态矩阵中的字节写⼊⽂件中函数*/250void BytesWrite(FILE *fp, unsigned char status[][4]){251char ch;252for (int i = 0; i < 4; i++)253for (int j = 0; j < 4; j++){254 ch = status[i][j];255 fputc(ch, fp);256 }257 }258259/*16.加密总函数*/260void DataEncrypt(char *k, unsigned char key[][4], unsigned char bit[], FILE *fp1, FILE *fp2, unsigned char RoundKey[][4], unsigned char status[][4]) { 261int sum, numOfBlock, numOfSurplus;262char ch;263int len = strlen(k);264if (len != 16){265 free(k);266 printf("\n\n输⼊密钥长度不满⾜要求!\n"); return;267 }268 KeyExpansion(k, key, bit);269 sum = SumBytes(fp1);270 fp1 = fopen("源⽂件.txt", "r");271 numOfBlock = sum / 16;272 numOfSurplus = sum % 16;273 ch = fgetc(fp1);274/*第⼀种情况*/275if (numOfBlock != 0 && numOfSurplus == 0){276for (int n = 1; n <= numOfBlock; n++){277for (int i = 0; i < 4; i++)278for (int j = 0; j < 4; j++){279 status[i][j] = ch;280 ch = fgetc(fp1);281 }//status赋值282 RoundKeyChoice(key, RoundKey, 0);283 AddRoundKey(RoundKey, status);284for (int nr = 1; nr <= 10; nr++){285 SubBytes(status, bit);286 ShiftRows(status);287 MixColumns(status);288 RoundKeyChoice(key, RoundKey, nr);289 AddRoundKey(RoundKey, status);290 }//10轮加密291 SubBytes(status, bit);292 ShiftRows(status);293 RoundKeyChoice(key, RoundKey, 4);294 AddRoundKey(RoundKey, status);295 BytesWrite(fp2, status);296 }//Block循环297 }//if298//第⼆种情况299else if (numOfBlock == 0 && numOfSurplus != 0){300for (int i = 0; i < 4; i++)301for (int j = 0; j < 4; j++){302if (ch == EOF) break;303 status[i][j] = ch;304 ch = fgetc(fp1);305 }306for (int i = sum / 4; i < 4; i++)307for (int j = sum % 4; j < 4; j++)308 status[i][j] = 0x00;309 RoundKeyChoice(key, RoundKey, 0);310 AddRoundKey(RoundKey, status);311for (int nr = 1; nr <= 10; nr++){312 SubBytes(status, bit);313 ShiftRows(status);314 MixColumns(status);315 RoundKeyChoice(key, RoundKey, nr);316 AddRoundKey(RoundKey, status);317 }//10轮加密318 SubBytes(status, bit);319 ShiftRows(status);320 RoundKeyChoice(key, RoundKey, 4);321 AddRoundKey(RoundKey, status);322 BytesWrite(fp2, status);323 }//else if324//第三种情况325else if (numOfBlock != 0 && numOfSurplus != 0){326for (int n = 1; n <= numOfBlock; n++){327for (int i = 0; i <4; i++)328for (int j = 0; j < 4; j++){329 status[i][j] = ch;330 ch = fgetc(fp1);331 }//status赋值332 RoundKeyChoice(key, RoundKey, 0);333 AddRoundKey(RoundKey, status);334for (int nr = 1; nr <= 10; nr++){335 SubBytes(status, bit);336 ShiftRows(status);337 MixColumns(status);338 RoundKeyChoice(key, RoundKey, nr);339 AddRoundKey(RoundKey, status);340 }//10轮加密341 SubBytes(status, bit);342 ShiftRows(status);343 RoundKeyChoice(key, RoundKey, 4);344 AddRoundKey(RoundKey, status);345 BytesWrite(fp2, status);346 }//Block循环347for (int i = 0; i < 4; i++)348for (int j = 0; j < 4; j++){349if (ch == EOF) break;350 status[i][j] = ch;351 ch = fgetc(fp1);352 }353for (int i = sum / 4; i < 4; i++)354for (int j = sum % 4; j < 4; j++)355 status[i][j] = 0x00;356 RoundKeyChoice(key, RoundKey, 0);357 AddRoundKey(RoundKey, status);358for (int nr = 1; nr <= 10; nr++){359 SubBytes(status, bit);360 ShiftRows(status);361 MixColumns(status);362 RoundKeyChoice(key, RoundKey, nr);363 AddRoundKey(RoundKey, status);364 }//10轮加密365 SubBytes(status, bit);366 ShiftRows(status);367 RoundKeyChoice(key, RoundKey, 4);368 AddRoundKey(RoundKey, status);369 BytesWrite(fp2, status);370 }//else371 free(k);372 fclose(fp1);373 fclose(fp2);374 printf("\n\n加密⽂件成功!\n\n");375 }376377/*17.解密总函数*/378void DataDecrypt(char *k1, unsigned char key[][4], FILE *fp1, FILE *fp2, unsigned char status[][4], unsigned char RoundKey[][4], unsigned char bit[]) { 379int numOfBlock, sum;380char ch;381int len = strlen(k1);382if (len != 16){383 free(k1);384 printf("\n\n输⼊密钥长度不满⾜要求!\n"); return;385 }386 sum = SumBytes(fp1);387 fp1 = fopen("加密后⽂件.txt", "r");388 numOfBlock = sum / 16;389 ch = fgetc(fp1);390for (int i = 1; i <= numOfBlock; i++){391for (int i = 0; i < 4; i++)392for (int j = 0; j < 4; j++){393 status[i][j] = ch;394 ch = fgetc(fp1);395 }396 RoundKeyChoice(key, RoundKey, 4);397 AddRoundKey(RoundKey, status);398 Inv_ShiftRows(status);399 Inv_SubBytes(status, bit);400for (int nr = 10; nr >= 1; nr--){401 RoundKeyChoice(key, RoundKey, nr);402 AddRoundKey(RoundKey, status);403 Inv_MixColumns(status);404 Inv_ShiftRows(status);405 Inv_SubBytes(status, bit);406 }//10轮解密407 RoundKeyChoice(key, RoundKey, 0);408 AddRoundKey(RoundKey, status);409 BytesWrite(fp2, status);410 }//Block411 free(k1);412 fclose(fp1);413 fclose(fp2);414 printf("\n\n解密⽂件成功!\n\n");415 }416417int main(){418int choice, sum1;419int flag = 1;420char *k, *k1;421 FILE *fp1, *fp2;422 unsigned char status[4][4] = { 0x00 };423 unsigned char key[44][4] = { 0x00 };424 unsigned char RoundKey[4][4] = { 0x00 };425 unsigned char bit[8] = { 0x00 };426do{427 printf("*****************************AES加密解密⽂件************************************"); 428 printf("\n");429 printf(" 1.加密⽂件\n\n");430 printf(" 2.解密⽂件\n\n");431 printf(" 3.退出\n\n");432 printf("\n请选择要进⾏的操作:");433 scanf("%d", &choice);434switch (choice){435case1: fp1 = fopen("源⽂件.txt", "r");436if (fp1 == NULL){437 printf("打开源⽂件失败!\n");438 getchar();439 exit(0);440 }441 fp2 = fopen("加密后⽂件.txt", "w");442if (fp2 == NULL){443 printf("打开加密后⽂件失败!\n");444 getchar();445 exit(0);446 }447 printf("\n请输⼊加密密钥(128bit):");448 k = (char *)malloc(20 * sizeof(char));449 cin >> k;450 DataEncrypt(k, key, bit, fp1, fp2, RoundKey, status);451break;452case2: fp1 = fopen("加密后⽂件.txt", "r");453if (fp1 == NULL){454 printf("\n打开加密后⽂件失败!\n");455 getchar();456 exit(0);457 }458 fp2 = fopen("解密后⽂件.txt", "w");459if (fp2 == NULL){460 printf("\n打开解密后⽂件失败!\n");461 getchar();462 exit(0);463 }464 printf("\n\n请输⼊解密密钥(128bit):");465 k1 = (char *)malloc(20 * sizeof(char));466 cin >> k1;467 DataDecrypt(k1, key, fp1, fp2, status, RoundKey, bit);468break;469case3: flag = 0; break;470default: printf("\n\n所选操作不合法!\n");471 }//switch472 } while (flag);473 }C Code。
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加密算法源代码
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");}。
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};
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*密钥置换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);
typedef char ElemType;
/*初始置换表IP*/ int IP_Table[64] = { 57,49,41,33,25,17,9,1, 59,51,43,35,27,19,11,3, 61,53,45,37,29,21,13,5, 63,55,47,39,31,23,15,7, 56,48,40,32,24,16,8,0, 58,50,42,34,26,18,10,2, 60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6}; /*逆初始置换表IP^-1*/ int IP_1_Table[64] = {39,7,47,15,55,23,63,31,
*ch |= *(bit + cnt)<<cnt; } return 0; }
/*将长度为8的字符串转为二进制位串*/ int Char8ToBit64(ElemType ch[8],ElemType bit[64]){
第2页
int cnt; for(cnt = 0; cnt < 8; cnt++){ ByteToBit(*(ch+cnt),bit+(cnt<<3)); } return 0; }
{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}, {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}, {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}}, /*S2*/ {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5}, {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}}, /*S3*/ {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8}, {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1}, {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7}, {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}}, /*S4*/ {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9}, {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4}, {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}}, /*S5*/ {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9}, {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6}, {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14}, {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}}, /*S6*/
/*字节转换成二进制*/ int ByteToBit(ElemType ch, ElemType bit[8]){ int cnt; for(cnt = 0;cnt < 8; cnt++){
*(bit+cnt) = (ch>>cnt)&1; } return 0; }
/*二进制转换成字节*/ int BitToByte(ElemType bit[8],ElemType *ch){ int cnt; for(cnt = 0;cnt < 8; cnt++){
/*置换函数P*/ int P_Table[32] = {15,6,19,20,28,11,27,16, 0,14,22,25,4,17,30,9, 1,7,23,13,31,26,2,8, 18,12,29,5,21,10,3,24};
/*S盒*/ int S[8][4][16] = /*S1*/ {{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
38,6,46,14,54,22,62,30, 37,5,45,13,53,21,61,29, 36,4,44,12,52,20,60,28, 35,3,43,11,51,19,59,27, 34,2,42,10,50,18,58,26, 33,1,41,9,49,17,57,25, 32,0,40,8,48,16,56,24};
#include "stdio.h" #include "memory.h" #include "time.h" #include "stdlib.h"
Байду номын сангаас
AES加密算法c语言实现代码
#define PLAIN_FILE_OPEN_ERROR -1 #define KEY_FILE_OPEN_ERROR -2 #define CIPHER_FILE_OPEN_ERROR -3 #define OK 1
/*生成子密钥*/ int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){ ElemType temp[56]; int cnt; DES_PC1_Transform(key,temp);/*PC1置换*/ for(cnt = 0; cnt < 16; cnt++){/*16轮跌代,产生16个子密钥*/
/*置换选择2*/ int PC_2[48] = {13,16,10,23,0,4,2,27,
14,5,20,9,22,18,11,3, 25,7,15,6,26,19,12,1, 40,51,30,36,46,54,29,39, 50,44,32,46,43,48,38,55, 33,52,45,41,49,35,28,31};