使用Openssl的AES加密算法
http://blog.gpjtag.com/?p=18
在网络应用的信息安全是基于密码学的,所以如果想做安全方面的邻域需要有一定的密码学基础。当然最好的学习方法就是边看书边尝试。
我的学习过程有三个阶段:
- 看书、通过使用一些软件了解基本的流程。
- 深入算法,自己实现部分加密算法。
- 了解常用的库的用法。
有人说“不要重复造轮子,有现成的要拿来用。”我赞同,但是这个的前提是你造过轮子,知道装配轮子的时候会有什么注意事项:)
所以在学习的过程中一定要“自己造轮子”,在工作的时候一定要“找轮子,用现成的”:)
Openssl是很常见的C接口的库,个人觉得易用。以下是AES加密的使用备忘。如果你有一定的密码学基础,那么就很好理解。代码是从网上弄下来的(原始地址已经忘记了),然后在尝试的过程中改了一点东西。其它的cbc、cfb、ecb加密方式的用法都是类似的,只是函数名有点区别,就不一一列举了。
一、接口简介
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//设置加密密钥,使用字符缓冲区
int
AES_set_encrypt_key(
const
unsigned
char
*userKey,
const
int
bits,
AES_KEY *key);
//设置解密密钥,同样适用字符缓冲区
int
AES_set_decrypt_key(
const
unsigned
char
*userKey,
const
int
bits,
AES_KEY *key);
//加解密的接口,通过最后的enc来区分是加密还是解密操作
//每次执行AES_cbc_encrypt后,iv(向量)会被更新,
//所以需要自己保存它。
void
AES_cbc_encrypt(
const
unsigned
char
*in,
unsigned
char
*out,
const
unsigned
long
length,
const
AES_KEY *key,
unsigned
char
*ivec,
const
int
enc);
|
二、一个简单的Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
CFLAGS = /nologo /I .. /c /Fo./objs/
LFLAGS = /nologo
LLIBS = ../lib/ssleay32MD.lib ../lib/libeay32MD.lib
all:./release/testaes.exe
./release/testaes.exe:./objs/testaes.obj
link $(LFLAGS) ./objs/testaes.obj $(LLIBS) \
/out:./release/testaes.exe
{.}.cpp{./objs}.obj:
cl $(CFLAGS) $<
clean:
rm -rf *.obj
|
三、示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
/* file testaes.cpp */
static
void
hexdump(
FILE
*f,
const
char
*title,
const
unsigned
char
*s,
int
l)
{
int
n = 0;
fprintf
(f,
"%s"
, title);
for
(; n < l; ++n) {
if
((n % 16) == 0) {
fprintf
(f,
"\n%04x"
, n);
}
fprintf
(f,
" %02x"
, s[n]);
}
fprintf
(f,
"\n"
);
}
int
main(
int
argc,
char
**argv)
{
//256bits key.
unsigned
char
rkey[16];
//Internal key.
AES_KEY key;
//Testdata.
unsigned
char
plaintext[AES_BLOCK_SIZE * 4];
unsigned
char
ciphertext[AES_BLOCK_SIZE * 4];
unsigned
char
checktext[AES_BLOCK_SIZE * 4];
//Init vector.
unsigned
char
iv[AES_BLOCK_SIZE * 4];
//Save vector.
unsigned
char
saved_iv[AES_BLOCK_SIZE * 4];
int
nr_of_bits = 0;
int
nr_of_bytes = 0;
//Zeror buffer.
memset
(plaintext, 0,
sizeof
plaintext);
memset
(ciphertext, 0,
sizeof
ciphertext);
memset
(checktext, 0,
sizeof
checktext);
//Generate random
RAND_pseudo_bytes(rkey,
sizeof
rkey);
RAND_pseudo_bytes(plaintext,
sizeof
plaintext);
RAND_pseudo_bytes(saved_iv,
sizeof
saved_iv);
hexdump(stdout,
"== rkey =="
,
rkey,
sizeof
(rkey));
hexdump(stdout,
"== iv =="
,
saved_iv,
sizeof
(saved_iv));
printf
(
"\n"
);
hexdump(stdout,
"== plaintext =="
,
plaintext,
sizeof
(plaintext));
printf
(
"\n"
);
//Entrypt
memcpy
(iv, saved_iv,
sizeof
(iv));
nr_of_bits = 8 *
sizeof
(rkey);
AES_set_encrypt_key(rkey, nr_of_bits, &key);
nr_of_bytes =
sizeof
(plaintext);
AES_cbc_encrypt(plaintext,
ciphertext,
nr_of_bytes,
&key,
iv,
AES_ENCRYPT);
hexdump(stdout,
"== ciphertext =="
,
ciphertext,
sizeof
(ciphertext));
printf
(
"\n"
);
//Decrypt
memcpy
(iv, saved_iv,
sizeof
(iv));
nr_of_bytes = 8 *
sizeof
(rkey);
AES_set_decrypt_key(rkey, nr_of_bits, &key);
nr_of_bytes =
sizeof
(ciphertext) / 2;
//Decrypt in two step:)
AES_cbc_encrypt(ciphertext,
checktext,
nr_of_bytes,
&key, iv,
AES_DECRYPT);
AES_cbc_encrypt(
ciphertext + nr_of_bytes,
checktext + nr_of_bytes,
nr_of_bytes,
&key,
iv,
AES_DECRYPT);
hexdump(stdout,
"== checktext =="
,
checktext,
sizeof
(checktext));
printf
(
"\n"
);
return
0;
}
|