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

合集下载

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/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语言实现代码

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语言实现

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-128,192,256C语言实现第一版

分组密码算法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版)

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加密算法⽰例本⽂实例讲述了基于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算法是一种高级加密标准,也是一种对称加密算法。

本文将详细介绍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语言上的实现

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语言实现数据加密算法数据加密是对敏感信息进行转换的过程,以保护数据的机密性和完整性。

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实验代码

密码学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语言实现

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加解密源代码

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加密算法源代码//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语言程序

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