C语言实现数据加密算法

合集下载

RSA加密算法(C语言实现)

RSA加密算法(C语言实现)

RSA加密算法(C语言实现)RSA(Rivest-Shamir-Adleman)算法是一种非对称加密算法,它是目前应用最广泛的加密算法之一、RSA算法基于两个大素数之间的乘积很难分解的特性,并使用公钥和私钥进行加密和解密。

在C语言中实现RSA算法需要进行以下步骤:1.生成大素数p和q:选择两个大素数p和q,它们需要满足p≠q。

这样选取p和q是为了使得计算n=p*q变得困难,保护私钥。

2.计算n:计算n=p*q,n即为公钥和私钥的参数之一3.计算欧拉函数φ(n):计算欧拉函数φ(n)=(p-1)*(q-1)。

4.选择e:选择一个与φ(n)互质且小于φ(n)的整数e作为加密指数,e即为公钥的参数。

5. 计算d:计算d = e^(-1) mod φ(n),d即为私钥的参数。

可以使用扩展欧几里得算法来计算d。

6. 加密:将明文M转换为整数m,加密后的密文C = m^e mod n。

7. 解密:解密密文C得到明文M = C^d mod n。

以下是C语言实现RSA加密算法的代码示例:```c#include <stdio.h>int gcd(int a, int b)if(b == 0)}return gcd(b, a % b);int extendedGcd(int a, int b, int *x, int *y) if(a == 0)*x=0;*y=1;return b;}int x1, y1;int gcd = extendedGcd(b % a, a, &x1, &y1);*x=y1-(b/a)*x1;*y=x1;return gcd;int modInverse(int a, int m)int x, y;int gcd = extendedGcd(a, m, &x, &y);if(gcd != 1)printf("Inverse doesn't exist\n");}return (x % m + m) % m;int powerMod(int x, unsigned int y, int m) if (y == 0)return 1;}int p = powerMod(x, y/2, m) % m;p=(p*p)%m;return (y%2 == 0) ? p : (x*p) % m;int maiint p, q, n, phiN, e, d;//选择两个大素数p和qp=31;q=17;//计算n和φ(n)n=p*q;phiN = (p - 1) * (q - 1);//选择加密指数ee=7;//计算解密指数dd = modInverse(e, phiN);int plaintext = 88;int ciphertext = powerMod(plaintext, e, n);int decryptedtext = powerMod(ciphertext, d, n);printf("Plaintext: %d\n", plaintext);printf("Ciphertext: %d\n", ciphertext);printf("Decryptedtext: %d\n", decryptedtext);return 0;```在上面的代码中,我们使用了几个辅助函数来实现扩展欧几里得算法、计算模反元素和快速幂算法。

C语言实现RSA算法

C语言实现RSA算法

C语言实现RSA算法RSA算法是一种非对称加密算法,用于在网络通信中进行数据加密和解密。

下面我将给出C语言中RSA算法的实现。

首先,我们需要生成RSA密钥对,包括公钥和私钥。

