OpenSSL之EVP(一)——数据结构及源码结构介绍
来源:互联网 发布:插画软件 编辑:程序博客网 时间:2024/06/05 23:07
EVP简介
Openssl EVP提供了丰富的密码学中的各种函数。
Openssl 中实现了各种对称算法、摘要算法以及签名/验签算法。 EVP 函数将这些具体的算法进行了封装。
EVP 主要封装了如下功能函数:
1)实现了 base64 编解码 BIO;
2)实现了加解密 BIO;
3)实现了摘要 BIO;
4)实现了 reliable BIO;
5)封装了摘要算法;
6)封装了对称加解密算法;
7)封装了非对称密钥的加密(公钥)、解密(私钥)、签名与验证以及辅助函数;
7)基于口令的加密(PBE);
8)对称密钥处理;
9)数字信封:数字信封用对方的公钥加密对称密钥,数据则用此对称密钥加密。发送给对方时,同时发送对称密钥密文和数据密文。接收方首先用自己的私钥解密密钥密文,得到对称密钥,然后用它解密数据。
10)其他辅助函数。
EVP相关数据结构
EVP相关数据结构
声明在文件openssl-1.1.0c\include\opensslossl_typ.h中
EVP相关算法上下文数据结构定义在文件openssl-1.1.0c\crypto\evp\evp_locl.h中。
EVP相关算法数据结构定义在文件openssl-1.1.0c\crypto\include\internal\evp_int.h中。
typedef struct evp_cipher_st EVP_CIPHER;typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;typedef struct evp_md_st EVP_MD;typedef struct evp_md_ctx_st EVP_MD_CTX;typedef struct evp_pkey_st EVP_PKEY;typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;typedef struct evp_pkey_method_st EVP_PKEY_METHOD;typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX;
EVP_CIPHER
EVP_CIPHER用来存放对称加密相关的信息以及算法。
struct evp_cipher_st { int nid; //对称算法 nid int block_size; //对称算法每次加解密的字节数 /* Default value for variable length ciphers */ int key_len; //对称算法的密钥长度字节数 int iv_len; //对称算法的填充长度 /* Various flags */ unsigned long flags; //用于标记 /* init key */ /*加密初始化函数,用来初始化 ctx, key 为对称密钥值, iv 为初始化向量, enc用于指明是要加密还是解密,这些信息存放在 ctx 中*/ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ /*对称运算函数,用于加密或解密*/ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx 清除上下文函数*/ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ /*设置上下文参数函数*/ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ /*获取上下文参数函数*/ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations 控制函数,实现各种其他操作*/ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data 用于存放应用数据*/ void *app_data;} /* EVP_CIPHER */ ;
对称算法上下文结构EVP_CIPHER_CTX ,此结构主要用来维护加解密状态,存放中间以及最后结果。因为加密或解密时,当数据很多时,可能会用到 Update 函数,并且每次加密或解密的输入数据长度任意的,并不一定是对称算法 block_size 的整数倍,所以需要用该结构来存放中间未加密的数据。
struct evp_cipher_ctx_st { const EVP_CIPHER *cipher; ENGINE *engine; /* functional reference if 'cipher' is * ENGINE-provided */ int encrypt; /* encrypt or decrypt */ int buf_len; /* number we have left */ unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ int num; /* used by cfb/ofb/ctr mode */ /* FIXME: Should this even exist? It appears unused */ void *app_data; /* application stuff */ int key_len; /* May change for variable length cipher */ unsigned long flags; /* Various flags */ void *cipher_data; /* per EVP data */ int final_used; int block_mask; unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */} /* EVP_CIPHER_CTX */ ;
openssl 对于各种对称算法实现了上述结构,各个源码位于 cypto/evp 目录下,文件名以 e_开头。 Openssl 通过这些结构来封装了对称算法相关的运算。
EVP_MD
EVP_MD结构用来存放摘要算法信息以及各种计算函数。
struct evp_md_st { int type; //摘要类型,一般是摘要算法 NID int pkey_type; //公钥类型,一般是签名算法 NID int md_size; //摘要值大小,为字节数 unsigned long flags; //用于设置标记 /*摘要算法初始化函数*/ int (*init) (EVP_MD_CTX *ctx); /*多次摘要函数*/ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); /*摘要完结函数*/ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); /*摘要上下文结构复制函数*/ int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); /*清除摘要上下文函数*/ int (*cleanup) (EVP_MD_CTX *ctx); int block_size; int ctx_size; /* how big does the ctx->md_data need to be */ /* control function */ int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);} /* EVP_MD */ ;
struct evp_md_ctx_st { const EVP_MD *digest; /* functional reference if 'digest' is ENGINE-provided */ ENGINE *engine; unsigned long flags; void *md_data; /* Public key context for sign/verify */ EVP_PKEY_CTX *pctx; /* Update function: usually copied from EVP_MD */ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);} /* EVP_MD_CTX */ ;
openssl 对于各种摘要算法实现了上述结构,各个源码位于 cypto/evp 目录下,文件名以 m_开头。 Openssl 通过这些结构来封装了各个摘要相关的运算。
EVP_PKEY
EVP_PKEY用来存放非对称密钥信息,可以是 RSA、 DSA、 DH 或 ECC 密钥。其中, ptr 用来存放密钥结构地址, attributes 堆栈用来存放密钥属性。
/* * Type needs to be a bit field Sub-type needs to be for variations on the * method, as in, can it do arbitrary encryption.... */struct evp_pkey_st { int type; int save_type; int references; const EVP_PKEY_ASN1_METHOD *ameth; ENGINE *engine; union { void *ptr;# ifndef OPENSSL_NO_RSA struct rsa_st *rsa; /* RSA */# endif# ifndef OPENSSL_NO_DSA struct dsa_st *dsa; /* DSA */# endif# ifndef OPENSSL_NO_DH struct dh_st *dh; /* DH */# endif# ifndef OPENSSL_NO_EC struct ec_key_st *ec; /* ECC */# endif } pkey; int save_parameters; STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ CRYPTO_RWLOCK *lock;} /* EVP_PKEY */ ;
EVP源码结构
evp 源码位于 crypto/evp 目录,可以分为如下几类:
1) 全局函数
主要包括 c_allc.c、 c_alld.c 以及 names.c。他们加载 openssl 支持的所有的对称算法和摘要算法,放入到哈希表中。实现了 OpenSSL_add_all_digests、
OpenSSL_add_all_ciphers 以及 OpenSSL_add_all_algorithms(调用了前两个函数)函数。在进行计算时,用户也可以单独加载摘要函数( EVP_add_digest)和对称计算函数( EVP_add_cipher)。
2) BIO 扩充
包括 bio_b64.c、 bio_enc.c、 bio_md.c 和 bio_ok.c,各自实现了 BIO_METHOD方法,分别用于 base64 编解码、对称加解密以及摘要。
3) 摘要算法 EVP 封装
由 digest.c 实现,实现过程中调用了对应摘要算法的回调函数。各个摘要算法提供了自己的 EVP_MD 静态结构,对应源码为 m_xxx.c。
4) 对称算法 EVP 封装
由 evp_enc.c 实现,实现过程调用了具体对称算法函数,实现了 Update 操作。
各种对称算法都提供了一个 EVP_CIPHER 静态结构,对应源码为 e_xxx.c。需要注意的是, e_xxx.c 中不提供完整的加解密运算,它只提供基本的对于一个 block_size数据的计算,完整的计算由 evp_enc.c 来实现。当用户想添加一个自己的对称算法
时,可以参考 e_xxx.c 的实现方式。一般用户至少需要实现如下功能:
- 构造一个新的静态的 EVP_CIPHER 结构;
- 实现 EVP_CIPHER 结构中的 init 函数, 该函数用于设置 iv,设置加解密标记、以及根据外送密钥生成自己的内部密钥;
- 实现 do_cipher 函数,该函数仅对 block_size 字节的数据进行对称运算;
- 实现 cleanup 函数,该函数主要用于清除内存中的密钥信息。
5) 非对称算法 EVP 封装
主要是以 p_开头的文件。其中, p_enc.c 封装了公钥加密; p_dec.c 封装了私钥解密; p_lib.c 实现一些辅助函数; p_sign.c 封装了签名函数; p_verify.c 封装了验签函数; p_seal.c 封装了数字信封; p_open.c 封装了解数字信封。
6) 基于口令的加密
包括 p5_crpt2.c、 p5_crpt.c 和 evp_pbe.c。
- OpenSSL之EVP(一)——数据结构及源码结构介绍
- OpenSSL之EVP(二)——EVP系列函数介绍
- OpenSSL之EVP(三)——EVP对称算法编程示例
- openssl之EVP
- openssl之EVP函数
- openssl之EVP系列之10---EVP_Sign系列函数介绍
- openssl之EVP系列之11---EVP_Verify系列函数介绍
- openssl之EVP系列之12---EVP_Seal系列函数介绍
- openssl之EVP系列之13---EVP_Open系列函数介绍
- openssl之EVP系列之10---EVP_Sign系列函数介绍
- openssl之EVP系列之11---EVP_Verify系列函数介绍
- openssl之EVP系列之12---EVP_Seal系列函数介绍
- openssl之EVP系列之13---EVP_Open系列函数介绍
- openssl之EVP系列之10---EVP_Sign系列函数介绍
- openssl之EVP系列之11---EVP_Verify系列函数介绍
- openssl之EVP系列之12---EVP_Seal系列函数介绍
- openssl之EVP系列之13---EVP_Open系列函数介绍
- openssl之EVP系列之7---信息摘要算法结构概述
- poj3617 Best Cow Line
- C/C++中的日期和时间
- npm下载错误解决办法
- Qt动态分配内存的内存回收规则
- python函数中*args和**kwargs的区别
- OpenSSL之EVP(一)——数据结构及源码结构介绍
- 301、404、200、304等HTTP状态
- 初识Python
- Java ArrayDeque源码剖析
- WinDBG调试dNet程序总结
- poj 2241 && uva 437 The Tower of Babylon(DP)
- 浙大PAT 1020. Tree Traversals (25)
- WorkerMan学习篇:websocket+workerman聊天功能设计(一):简单认证
- Jquery的4种事件绑定