openssl开源加密库
一、openssl开源加密库的安装,我的环境是ubuntu16.0.4版本
源码下载路径:https://www.OpenSSL.org/source/
可执行命令:
wget https://www.openssl.org/source/old/1.0.0/openssl-1.0.0s.tar.gz
tar xzvf openssl-1.0.0s
cd openssl-1.0.0s
./config --prefix=/usr/local/include/openssl
make //make -j
sudo make install
1.cp 安装后生成的include目录下的头文件拷贝到/usr/local/include/openssl/路径下;
2.执行命令:
cp libcrypto.a libssl.a /usr/local/lib/
将libcrypto.a libssl.a 这两个库文件拷贝到/usr/local/lib/路径下
Openssl到这里已经安装好了.
下面我的学习笔记可大概分为以下这几部分:
- HASH哈希
- 抽象IO [BIO]
- Base64
- Md4, md5, SHA1
- RSA非对称加密
二、BIO抽象io
对于BIO对内存的操作附上以下代码:
1 BIO * bio = BIO_new(BIO_s_name());
2 int len = BIO_write(bio, /*类似于一个fd*/
3 "Openssl", /*写入的一块buffer*/
4 4);/*写入长度*/
5
6 len = BIO_printf(bio, "%s", "will");/*类似fprintf()这个函数*/
7
8 char * out = OPENSSL_malloc(len);/*申请空间*/
9 len = BIO_read(bio, out, len);/*将bio的内容读到outbuffer这块缓存中,返回一个length*/
10
11 printf("len: %d, %s\n", len, out);
12
13 OPENSSL_free(out);/*对申请的内存进行释放*/
14 BIO_free(b);
申请内存的源码:
# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__)
BIO_METHOD中所封装的以下方法
static BIO_METHOD methods_md = {
BIO_TYPE_MD, "message digest",
md_write,
md_read,
NULL, /* md_puts, */
md_gets,
md_ctrl,
md_new,
md_free,
md_callback_ctrl,
};
三、Hash表
hash表(crypto/lhash目录),实现了散列表数据结构。OpenSSL中很多数据结构都是以散列表来存放的。比如配置信息、ssl session和asn.1对象信息等。在记录的存储位置和它的关键字之间建立确定的对应关系,使每个关键字和结构中一个唯一的存储位置相对应。在查找时,只需根据这个对应关系找到给定值。这种对应关系既是哈希函数,按这个思想建立的表为哈希表。
Hash 操作接口举例:
lh_new(NULL, student_cmp);//创建一个hash,传入参数是两个回调函数[回调计算hash key,回调计算compare];在这里回调student_cmp
lh_insert(h,s1);//插入值;
lh_doall(h, printf_student);//遍历打印所有的值
void * data = lh_retrieve(h, (const char *)"will");//查找字段”will”,返回值到data,
print_student(data);//回调函数打印返回的数据;
lh_free(h);//销毁hash
编译包含头文件:
#include <stdio.h>
#include <string.h>
#include <openssl/lhash.h>
编译命令:gcc -o hash openssl_hash.c -lssl -lcrypto
这里附上openssl hash表部分源码:
创建一个hash表时看源码是做了这些事情:
1 _LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
2 {
3 _LHASH *ret;
4 int i;
5
6 if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL)
7 goto err0;
8 if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL)
9 goto err1;
10 for (i = 0; i < MIN_NODES; i++)
11 ret->b[i] = NULL;
12 ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c);
13 ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h);
14 ret->num_nodes = MIN_NODES / 2;
15 ret->num_alloc_nodes = MIN_NODES;
16 ret->p = 0;
17 ret->pmax = MIN_NODES / 2;
18 ret->up_load = UP_LOAD;
19 ret->down_load = DOWN_LOAD;
20 ret->num_items = 0;
21
22 ret->num_expands = 0;
23 ret->num_expand_reallocs = 0;
24 ret->num_contracts = 0;
25 ret->num_contract_reallocs = 0;
26 ret->num_hash_calls = 0;
27 ret->num_comp_calls = 0;
28 ret->num_insert = 0;
29 ret->num_replace = 0;
30 ret->num_delete = 0;
31 ret->num_no_delete = 0;
32 ret->num_retrieve = 0;
33 ret->num_retrieve_miss = 0;
34 ret->num_hash_comps = 0;
35
36 ret->error = 0;
37 return (ret);
38 err1:
39 OPENSSL_free(ret);
40 err0:
41 return (NULL);
42 }
lh_new中_LHASH结构体是这样定义的:
1 typedef struct lhash_st {
2 LHASH_NODE **b;
3 LHASH_COMP_FN_TYPE comp;
4 LHASH_HASH_FN_TYPE hash;
5 unsigned int num_nodes;
6 unsigned int num_alloc_nodes;
7 unsigned int p;
8 unsigned int pmax;
9 unsigned long up_load; /* load times 256 */
10 unsigned long down_load; /* load times 256 */
11 unsigned long num_items;
12 unsigned long num_expands;
13 unsigned long num_expand_reallocs;
14 unsigned long num_contracts;
15 unsigned long num_contract_reallocs;
16 unsigned long num_hash_calls;
17 unsigned long num_comp_calls;
18 unsigned long num_insert;
19 unsigned long num_replace;
20 unsigned long num_delete;
21 unsigned long num_no_delete;
22 unsigned long num_retrieve;
23 unsigned long num_retrieve_miss;
24 unsigned long num_hash_comps;
25 int error;
26 } _LHASH; /* Do not use _LHASH directly, use LHASH_OF
四、Base64: 常用的16#数据转可见字符的编码,与ASCII码相比,它占用的空间较小。常应用于图片编码;
编码原理:将数据编码成BASE64编码时,以3字节数据为一组,转换为24bit的二进制数,将24bit的二进制数分成四组,每组6bit。对于每一组,得到一个数字:0-63。然后根据这个数字查表即得到结果。
特点:上下文用来存储中间转换产生的临时数据;Base64编码过程是线程不安全的;可逆的;
五、MD5摘要算法,也称签名算法、指纹算法
MD5是不可逆的,一般用于大文件的校验。
六、非对称加密,RSA算法