📄 aes.c
字号:
}//AES加密函数void AES_encrypt(const byte in[16], byte out[16], const byte key[16]){ word state[4], temp[4], key_ex[44]; int i; for (i = 0; i < 4; i++) state[i] = Byte2Word(&in[i*4]); KeyExpansion(key, key_ex); AddRoundKey(state, &key_ex[0]); for (i = 1; i < 10; i++) { MixColumns_ShifRows(state); AddRoundKey(state, &key_ex[i*4]); } temp[0] = sbox[(byte)(state[0])] | sbox[(byte)(state[1] >> 8)] << 8 | sbox[(byte)(state[2] >> 16)] << 16 | sbox[(byte)(state[3] >> 24)] << 24; temp[1] = sbox[(byte)(state[1])] | sbox[(byte)(state[2] >> 8)] << 8 | sbox[(byte)(state[3] >> 16)] << 16 | sbox[(byte)(state[0] >> 24)] << 24; temp[2] = sbox[(byte)(state[2])] | sbox[(byte)(state[3] >> 8)] << 8 | sbox[(byte)(state[0] >> 16)] << 16 | sbox[(byte)(state[1] >> 24)] << 24; temp[3] = sbox[(byte)(state[3])] | sbox[(byte)(state[0] >> 8)] << 8 | sbox[(byte)(state[1] >> 16)] << 16 | sbox[(byte)(state[2] >> 24)] << 24; AddRoundKey(temp, &key_ex[i*4]); for (i = 0; i < 4; i++) Word2Byte(temp[i], &out[i*4]);}//AES解密函数void AES_decrypt(const byte in[16], byte out[16], const byte key[16]){ word state[4], temp[4], key_ex[44]; int i; for (i = 0; i < 4; i++) state[i] = Byte2Word(&in[i*4]); KeyExpansion(key, key_ex); for (i = 1; i < 10; i++) { InvMixColumns(&key_ex[i*4]); } AddRoundKey(state, &key_ex[10 * 4]); for (i = 9; i > 0; i--) { state[0] = InvSubWord(state[0]); state[1] = InvSubWord(state[1]); state[2] = InvSubWord(state[2]); state[3] = InvSubWord(state[3]); InvMixColumns_ShiftRows(state); AddRoundKey(state, &key_ex[i*4]); } temp[0] = invsbox[(byte)(state[0])] | invsbox[(byte)(state[3] >> 8)] << 8 | invsbox[(byte)(state[2] >> 16)] << 16 | invsbox[(byte)(state[1] >> 24)] << 24; temp[1] = invsbox[(byte)(state[1])] | invsbox[(byte)(state[0] >> 8)] << 8 | invsbox[(byte)(state[3] >> 16)] << 16 | invsbox[(byte)(state[2] >> 24)] << 24; temp[2] = invsbox[(byte)(state[2])] | invsbox[(byte)(state[1] >> 8)] << 8 | invsbox[(byte)(state[0] >> 16)] << 16 | invsbox[(byte)(state[3] >> 24)] << 24; temp[3] = invsbox[(byte)(state[3])] | invsbox[(byte)(state[2] >> 8)] << 8 | invsbox[(byte)(state[1] >> 16)] << 16 | invsbox[(byte)(state[0] >> 24)] << 24; AddRoundKey(temp, &key_ex[i*4]); for (i = 0; i < 4; i++) Word2Byte(temp[i], &out[i*4]);}/* int main() *//* { *//* byte a[16] = {0, 1, 2, 3, 4, 5, 6, 7, *//* 8, 9, 10, 11, 12, 13, 14, 15}; *//* word w[44]; *//* word b[4] = {0x3d7c6ebd, 0x9e77b5f2, 0x6e21610b, 0x89b6108b}; *//* byte key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, *//* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; *//* int i; *//* byte input[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, *//* 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; *//* byte ckey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, *//* 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; *//* byte output[16]; *//* clock_t start, finish; *//* double duration; *//* start = clock(); *//* for (i = 0; i < 1000000; i++) *//* AES_encrypt(input, output, ckey); *//* finish = clock(); *//* duration = (double)(finish - start) / CLOCKS_PER_SEC; *//* printf("%lf\n", duration); *//* for (i = 0; i < 16; i++) *//* printf("%02x", output[i]); *//* printf("\n"); */ /* return 0; *//* } *///AES文件加密函数/* 文件加密采用ECB模式,也就是电话簿模式,别的模式有待实现 最后在文件的尾部写入加密文件的大小(当然也是加密过的数据) @param fr 需要加密的文件 @param fw 加密后输出的文件 @param key 加密所需的密钥*/int AES_file_encrypt(const char* fr, const char* fw, const byte key[16]){ byte buf[BLOCK_SIZE]; FILE *fp_r, *fp_w; int i, r_size; if ((fp_r = fopen(fr, "rb")) == NULL) { fprintf(stderr, "Error reading file."); return 1; } if ((fp_w = fopen(fw, "wb")) == NULL) { fprintf(stderr, "Error reading file."); fclose(fp_r); return 1; } //读入初始的文件块 r_size = fread(buf, sizeof(byte), BLOCK_SIZE, fp_r); while (r_size == BLOCK_SIZE) { //加密文件快 AES_encrypt(buf, buf, key); //写入到文件 fwrite(buf, sizeof(byte), BLOCK_SIZE, fp_w); //读入下一个块 r_size = fread(buf, sizeof(byte), BLOCK_SIZE, fp_r); } //如果不是文件结束,返回错误值 if (!feof(fp_r)) { fprintf(stderr, "Error reading file in feof."); fclose(fp_r); fclose(fp_w); return 1; } //写入最后一块,不够16位的补零 for (i = r_size; i < BLOCK_SIZE; i++) buf[i] = 0; AES_encrypt(buf, buf, key); fwrite(buf, sizeof(byte), BLOCK_SIZE, fp_w); *((int *)buf) = ftell(fp_r); AES_encrypt(buf, buf, key); //写入文件大小,放在最后 fwrite(buf, sizeof(byte), BLOCK_SIZE, fp_w);/* for (i = 0; i < BLOCK_SIZE; i++) *//* printf("%02x ", buf[i]); *//* printf("\n"); *//* printf("last count:%d\n", r_size); */ fclose(fp_r); fclose(fp_w); return 0;}//AES文件解密密函数/* 文件解密密同样采用ECB模式 @param fr 需要解密的文件 @param fw 解密后输出的文件 @param key 解密所需的密钥*/int AES_file_decrypt(const char* fr, const char* fw, const byte key[16]){ byte buf1[BLOCK_SIZE], buf2[BLOCK_SIZE], buf3[BLOCK_SIZE], *p, *q, *r, *t; FILE *fp_r, *fp_w; int r_size, diff; if ((fp_r = fopen(fr, "rb")) == NULL) { fprintf(stderr, "Error reading file."); return 1; } if ((fp_w = fopen(fw, "wb")) == NULL) { fprintf(stderr, "Error reading file."); fclose(fp_r); return 1; } p = buf1, q = buf2, r = buf3; r_size = fread(p, sizeof(byte), BLOCK_SIZE, fp_r); //读入初始的两块 if (r_size != BLOCK_SIZE) { fprintf(stderr, "Decrypt file failed"); fclose(fp_r); fclose(fp_w); return 1; } r_size = fread(q, sizeof(byte), BLOCK_SIZE, fp_r); if (r_size != BLOCK_SIZE) { fprintf(stderr, "Decrypt file failed"); fclose(fp_r); fclose(fp_w); return 1; } r_size = fread(r, sizeof(byte), BLOCK_SIZE, fp_r); while (r_size == BLOCK_SIZE) { //先解密然后再写入 AES_decrypt(p, p, key); fwrite(p, sizeof(byte), BLOCK_SIZE, fp_w); t = p; p = q; q = r; r = t; //读入下一块 r_size = fread(r, sizeof(byte), BLOCK_SIZE, fp_r);/* for (i = 0; i < BLOCK_SIZE; i++) *//* printf("%02x ", p[i]); *//* printf("\n"); *//* for (i = 0; i < BLOCK_SIZE; i++) *//* printf("%02x ", q[i]); *//* printf("\n"); *//* for (i = 0; i < BLOCK_SIZE; i++) *//* printf("%02x ", r[i]); *//* printf("\n"); */ } if (!feof(fp_r)) { fprintf(stderr, "Error reading file in feof."); fclose(fp_r); fclose(fp_w); return 1; } //解密最后的两块,最后一块放的是加密前文件的大小 AES_decrypt(p, p, key); AES_decrypt(q, q, key); //计算倒数第二块的大小,并写入 diff = 32 + *(int *)q - ftell(fp_r); if (diff > 0 && diff < 16) fwrite(p, sizeof(byte), diff, fp_w); fclose(fp_r); fclose(fp_w); return 0;}/* * 实例: * 加密接口: AES_file_encrypt * 解密接口: AES_file_decrypt */int main(){ //密钥 可以自己修改 byte ckey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; clock_t start, finish; double duration; start = clock(); //对文件进行加密: 第一个参数"enc.rar"是所需要加密的文件,第二个参数enc.rar.enc是加密后的文件名, //第三个参数是上面自己设置的密钥 AES_file_encrypt("enc.rar", "enc.rar.enc", ckey); //对已加过密的文件进行解密: 其中"enc.rar.dec"是解密后的文件。 AES_file_decrypt("enc.rar.enc", "enc.rar.dec", ckey); /* AES_file_encrypt("aes.o", "aes.o.enc", ckey); AES_file_decrypt("aes.o.enc", "aes.o.dec", ckey); */ finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf("%lf", duration); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -