使用Openssl的AES加密算法

来源:互联网 发布:电视盒子无法安软件 编辑:程序博客网 时间:2024/05/21 18:32

http://blog.gpjtag.com/?p=18

在网络应用的信息安全是基于密码学的,所以如果想做安全方面的邻域需要有一定的密码学基础。当然最好的学习方法就是边看书边尝试。

我的学习过程有三个阶段:

  1. 看书、通过使用一些软件了解基本的流程。
  2. 深入算法,自己实现部分加密算法。
  3. 了解常用的库的用法。

有人说“不要重复造轮子,有现成的要拿来用。”我赞同,但是这个的前提是你造过轮子,知道装配轮子的时候会有什么注意事项:)

所以在学习的过程中一定要“自己造轮子”,在工作的时候一定要“找轮子,用现成的”:)

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
//设置加密密钥,使用字符缓冲区
intAES_set_encrypt_key(
        constunsigned char*userKey,
        constint bits,
        AES_KEY *key);
 
//设置解密密钥,同样适用字符缓冲区
intAES_set_decrypt_key(
        constunsigned char*userKey,
        constint bits,
        AES_KEY *key);
 
//加解密的接口,通过最后的enc来区分是加密还是解密操作
//每次执行AES_cbc_encrypt后,iv(向量)会被更新,
//所以需要自己保存它。
voidAES_cbc_encrypt(
        constunsigned char*in,
        unsignedchar*out,
        constunsigned longlength,
        constAES_KEY *key,
        unsignedchar*ivec,
        constint 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 */
 
staticvoid hexdump(
                FILE*f,
                constchar *title,
                constunsigned char*s,
                intl)
{
    intn = 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");
}
 
intmain(intargc, char**argv)
{
        //256bits key.
        unsignedchar  rkey[16];
        //Internal key.
        AES_KEY         key;
 
        //Testdata.
        unsignedchar  plaintext[AES_BLOCK_SIZE * 4];
        unsignedchar  ciphertext[AES_BLOCK_SIZE * 4];
        unsignedchar  checktext[AES_BLOCK_SIZE * 4];
 
        //Init vector.
        unsignedchar  iv[AES_BLOCK_SIZE * 4];
        //Save vector.
        unsignedchar  saved_iv[AES_BLOCK_SIZE * 4];
 
        intnr_of_bits = 0;
        intnr_of_bytes = 0;
 
        //Zeror buffer.
        memset(plaintext, 0, sizeofplaintext);
        memset(ciphertext, 0, sizeofciphertext);
        memset(checktext, 0, sizeofchecktext);
 
        //Generate random
        RAND_pseudo_bytes(rkey,sizeofrkey);
        RAND_pseudo_bytes(plaintext,sizeofplaintext);
        RAND_pseudo_bytes(saved_iv,sizeofsaved_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");
 
        return0;
}

0 0