看来,用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];
}
}
}