以下是生成RSA 密钥对的C代码实现:```c#include <stdio.h>#include <stdlib.h>#include <math.h>//定义最大素数范围//定义RSA密钥结构体typedef structunsigned long long e; // 公钥指数unsigned long long d; // 私钥指数unsigned long long n; // 模数} RSAKey;//判断一个数是否为素数int isPrime(unsigned long long num)//小于等于1的数不是素数if (num <= 1) return 0;//判断是否存在因子for (unsigned long long i = 2; i <= sqrt(num); i++)if (num % i == 0)return 0;}}return 1;//生成一个指定范围内的随机素数unsigned long long generateRandomPrime(unsigned long long min, unsigned long long max)unsigned long long num;donum = rand( % (max - min + 1) + min;} while (!isPrime(num));return num;//求最大公约数unsigned long long gcd(unsigned long long a, unsigned long long b)unsigned long long temp;while (b != 0)temp = a % b;a=b;b = temp;}return a;//求模反元素unsigned long long modReverse(unsigned long long a, unsigned long long b)unsigned long long m0 = b, t, q;unsigned long long x0 = 0, x1 = 1;if (b == 1) return 0;while (a > 1)q=a/b;t=b;b=a%b;a=t;t=x0;x0=x1-q*x0;x1=t;}if (x1 < 0) x1 += m0;return x1;//生成RSA密钥对RSAKey generateRSAKeys(unsigned long long p, unsigned long long q)RSAKey keys;//计算模数keys.n = p * q;//计算欧拉函数值unsigned long long phi = (p - 1) * (q - 1);//选择公钥指数ekeys.e = generateRandomPrime(2, phi - 1);//计算私钥指数dkeys.d = modReverse(keys.e, phi);return keys;int mai//设置随机种子//生成两个不同的随机素数unsigned long long p = generateRandomPrime(2,MAX_PRIME_NUMBER);unsigned long long q = generateRandomPrime(2,MAX_PRIME_NUMBER);RSAKey keys = generateRSAKeys(p, q);printf("公钥指数e: %llu\n", keys.e);printf("私钥指数d: %llu\n", keys.d);printf("模数n: %llu\n", keys.n);return 0;```运行上述代码,即可生成RSA密钥对。

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];}```接下来,我们实现密钥扩展和子密钥生成的过程。

RSA的C语言算法实现

RSA的C语言算法实现

RSA的C语言算法实现RSA算法是一种非对称密码算法,用于加密和解密数据。

它是由三位数学家Rivest、Shamir和Adleman在1977年提出的,是目前最广泛使用的公钥加密算法之一RSA算法的实现需要以下步骤:1.选择两个大素数p和q,计算它们的乘积n=p*q。

n称为模数。

2.计算欧拉函数φ(n)=(p-1)*(q-1)。

3. 选择一个小于φ(n)的整数e,使得e与φ(n)互质,即gcd(e,φ(n)) = 1、e称为公钥指数。

4. 计算私钥指数d,满足(d * e) mod φ(n) = 1、d称为私钥指数。

5.公钥是(n,e),私钥是(n,d)。

6. 要加密消息m,计算c = m^e mod n,其中c是密文。

7. 要解密密文c,计算m = c^d mod n,其中m是原始消息。

下面是一个使用C语言实现RSA算法的示例:```c#include <stdio.h>#include <stdlib.h>typedef unsigned long long int ullong;ullong gcd(ullong a, ullong b)ullong temp;while (b != 0)temp = b;b=a%b;a = temp;}return a;ullong mod_inverse(ullong a, ullong m) ullong m0 = m;ullong y = 0, x = 1;if (m == 1)return 0;while (a > 1)ullong q = a / m;ullong t = m;m=a%m,a=t;t=y;y=x-q*y;x=t;}if (x < 0)x+=m0;return x;ullong mod_exp(ullong base, ullong exponent, ullong modulus) ullong result = 1;base = base % modulus;while (exponent > 0)if (exponent % 2 == 1)result = (result * base) % modulus;exponent = exponent >> 1;base = (base * base) % modulus;}return result;int mai//选择素数p和qullong p = 17;ullong q = 19;//计算模数n和欧拉函数φ(n)ullong n = p * q;ullong phi_n = (p - 1) * (q - 1);//选择公钥指数eullong e = 5;//计算私钥指数dullong d = mod_inverse(e, phi_n);//打印公钥和私钥printf("公钥: (%llu, %llu)\n", n, e); printf("私钥: (%llu, %llu)\n", n, d);//要加密的消息ullong m = 88;//加密消息ullong c = mod_exp(m, e, n);//打印加密结果printf("加密结果: %llu\n", c);//解密消息ullong decrypted_m = mod_exp(c, d, n); //打印解密结果printf("解密结果: %llu\n", decrypted_m);return 0;```这是一个简单的RSA实现示例,用于加密和解密一个整数。

C语言加密与解密算法

C语言加密与解密算法

C语言加密与解密算法在计算机科学与信息安全领域,加密与解密算法起着至关重要的作用。

加密算法用于将原始数据转换为不可读的密文,而解密算法则用于将密文还原为可读的原始数据。

C语言是一种常用的编程语言,具备高效性和灵活性,适用于加密与解密算法的开发。

本文将介绍几种常用的C语言加密与解密算法。

一、凯撒密码算法凯撒密码算法是一种最简单的替换加密算法,通过将字母按照固定的偏移量进行替换来实现加密与解密。

以下是一个简单的C语言凯撒密码实现例子:```c#include <stdio.h>void caesarEncrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' + key) % 26 + 'a';} else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' + key) % 26 + 'A';}i++;}}void caesarDecrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' - key + 26) % 26 + 'a'; } else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' - key + 26) % 26 + 'A'; }i++;}}int main() {char message[] = "Hello, World!";int key = 3;printf("Original message: %s\n", message);caesarEncrypt(message, key);printf("Encrypted message: %s\n", message);caesarDecrypt(message, key);printf("Decrypted message: %s\n", message);return 0;}```以上程序演示了凯撒密码的加密与解密过程,通过指定偏移量实现对消息的加密与解密。

MD5加密C语言实现

MD5加密C语言实现

MD5加密C语言实现MD5 (Message Digest Algorithm 5) 是一种常用的密码散列函数,用于将数据加密为128位长度的摘要。

在C语言中,可以通过一系列步骤来实现MD5加密算法。

1.准备工作:首先需要包含一些C标准头文件和预定义常量。

在C语言中,可以使用以下代码来实现:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdint.h>#define HASH_LENGTH 16```2.定义数据结构:MD5算法涉及到一个64字节的消息块和一个4字节的消息摘要块。

在C语言中,可以使用以下代码来定义这些结构:```ctypedef structuint8_t data[64];uint32_t datalen;uint32_t bitlen[2];uint32_t state[4];}MD5_CTX;typedef uint8_t (*hash_function)(uint8_t *);```3.定义常量和函数:MD5算法使用到一些常量和函数。

在C语言中,可以使用以下代码来定义这些常量和函数:```cconst uint32_t k[64] =// more constants ...};const uint32_t r[64] =7,12,17,22,7,12,17,22,// more constants ...};void md5_transform(MD5_CTX *ctx, uint8_t data[]);void md5_init(MD5_CTX *ctx)ctx->datalen = 0;ctx->bitlen[0] = 0;ctx->bitlen[1] = 0;ctx->state[1] = 0xEFCDAB89;ctx->state[2] = 0x98BADCFE;void md5_update(MD5_CTX *ctx, uint8_t data[], uint32_t len) for (uint32_t i = 0; i < len; i++)ctx->data[ctx->datalen] = data[i];ctx->datalen++;if (ctx->datalen == 64)md5_transform(ctx, ctx->data);ctx->bitlen[0] += 512;ctx->bitlen[1] += (ctx->bitlen[0] < 512);ctx->datalen = 0;}}void md5_final(MD5_CTX *ctx, uint8_t hash[])uint32_t i = ctx->datalen;if (ctx->datalen < 56)ctx->data[i++] = 0x80;while (i < 56)ctx->data[i++] = 0x00;}} elsectx->data[i++] = 0x80;while (i < 64)ctx->data[i++] = 0x00;}md5_transform(ctx, ctx->data);memset(ctx->data, 0, 56);}ctx->bitlen[0] += ctx->datalen * 8;ctx->bitlen[1] += (ctx->bitlen[0] < ctx->datalen * 8); ctx->data[63] = ctx->bitlen[0] & 0xff;ctx->data[62] = (ctx->bitlen[0] >> 8) & 0xff;ctx->data[61] = (ctx->bitlen[0] >> 16) & 0xff;ctx->data[60] = (ctx->bitlen[0] >> 24) & 0xff;ctx->data[59] = ctx->bitlen[1] & 0xff;ctx->data[58] = (ctx->bitlen[1] >> 8) & 0xff;ctx->data[57] = (ctx->bitlen[1] >> 16) & 0xff;ctx->data[56] = (ctx->bitlen[1] >> 24) & 0xff;md5_transform(ctx, ctx->data);for (i = 0; i < 4; i++)hash[i] = (ctx->state[0] >> (i * 8)) & 0xff;hash[i + 4] = (ctx->state[1] >> (i * 8)) & 0xff;hash[i + 8] = (ctx->state[2] >> (i * 8)) & 0xff;hash[i + 12] = (ctx->state[3] >> (i * 8)) & 0xff;}void md5_transform(MD5_CTX *ctx, uint8_t data[])uint32_t a, b, c, d, f, g, temp;uint32_t m[16], i, j;for (i = 0, j = 0; i < 16; i++, j += 4)m[i] = (data[j]) + (data[j + 1] << 8) + (data[j + 2] << 16) + (data[j + 3] << 24);}a = ctx->state[0];b = ctx->state[1];c = ctx->state[2];d = ctx->state[3];for (i = 0; i < 64; i++)if (i < 16)f=(b&c),((~b)&d);g=i;} else if (i < 32)f=(d&b),((~d)&c);g=(5*i+1)%16;} else if (i < 48)f=b^c^d;g=(3*i+5)%16;} elsef=c^(b,(~d));g=(7*i)%16;}temp = d;d=c;c=b;b = b + leftrotate((a + f + k[i] + m[g]), r[i]);a = temp;}ctx->state[0] += a;ctx->state[1] += b;ctx->state[2] += c;ctx->state[3] += d;```4.实现加密函数:最后,可以编写一个简单的调用MD5算法的加密函数。

des密码算法程序c语言

des密码算法程序c语言

des密码算法程序c语言一、概述DES(数据加密标准)是一种常用的对称加密算法,它采用64位的密钥,对数据进行加密和解密。

本程序使用C语言实现DES算法,包括密钥生成、数据加密和解密等操作。

二、算法实现1.密钥生成:使用初始置换算法IP(56位)将明文转化为56位的分组,再将该分组经过一系列的逻辑函数F进行6轮处理,最终生成一个56位的密文。

其中密钥包括56位数据位和8位奇偶校验位。

2.数据加密:将需要加密的数据转化为56位的分组,再经过DES 算法处理,得到密文。

3.数据解密:将密文经过DES算法处理,还原成原始明文。

