openssl开源加密库

OpenSSL是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。

一、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到这里已经安装好了.

下面我的学习笔记可大概分为以下这几部分:

  1. HASH哈希
  2. 抽象IO  [BIO]
  3. Base64
  4. Md4, md5, SHA1
  5. 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算法

RSA算法的安全性基于数论中大素数分解的困难性,所以,RSA需采用足够大的整数。因子分解越困难,密码就越难以破译,加密强度就越高。其算法如下:
A. 选择两质数p、q
B. 计算n = p * q
C. 计算n的欧拉函数Φ(n) = (p - 1)(q - 1)
D. 选择整数e,使e与Φ(n)互质,且1 < e < Φ(n)
E. 计算d,使d * e = 1 mod Φ(n)
其中,公钥KU={e, n},私钥KR={d, n}。
加密/解密过程:
利用RSA加密,首先需将明文数字化,取长度小于log2n位的数字作为明文块。对于明文块M和密文块C,加/解密的形式如下:
加密: C = Me mod n
解密: M = Cd mod n = (Me)d mod n = Med mod n
RSA的安全性基于大数分解质因子的困难性。因为若n被分解为n = p * q,则Φ(n)、e、d可依次求得。目前,因式分解速度最快的方法的时间复杂性为exp(sqrt(ln(n)lnln(n)))。统计数据表明,在重要应用中,使用512位的密钥已不安全,需要采用1024位的密钥。
posted @ 2020-06-19 01:42  will287248100  阅读(374)  评论(0编辑  收藏  举报