AES文件加密项目分析(4)

看来,用Python实现AES太慢了。
还得靠C语言实现,先分析这个项目吧:AES

直接用这个项目来加密文件不合适,必要时需要改改:
(1)用于加密的原文:

uint8_t in[] = {
		0x00, 0x11, 0x22, 0x33,
		0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xaa, 0xbb,
		0xcc, 0xdd, 0xee, 0xff};

按照这篇文章的说法:C - Type - What are uint8_t, uint16_t, uint32_t and uint64_t?
uint_8就相当于unsigned char,用二进制表示为一个字节。
如果打开视频文件时,也能弄成逐个字节的就好了。按照这篇文章:
How to read a video file using C
打开视频文件用到fopen函数。
根据C fopen() function with Examples

The fopen() method in C is a library function that is used to open a file to perform various operations which include reading, writing, etc. along with various modes. If the file exists then the fopen() function opens the particular file else a new file is created.

下面的案例,比方说要创建一个新文件:

// C program to illustrate fopen()

#include <stdio.h>
#include <stdlib.h>

int main()
{

	// pointer demo to FILE
	FILE* demo;

	// Creates a file "demo_file"
	// with file access as write-plus mode
	demo = fopen("demo_file.txt", "w+");

	// adds content to the file
	fprintf(demo, "%s %s %s", "Welcome", "to",
			"GeeksforGeeks");

	// closes the file pointed by demo
	fclose(demo);

	return 0;
}

这样会创立新文件“demo_file.txt”,其内容为:

Welcome to GeeksforGeeks

如果我们想要读这个文件的内容,就可以这样:

// C program to illustrate fopen()

#include <stdio.h>

int main()
{

	// pointer demo to FILE
	FILE* demo;
	int display;

	// Creates a file "demo_file"
	// with file access as read mode
	demo = fopen("demo_file.txt", "r");

	// loop to extract every characters
	while (1) {
		// reading file
		display = fgetc(demo);

		// end of file indicator
		if (feof(demo))
			break;

		// displaying every characters
		printf("%c", display);
	}

	// closes the file pointed by demo
	fclose(demo);

	return 0;
}

注意函数fgetc():(来自C library function - fgetc()

The C library function int fgetc(FILE *stream) gets the next character (an unsigned char) from the specified stream and advances the position indicator for the stream.This function returns the character read as an unsigned char cast to an int or EOF on end of file or error.

(2)密钥:

uint8_t key[] = {
		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};

(3)定义扩展密钥并为其分配空间

uint8_t *w; // expanded key
w = aes_init(sizeof(key));

// 函数原型:
uint8_t *aes_init(size_t key_size) {

        switch (key_size) {
		default:
		case 16: Nk = 4; Nr = 10; break;
		case 24: Nk = 6; Nr = 12; break;
		case 32: Nk = 8; Nr = 14; break;
	}

	return malloc(Nb*(Nr+1)*4);
}

Nk是组成加密密钥的32位字(4字节字的个数);
Nr是轮次个数
Nb是state的列数,Nb = 4

(4)密钥扩展:

aes_key_expansion(key, w);

// 函数原型:
void aes_key_expansion(uint8_t *key, uint8_t *w) {

	uint8_t tmp[4];
	uint8_t i;
	uint8_t len = Nb*(Nr+1);

	for (i = 0; i < Nk; i++) {
		w[4*i+0] = key[4*i+0];
		w[4*i+1] = key[4*i+1];
		w[4*i+2] = key[4*i+2];
		w[4*i+3] = key[4*i+3];
	}

	for (i = Nk; i < len; i++) {
		tmp[0] = w[4*(i-1)+0];
		tmp[1] = w[4*(i-1)+1];
		tmp[2] = w[4*(i-1)+2];
		tmp[3] = w[4*(i-1)+3];

		if (i%Nk == 0) {

			rot_word(tmp);
			sub_word(tmp);
			coef_add(tmp, Rcon(i/Nk), tmp);

		} else if (Nk > 6 && i%Nk == 4) {

			sub_word(tmp);

		}

		w[4*i+0] = w[4*(i-Nk)+0]^tmp[0];
		w[4*i+1] = w[4*(i-Nk)+1]^tmp[1];
		w[4*i+2] = w[4*(i-Nk)+2]^tmp[2];
		w[4*i+3] = w[4*(i-Nk)+3]^tmp[3];
	}
}

(5)执行加密:

aes_cipher(in /* in */, out /* out */, w /* expanded key */);

// 函数原型:
void aes_cipher(uint8_t *in, uint8_t *out, uint8_t *w) {

	uint8_t state[4*Nb];
	uint8_t r, i, j;

	for (i = 0; i < 4; i++) {
		for (j = 0; j < Nb; j++) {
			state[Nb*i+j] = in[i+4*j];
		}
	}

	add_round_key(state, w, 0);

	for (r = 1; r < Nr; r++) {
		sub_bytes(state);
		shift_rows(state);
		mix_columns(state);
		add_round_key(state, w, r);
	}

	sub_bytes(state);
	shift_rows(state);
	add_round_key(state, w, Nr);

	for (i = 0; i < 4; i++) {
		for (j = 0; j < Nb; j++) {
			out[i+4*j] = state[Nb*i+j];
		}
	}
}

(6)执行解密

aes_inv_cipher(out, in, w);

// 函数原型:
void aes_inv_cipher(uint8_t *in, uint8_t *out, uint8_t *w) {

	uint8_t state[4*Nb];
	uint8_t r, i, j;

	for (i = 0; i < 4; i++) {
		for (j = 0; j < Nb; j++) {
			state[Nb*i+j] = in[i+4*j];
		}
	}

	add_round_key(state, w, Nr);

	for (r = Nr-1; r >= 1; r--) {
		inv_shift_rows(state);
		inv_sub_bytes(state);
		add_round_key(state, w, r);
		inv_mix_columns(state);
	}

	inv_shift_rows(state);
	inv_sub_bytes(state);
	add_round_key(state, w, 0);

	for (i = 0; i < 4; i++) {
		for (j = 0; j < Nb; j++) {
			out[i+4*j] = state[Nb*i+j];
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值