三、程序代码```c#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>//DES算法参数定义#defineITERATIONS6//加密轮数#defineKEY_LENGTH8//密钥长度,单位为字节#defineBLOCK_SIZE8//数据分组长度,单位为字节#definePADDINGPKCS7Padding//填充方式#defineMAX_INPUT_LENGTH(BLOCK_SIZE*2)//数据输入的最大长度//初始置换函数voidinit_permutation(unsignedcharinput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){input[i]=i;}}//逻辑函数F的定义voidlogic_function(unsignedcharinput[BLOCK_SIZE],unsigned charoutput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){output[i]=input[(i+1)%BLOCK_SIZE]^input[i]^(i+1)/BLOCK_SI ZE;}}//DES算法主函数voiddes_encrypt(unsignedchar*input,unsignedchar*output){ unsignedcharkey[KEY_LENGTH];//密钥数组unsignedchariv[BLOCK_SIZE];//初始置换的输入数组unsignedcharciphertext[MAX_INPUT_LENGTH];//密文数组unsignedcharpadding[BLOCK_SIZE];//填充数组unsignedintlength=strlen((char*)input);//数据长度(以字节为单位)unsignedintpadding_length=(length+BLOCK_SIZE-1)%BLOCK_SIZE;//需要填充的字节数unsignedintround=0;//加密轮数计数器unsignedintj=0;//数据指针,用于循环读取数据和填充数据intkey_offset=((1<<(32-KEY_LENGTH))-1)<<(32-(ITERATIONS*BLOCK_SIZE));//密钥索引值,用于生成密钥数组和填充数组的初始值unsignedintk=0;//DES算法中每个轮次的密钥索引值,用于生成每个轮次的密钥数组和填充数组的值unsignedintkplus1=(k+1)%((1<<(32-BLOCK_SIZE))-1);//DES算法中每个轮次的密钥索引值加一后的值,用于下一个轮次的密钥生成charseed[32];//使用MD5作为初始种子值生成随机数序列chartmp[MAX_INPUT_LENGTH];//临时变量数组,用于数据交换和中间计算结果存储等操作time_tt;//时间戳变量,用于生成随机数序列的种子值srand((unsignedint)time(&t));//设置随机数种子值,确保每次运行生成的随机数序列不同init_permutation(iv);//初始置换操作,将输入数据转化为56位分组(需要重复填充时)或一个随机的分组(不需要重复填充时)memcpy(key,key_offset,sizeof(key));//将初始化的密钥数组复制到相应的位置上,以便于接下来的轮次生成不同的密钥值memcpy(padding,seed,sizeof(seed));//将种子值复制到填充数组中,以便于接下来的轮次生成不同的随机数序列值for(round=0;round<ITERATIONS;round++){//进行加密轮次操作,每轮包括。

AES-256算法C语言实现

AES-256算法C语言实现

AES-256算法C语⾔实现AES是美国确⽴的⼀种⾼级数据加密算法标准,它是⼀种对数据分组进⾏对称加密的算法,这种算法是由⽐利时的Joan Daemen和Vincent Rijmen设计的,因此⼜被称为RIJNDAE算法.根据密钥长度的不同,AES标准⼜区分为AES-128, AES-192, AES-256三种,密钥越长,对每⼀数据分组进⾏的加密步骤(加密轮数)也越多.AES-128/192/256分别对应10/12/14轮加密步骤. AES-256对应的密钥长度为256bits, 其每⼀数据分组都需要进⾏14轮的加密运算,(若将初始轮+结束轮视为完整⼀轮, 总共就是14轮).AES规定每⼀数据分组长度均为128bits.由于加密过程中每⼀轮都需要⼀个密钥,因此⾸先需要从输⼊密钥(也称为种⼦密码)扩展出Nr(10/12/14)个密钥,总共是Nr+1个密钥.AES加密步骤:密钥扩展(每⼀轮加密都需要⼀个密钥) -> 初始轮加密(⽤输⼊密钥 AddRoundKey) ->重复轮加密(⽤扩展密钥SubBytes/ShiftRow/MixColumns/AddRoundKey) -> 结束轮加密(⽤扩展密钥 SubBytes/ShiftRows/AddRoundKey)AES解密步骤:密钥扩展(每⼀轮解密都需要⼀个密钥) -> 初始轮解密(⽤输⼊密钥AddRoundKey) ->重复轮解密(⽤扩展密钥InvShiftRows/InvSubBytes/AddRoundKey/InvMixColumns) -> 结束轮解密(⽤扩展密钥InvShiftRows/InvSubBytes/AddRoundKey)加/解密步骤由以下基本算⼦组成AddRoundKey: 加植密钥SubBytes: 字节代换InvSubBytes: 字节逆代换ShiftRow: ⾏移位InvShiftRow: ⾏逆移位MixColumn: 列混合InvMixColumn: 列逆混合AES的加密和解密互为逆过程, 因此两个过程其实可以相互交换.对⽂件进⾏AES加密, 就是将⽂件划分成多个数据分组,每个为128bit,然后对每⼀个数据分组进⾏如上所叙的加密处理.参考资料:Advanced Encryption Standard (AES) (FIPS PUB 197) (November 26, 2001)Advanced Encryption Standard by Example (by Adam Berent)下⾯是具体的AES-256加密解/密程序和注释.程序内也包含了AES-128/AES-192相应的测试数据,如有兴趣可以选择不同标准进⾏测试.为了演⽰⽅便,程序只进⾏了⼀个分组的加密和解密运算.并在密钥扩展和每轮计算后都将结果打印出来,以⽅便与AES标准⽂件中的例⼦进⾏⽐较.在Linux环境下编译和执⾏:gcc -o aes256 aes256.c./aes256/*---------------------------------------------------------------------This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License version 2 aspublished by the Free Software Foundation.A test for AES encryption (RIJNDAEL symmetric key encryption algorithm).Reference:1. Advanced Encryption Standard (AES) (FIPS PUB 197)2. Advanced Encryption Standard by Example (by Adam Berent)Note:1. Standard and parameters.Key Size Block Size Number of Rounds(Nk words) (Nb words) (Nr)AES-128 4 4 10AES-192 6 4 12AES-256 8 4 14Midas Zhoumidaszhou@https:///widora/wegi----------------------------------------------------------------------*/#include <stdio.h>#include <stdint.h>#include <string.h>/* S_BOX S盒 */static const uint8_t sbox[256] = {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 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 };/* Reverse S_BOX 反向S盒 */static const uint8_t rsbox[256] = {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 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 };/* Galois Field Multiplication E-table GF乘法E表 */static const uint8_t Etab[256]= {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};/* Galois Field Multiplication L-table GF乘法L表 */static const uint8_t Ltab[256]= {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */0x0, 0x0, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03, // 00x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, // 10x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78, // 20x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, // 30x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38, // 40x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, // 50x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA, // 60x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, // 70xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8, // 80x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, // 90x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, // A0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D, // B0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, // C0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB, // D0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, // E0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07 // F};/* RCON 表 */static const uint32_t Rcon[15]= {0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000,0x40000000,0x80000000,0x1B000000,0x36000000,0x6C000000,0xD8000000,0xAB000000,0x4D000000,0x9A000000};/* Functions */void print_state(const uint8_t *s); /* 打印分组数据 */int aes_ShiftRows(uint8_t *state); /* ⾏移位 */int aes_InvShiftRows(uint8_t *state); /* ⾏逆移位 */int aes_ExpRoundKeys(uint8_t Nr, uint8_t Nk, const uint8_t *inkey, uint32_t *keywords); /* 密钥扩展 */int aes_AddRoundKey(uint8_t Nr, uint8_t Nk, uint8_t round, uint8_t *state, const uint32_t *keywords); /* 加植密钥 */ int aes_EncryptState(uint8_t Nr, uint8_t Nk, uint32_t *keywords, uint8_t *state); /* 分组加密 */int aes_DecryptState(uint8_t Nr, uint8_t Nk, uint32_t *keywords, uint8_t *state); /* 分组解密 *//*==============MAIN===============*/int main(void){int i,k;const uint8_t Nb=4; /* 分组长度 Block size in words, 4/4/4 for AES-128/192/256 */uint8_t Nk; /* 密钥长度 column number, as of 4xNk, 4/6/8 for AES-128/192/256 */uint8_t Nr; /* 加密轮数 Number of rounds, 10/12/14 for AES-128/192/256 */uint8_t state[4*4]; /* 分组数据 State array, data in row sequence! */uint64_t ns; /* 总分组数 Total number of states *//* 待加密数据 */const uint8_t input_msg[]= {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};/* AES-128/192/256 对应的密钥长度,加密轮数, 输⼊密钥 */#if 0 /* TEST data --- AES-128 */Nk=4;Nr=10;const uint8_t inkey[4*4]= { /* Nb*Nk */0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};#endif#if 0 /* TEST data --- AES-192 */Nk=6;Nr=12;const uint8_t inkey[4*6]= { /* Nb*Nk */0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17};#endif#if 1 /* TEST data --- AES-256 */Nk=8;Nr=14;const uint8_t inkey[4*8]= { /* Nb*Nk */0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};#endif/* 密钥扩展测试数据------TEST: For Key expansion */#if 0Nk=4;Nr=10;const uint8_t inkey[4*4]= /* Nb*Nk */{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; #endif#if 0Nk=6;Nr=12;const uint8_t inkey[4*6]= /* Nb*Nk */{ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b,0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };#endif#if 0Nk=8;const uint8_t inkey[4*8]= /* Nb*Nk */{ 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };#endifuint32_t keywords[Nb*(Nr+1)]; /* ⽤于存放扩展密钥,总共Nr+1把密钥 Nb==4, All expended keys, as of words in a column: 0xb0b1b2b3 *//* 从输⼊密钥产⽣Nk+1个轮密,每轮需要⼀个密钥 Generate round keys */aes_ExpRoundKeys(Nr, Nk, inkey, keywords);/* 数据分组数量,这⾥我们只设定为1组. Cal. total states *///ns=(strlen(input_msg)+15)/16;ns=1;/* 如果是多个分组,那么分别对每个分组进⾏加密,i=0 ~ ns-1 */i=0; /* i=0 ~ ns-1 *//* 将待加密数据放⼊到数据分组state[]中,注意:state[]中数据按column顺序存放! */bzero(state,16);for(k=0; k<16; k++)state[(k%4)*4+k/4]=input_msg[i*16+k];/* 加密数据分组 Encrypt each state */aes_EncryptState(Nr, Nk, keywords, state);/* 打印加密后的分组数据 */printf("***********************************\n");printf("******* Finish Encryption *******\n");printf("***********************************\n");print_state(state);/* 解密数据分组 Decrypt state */aes_DecryptState(Nr, Nk, keywords, state);//printf("Finish decrypt message, Round Nr=%d, KeySize Nk=%d, States ns=%llu.\n", Nr, Nk, ns);/* 打印解密后的分组数据 */printf("***********************************\n");printf("******* Finish Decryption *******\n");printf("***********************************\n");print_state(state);return 0;}/* 打印分组数据 Print state */void print_state(const uint8_t *s){int i,j;for(i=0; i<4; i++) {for(j=0; j<4; j++) {printf("%02x",s[i*4+j]);//printf("'%c'",s[i*4+j]); /* A control key MAY erase previous chars on screen! */printf(" ");}printf("\n");}printf("\n");}/*------------------------------⾏移位Shift operation of the state.Return:0 OK<0 Fails-------------------------------*/int aes_ShiftRows(uint8_t *state){int j,k;uint8_t tmp;if(state==NULL)return -1;for(k=0; k<4; k++) {/* each row shift k times */for(j=0; j<k; j++) {tmp=*(state+4*k); /* save the first byte *///memcpy(state+4*k, state+4*k+1, 3);memmove(state+4*k, state+4*k+1, 3);*(state+4*k+3)=tmp; /* set the last byte */}}return 0;}/*------------------------------⾏逆移位Shift operation of the state.@state[4*4]Return:0 OK<0 Fails-------------------------------*/int aes_InvShiftRows(uint8_t *state){int j,k;uint8_t tmp;if(state==NULL)return -1;for(k=0; k<4; k++) {/* each row shift k times */for(j=0; j<k; j++) {tmp=*(state+4*k+3); /* save the last byte */memmove(state+4*k+1, state+4*k, 3);*(state+4*k)=tmp; /* set the first byte */}}return 0;}/*-------------------------------------------------------------加植密钥Add round key to the state.@Nr: Number of rounds, 10/12/14 for AES-128/192/256 @Nk: Key size, in words.@round: Current round number.@state: Pointer to state.@keywords[Nb*(Nr+1)]: All round keys, in words.int aes_AddRoundKey(uint8_t Nr, uint8_t Nk, uint8_t round, uint8_t *state, const uint32_t *keywords){int k;if(state==NULL || keywords==NULL)return -1;for(k=0; k<4*4; k++)state[k] = ( keywords[round*4+k%4]>>((3-(k>>2))<<3) &0xFF )^state[k];return 0;}/*----------------------------------------------------------------------------------------------------------密钥扩展从输⼊密钥(也称为种⼦密码)扩展出Nr(10/12/14)个密钥,总共是Nr+1个密钥Generate round keys.@Nr: Number of rounds, 10/12/14 for AES-128/192/256@Nk: Key size, in words.@inkey[4*Nk]: Original key, 4*Nk bytes, arranged row by row.@keywords[Nb*(Nr+1)]: Output keys, in words. Nb*(Nr+1)one keywords(32 bytes) as one column of key_bytes(4 bytes)Note:1. The caller MUST ensure enough mem space of input params.Return:0 Ok<0 Fails---------------------------------------------------------------------------------------------------------------*/int aes_ExpRoundKeys(uint8_t Nr, uint8_t Nk, const uint8_t *inkey, uint32_t *keywords){int i;const int Nb=4;uint32_t temp;if(inkey==NULL || keywords==NULL)return -1;/* Re_arrange inkey to keywords, convert 4x8bytes each row_data to a 32bytes keyword, as a complex column_data. */ for( i=0; i<Nk; i++ ) {keywords[i]=(inkey[4*i]<<24)+(inkey[4*i+1]<<16)+(inkey[4*i+2]<<8)+inkey[4*i+3];}/* Expend round keys */for(i=Nk; i<Nb*(Nr+1); i++) {temp=keywords[i-1];if( i%Nk==0 ) {/* RotWord */temp=( temp<<8 )+( temp>>24 );/* Subword */temp=(sbox[temp>>24]<<24) +(sbox[(temp>>16)&0xFF]<<16) +(sbox[(temp>>8)&0xFF]<<8)+sbox[temp&0xFF];/* temp=SubWord(RotWord(temp)) XOR Rcon[i/Nk-1] */temp=temp ^ Rcon[i/Nk-1];}else if (Nk>6 && i%Nk==4 ) {/* Subword */temp=(sbox[temp>>24]<<24) +(sbox[(temp>>16)&0xFF]<<16) +(sbox[(temp>>8)&0xFF]<<8)+sbox[temp&0xFF];}/* Get keywords[i] */}/* Print all keys */for(i=0; i<Nb*(Nr+1); i++)printf("keywords[%d]=0x%08X\n", i, keywords[i]);return 0;}/*----------------------------------------------------------------------数据分组加密Encrypt state.@Nr: Number of rounds, 10/12/14 for AES-128/192/256@Nk: Key length, in words.@keywordss[Nb*(Nr+1)]: All round keys, in words.@state[4*4]: The state block.Note:1. The caller MUST ensure enough mem space of input params.Return:0 Ok<0 Fails------------------------------------------------------------------------*/int aes_EncryptState(uint8_t Nr, uint8_t Nk, uint32_t *keywords, uint8_t *state) {int i,k;uint8_t round;uint8_t mc[4]; /* Temp. var */if(keywords==NULL || state==NULL)return -1;/* 1. AddRoundKey: 加植密钥 */printf(" --- Add Round_key ---\n");aes_AddRoundKey(Nr, Nk, 0, state, keywords);print_state(state);/* 循环Nr-1轮加密运算 Run Nr round functions */for( round=1; round<Nr; round++) { /* Nr *//* 2. SubBytes: 字节代换 Substitue State Bytes with SBOX */printf(" --- SubBytes() Round:%d ---\n",round);for(k=0; k<16; k++)state[k]=sbox[state[k]];print_state(state);/* 3. ShiftRow: ⾏移位 Shift State Rows */printf(" --- ShiftRows() Round:%d ---\n",round);aes_ShiftRows(state);print_state(state);/* 4. MixColumn: 列混合 Mix State Cloumns *//* Galois Field Multiplication, Multi_Matrix:2 3 1 11 2 3 11 12 33 1 1 2Note:1. Any number multiplied by 1 is equal to the number itself.2. Any number multiplied by 0 is 0!*/printf(" --- MixColumn() Round:%d ---\n",round);mc[0]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[2])%0xFF] )^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[3])%0xFF] )^state[i+8]^state[i+12];mc[1]= state[i]^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[2])%0xFF] )^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[3])%0xFF] )^state[i+12];mc[2]= state[i]^state[i+4]^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[2])%0xFF] )^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[3])%0xFF] );mc[3]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[3])%0xFF] )^state[i+4]^state[i+8]^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[2])%0xFF] );state[i+0]=mc[0];state[i+4]=mc[1];state[i+8]=mc[2];state[i+12]=mc[3];}print_state(state);/* 5. AddRoundKey: 加植密钥 Add State with Round Key */printf(" --- Add Round_key ---\n");aes_AddRoundKey(Nr, Nk, round, state, keywords);print_state(state);} /* END Nr rounds *//* 6. SubBytes: 字节代换 Substitue State Bytes with SBOX */printf(" --- SubBytes() Round:%d ---\n",round);for(k=0; k<16; k++)state[k]=sbox[state[k]];print_state(state);/* 7. ShiftRow: ⾏移位 Shift State Rows */printf(" --- ShiftRows() Round:%d ---\n",round);aes_ShiftRows(state);print_state(state);/* 8. AddRoundKey: 加植密钥 Add State with Round Key */printf(" --- Add Round_key ---\n");aes_AddRoundKey(Nr, Nk, round, state, keywords);print_state(state);return 0;}/*----------------------------------------------------------------------Decrypt the state.@Nr: Number of rounds, 10/12/14 for AES-128/192/256@Nk: Key length, in words.@keywordss[Nb*(Nr+1)]: All round keys, in words.@state[4*4]: The state block.Note:1. The caller MUST ensure enough mem space of input params.Return:0 Ok<0 Fails------------------------------------------------------------------------*/int aes_DecryptState(uint8_t Nr, uint8_t Nk, uint32_t *keywords, uint8_t *state)int i,k;uint8_t round;uint8_t mc[4]; /* Temp. var */if(keywords==NULL || state==NULL)return -1;/* 1. AddRoundKey: 加植密钥 Add round key */printf(" --- Add Round_key ---\n");aes_AddRoundKey(Nr, Nk, Nr, state, keywords); /* From Nr_th round */ print_state(state);/* 循环Nr-1轮加密运算 Run Nr round functions */for( round=Nr-1; round>0; round--) { /* round [Nr-1 1] *//* 2. InvShiftRow: ⾏逆移位 InvShift State Rows */printf(" --- InvShiftRows() Round:%d ---\n",Nr-round);aes_InvShiftRows(state);print_state(state);/* 3. InvSubBytes: 字节逆代换 InvSubstitue State Bytes with R_SBOX */printf(" --- (Inv)SubBytes() Round:%d ---\n",Nr-round);for(k=0; k<16; k++)state[k]=rsbox[state[k]];print_state(state);/* 4. AddRoundKey: 加植密钥 Add State with Round Key */printf(" --- Add Round_key Round:%d ---\n", Nr-round);aes_AddRoundKey(Nr, Nk, round, state, keywords);print_state(state);/* 5. InvMixColumn: 列逆混合 Inverse Mix State Cloumns *//* Galois Field Multiplication, Multi_Matrix:0x0E 0x0B 0x0D 0x090x09 0x0E 0x0B 0x0D0x0D 0x09 0x0E 0x0B0x0B 0x0D 0x09 0x0ENote:1. Any number multiplied by 1 is equal to the number itself.2. Any number multiplied by 0 is 0!*/printf(" --- InvMixColumn() Round:%d ---\n",Nr-round);for(i=0; i<4; i++) { /* i as column index */mc[0]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[0x0E])%0xFF] )^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[0x0B])%0xFF] )^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[0x0D])%0xFF] )^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[0x09])%0xFF] );mc[1]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[0x09])%0xFF] )^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[0x0E])%0xFF] )^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[0x0B])%0xFF] )^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[0x0D])%0xFF] );mc[2]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[0x0D])%0xFF] )^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[0x09])%0xFF] )^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[0x0E])%0xFF] )^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[0x0B])%0xFF] );mc[3]= ( state[i]==0 ? 0 : Etab[(Ltab[state[i]]+Ltab[0x0B])%0xFF] )^( state[i+4]==0 ? 0 : Etab[(Ltab[state[i+4]]+Ltab[0x0D])%0xFF] )^( state[i+8]==0 ? 0 : Etab[(Ltab[state[i+8]]+Ltab[0x09])%0xFF] )^( state[i+12]==0 ? 0 : Etab[(Ltab[state[i+12]]+Ltab[0x0E])%0xFF] );state[i+0]=mc[0];state[i+4]=mc[1];state[i+8]=mc[2];state[i+12]=mc[3];print_state(state);} /* END Nr rounds *//* 6. InvShiftRow: ⾏逆移位 Inverse Shift State Rows */printf(" --- InvShiftRows() Round:%d ---\n",Nr-round);aes_InvShiftRows(state);print_state(state);/* 7. InvSubBytes: 字节逆代换 InvSubstitue State Bytes with SBOX */ printf(" --- InvSubBytes() Round:%d ---\n",Nr-round);for(k=0; k<16; k++)state[k]=rsbox[state[k]];print_state(state);/* 8. AddRoundKey: 加植密钥 Add State with Round Key */printf(" --- Add Round_key Round:%d ---\n",Nr-round);aes_AddRoundKey(Nr, Nk, 0, state, keywords);print_state(state);return 0;}。

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

C语言实现数据加密算法
数据加密是一种保护信息安全性的重要手段。

在C语言中,有多种方
式可以实现数据加密算法。

下面将介绍几种常见的加密算法及其实现原理。

1.凯撒密码
凯撒密码是一种简单的替换密码。

它的原理是将明文中的每个字母按
照指定的位移量进行替换。

例如,将字母'A'替换成字母'D',字母'B'替
换成字母'E',以此类推。

解密过程与加密过程相反。

```c
#include <stdio.h>
void encrypt(char* message, int key)
int i = 0;
char ch;
while (message[i])
ch = message[i];
if (ch >= 'A' && ch <= 'Z')
ch = ((ch - 'A') + key) % 26 + 'A';
}
else if (ch >= 'a' && ch <= 'z')
ch = ((ch - 'a') + key) % 26 + 'a';
}
message[i] = ch;
i++;
}
void decrypt(char* message, int key)
int i = 0;
char ch;
while (message[i])
ch = message[i];
if (ch >= 'A' && ch <= 'Z')
ch = ((ch - 'A') - key + 26) % 26 + 'A'; }
else if (ch >= 'a' && ch <= 'z')
ch = ((ch - 'a') - key + 26) % 26 + 'a'; }
message[i] = ch;
i++;
}
int mai
char message[100];
int key;
printf("Enter message: ");
fgets(message, sizeof(message), stdin);
printf("Enter key: ");
scanf("%d", &key);
encrypt(message, key);
printf("Encrypted message: %s\n", message);
decrypt(message, key);
printf("Decrypted message: %s\n", message);
return 0;
```
2.DES(数据加密标准)
DES是一种对称密钥的分组密码算法。

它将明文按照64位分组,然后通过一系列的置换、替换、位移和异或运算,得到密文。

解密过程与加密过程相反。

DES需要使用一个64位的密钥进行加密和解密。

```c
#include <stdio.h>
#include <stdint.h>
#define NUM_ROUNDS 16
const int initial_permutation_table[64] = { ... }; const int final_permutation_table[64] = { ... };
const int expansion_table[48] = { ... };
const int permutation_table[32] = { ... };
const int sbox[8][4][16] = { ... };
const int key_schedule_shifts[NUM_ROUNDS] = { ... }; const int key_permutation_table[56] = { ... };
void initial_permutation(uint32_t* data)
// Initial permutation step
// TODO: Implement
void final_permutation(uint32_t* data)
// Final permutation step
// TODO: Implement
void expansion(uint32_t* data, uint32_t* expanded_data) // Expansion step
// TODO: Implement
void permutation(uint32_t* data)
// Permutation step
// TODO: Implement
void sbox_substitution(uint32_t* data)
// S-Box substitution step
// TODO: Implement
void key_schedule(uint32_t* key, uint32_t* key_schedule) // Key schedule generation step
// TODO: Implement
void xor(uint32_t* a, uint32_t* b)
// XOR operation
// TODO: Implement
void des_encrypt(uint32_t* plaintext, uint32_t* key, uint32_t* ciphertext)
uint32_t temp, left, right;
uint32_t expanded_data[48];
uint32_t subkey[48];
int round;
initial_permutation(plaintext);
left = (plaintext[0] >> 32) & 0xFFFFFFFF;
right = plaintext[0] & 0xFFFFFFFF;
key_schedule(key, subkey);
for (round = 0; round < NUM_ROUNDS; round++) // Expansion
expansion(&right, expanded_data);
// XOR with subkey
xor(expanded_data, subkey);
// S-Box substitution
sbox_substitution(expanded_data);
// Permutation
permutation(expanded_data);
// XOR with left half
xor(&left, expanded_data);
// Swap left and right
temp = left;
left = right;
right = temp;
// Shift subkey
key_schedule_shift(subkey, round);
}
plaintext[0] = (right << 32) , left;
final_permutation(plaintext);
void des_decrypt(uint32_t* ciphertext, uint32_t* key,
uint32_t* plaintext)
// TODO: Implement
// Similar to des_encrypt, but with a few modifications
int mai
// TODO: Implement
return 0;
```
以上是两种常见的加密算法的C语言实现示例。

通过这些示例,可以
了解到加密算法的基本原理和实现过程。

需要注意的是,这只是示例代码,并不是完整的实现。

实际的实现需要更多的细节和安全性考虑。

相关文档
最新文档