EVP系列函数

EVP系列函数
摘要函数

典型的摘要函数主要有:
1) EVP_md5
返回 md5 的 EVP_MD。
2) EVP_sha1
返回 sha1 的 EVP_MD。
3) EVP_sha256
返回 sha256 的 EVP_MD。
4) EVP_DigestInit
摘要初使化函数,需要有 EVP_MD 作为输入参数。
5) EVP_DigestUpdate 和 EVP_DigestInit_ex
摘要 Update 函数,用于进行多次摘要。
6) EVP_DigestFinal 和 EVP_DigestFinal_ex
摘要 Final 函数,用户得到最终结果。
7) EVP_Digest
对一个数据进行摘要,它依次调用了上述三个函数。
对称加解密函数

典型的加解密函数主要有:
1) EVP_CIPHER_CTX_init
初始化对称计算上下文。
2) EVP_CIPHER_CTX_cleanup
清除对称算法上下文数据, 它调用用户提供的销毁函数销清除内部密钥以及其他数据。
3) EVP_des_ede3_ecb
返回一个 EVP_CIPHER;
4) EVP_EncryptInit 和 EVP_EncryptInit_ex
加密初始化函数,本函数调用具体算法的 init 回调函数,将外送密钥 key 转换为内部密钥形式,将初始化向量 iv 拷贝到 ctx 结构中。
5) EVP_EncryptUpdate
加密函数,用于多次计算,它调用了具体算法的 do_cipher 回调函数。
6) EVP_EncryptFinal 和 EVP_EncryptFinal_ex
获取加密结果,函数可能涉及填充,它调用了具体算法的do_cipher 回调函数。
7) EVP_DecryptInit 和 EVP_DecryptInit_ex
解密初始化函数。
8) EVP_DecryptUpdate
解密函数,用于多次计算,它调用了具体算法的 do_cipher 回调函数。
9) EVP_DecryptFinal 和 EVP_DecryptFinal_ex
获取解密结果,函数可能涉及去填充,它调用了具体算法的do_cipher 回调函数。
10) EVP_BytesToKey
计算密钥函数,它根据算法类型、摘要算法、 salt 以及输入数据计算出一个对称密钥和初始化向量 iv。
11) PKCS5_PBE_keyivgen 和 PKCS5_v2_PBE_keyivgen
实现了 PKCS5 基于口令生成密钥和初始化向量的算法。
12) PKCS5_PBE_add
加载所有 openssl 实现的基于口令生成密钥的算法。
13) EVP_PBE_alg_add
添加一个 PBE 算法。
对称加密过程

对称加密过程如下:
1) EVP_EncryptInit:

设置 buf_len 为 0,表明临时缓冲区 buf 没有数据。
2) EVP_EncryptUpdate:

ctx 结构中的 buf 缓冲区用于存放上次 EVP_EncryptUpdate 遗留下来的未加密的数据, buf_len 指明其长度。如果 buf_len 为 0,加密的时候先加密输入数据的整数倍,将余下的数据拷贝到 buf 缓冲区。如果 buf_len 不为 0,先加密 buf 里面的数据和输入数据的一部分(凑足一个分组的长度),然后用上面的方法加密,输出结
果是加过密的数据。
3) EVP_ EncryptFinal

加密 ctx 的 buf 中余下的数据,如果长度不够一个分组(分组长度不为 1),则填充,然后再加密,输出结果。
总之,加密大块数据(比如一个大的文件,多出调用 EVP_EncryptUpdate)的结果等效于将所有的数据一次性读入内存进行加密的结果。加密和解密时每次计算的数据块的大
小不影响其运算结果。
非对称函数

典型的非对称函数有:
1) EVP_PKEY_encrypt
公钥加密。
2) EVP_PKEY_decrypt
私钥解密。
3) EVP_PKEY_assign
设置 EVP_PKEY 中具体的密钥结构,使它代表该密钥。
4) EVP_PKEY_assign_RSA/ EVP_PKEY_set1_RSA
设置 EVP_PKEY 中的 RSA 密钥结构,使它代表该 RSA 密钥。
5) EVP_PKEY_get1_RSA
获取 EVP_PKEY 的 RSA 密钥结构。
6) EVP_SignFinal
签名操作,输入参数必须有私钥(EVP_PKEY)。
7) EVP_VerifyFinal
验证签名,输入参数必须有公钥(EVP_PKEY)。
8) int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,const unsigned
char *ek, int ekl, const unsigned char *iv,EVP_PKEY *priv)
解数字信封初始化操作,type为对称加密算法,ek为密钥密文,ekl为密
钥密文长度,iv为填充值,priv为用户私钥。
9) EVP_OpenUpdate
做解密运算。
10) EVP_OpenFinal
做解密运算,解开数字信封。
11) int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
type为对称算法,ek数组用来存放多个公钥对密钥加密的结果,ekl用于存放ek数组中每个密钥密文的长度,iv为填充值,pubk数组用来存放多个公钥,npubk为公钥个数,本函数用多个公钥分别加密密钥,并做加密初始化。
12)EVP_SealUpdate
做加密运算。
13)EVP_SealFinal
做加密运算,制作数字信封。
BASE64 编解码函数

1) EVP_EncodeInit
BASE64 编码初始化。
2) EVP_EncodeUpdate
BASE64 编码,可多次调用。
3) EVP_EncodeFinal
BASE64 编码,并获取最终结果。
4) EVP_DecodeInit
BASE64 解码初始化。
5) EVP_DecodeUpdate
输入数据长度不能大于 80 字节。 BASE64 解码可多次调用,注意,本函数的输入数据不能太长。
6) EVP_DecodeFinal
BASE64 解码,并获取最终结果。
7) EVP_EncodeBlock
BASE64 编码函数,本函数可单独调用。
8) EVP_DecodeBlock
BASE64 解码,本函数可单独调用,对输入数据长度无要求。
其他函数

1) EVP_add_cipher
将对称算法加入到全局变量,以供调用。
2) EVP_add_digest
将摘要算法加入到全局变量中,以供调用
3) EVP_CIPHER_CTX_ctrl
对称算法控制函数,它调用了用户实现的 ctrl 回调函数。
4) EVP_CIPHER_CTX_set_key_length
当对称算法密钥长度为可变长时,设置对称算法的密钥长度。
5) EVP_CIPHER_CTX_set_padding
设置对称算法的填充,对称算法有时候会涉及填充。加密分组长度大于一时,用户输入数据不是加密分组的整数倍时,会涉及到填充。填充在最后一个分组来完成, openssl 分组填充时,如果有 n 个填充,则将最后一个分组用 n 来填满。
6) EVP_CIPHER_get_asn1_iv
获取原始 iv,存放在 ASN1_TYPE 结构中。
7) EVP_CIPHER_param_to_asn1
设置对称算法参数,参数存放在 ASN1_TYPE 类型中,它调用用户实现的回调函数 set_asn1_parameters 来实现。
8) EVP_CIPHER_type
获取对称算法的类型。
9) EVP_CipherInit/EVP_CipherInit_ex
对称算法计算(加/解密)初始化函数, _ex 函数多了硬件 enginge 参数,EVP_EncryptInit 和 EVP_DecryptInit 函数也调用本函数。
10) EVP_CipherUpdate
对称计算 (加/解密)函数, 它调用了 EVP_EncryptUpdate 和 EVP_DecryptUpdate函数。
11) EVP_CipherFinal/EVP_CipherFinal_ex
对 称 计 算 ( 加 / 解 ) 函 数 , 调 用 了 EVP_EncryptFinal (_ex ) 和EVP_DecryptFinal(_ex);本函数主要用来处理最后加密分组,可能会有对称计算。
12) EVP_cleanup
清除加载的各种算法,包括对称算法、摘要算法以及 PBE 算法,并清除这些算法相关的哈希表的内容。
13) EVP_get_cipherbyname
根据字串名字来获取一种对称算法(EVP_CIPHER),本函数查询对称算法哈希表。
14) EVP_get_digestbyname
根据字串获取摘要算法(EVP_MD),本函数查询摘要算法哈希表。
15) EVP_get_pw_prompt
获取口令提示信息字符串.
16) int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
PBE 初始化函数。本函数用口令生成对称算法的密钥和初始化向量,并作加/解密初始化操作。本函数再加上后续的 EVP_CipherUpdate 以及 EVP_CipherFinal_ex
构成一个完整的加密过程(可参考 crypto/p12_decr.c 的 PKCS12_pbe_crypt 函数) .
17) EVP_PBE_cleanup
删除所有的 PBE 信息,释放全局堆栈中的信息.
18) EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
将 PKCS8_PRIV_KEY_INFO(x509.h 中定义)中保存的私钥转换为 EVP_PKEY结构。
19) EVP_PKEY2PKCS8/EVP_PKEY2PKCS8_broken
将 EVP_PKEY 结构中的私钥转换为 PKCS8_PRIV_KEY_INFO 数据结构存储。
20) EVP_PKEY_bits
非对称密钥大小,为比特数。
21) EVP_PKEY_cmp_parameters
比较非对称密钥的密钥参数,用于 DSA 和 ECC 密钥。
22) EVP_PKEY_copy_parameters
拷贝非对称密钥的密钥参数,用于 DSA 和 ECC 密钥。
23) EVP_PKEY_free
释放非对称密钥数据结构。
24) EVP_PKEY_get1_DH/EVP_PKEY_set1_DH
获取/设置 EVP_PKEY 中的 DH 密钥。
25) EVP_PKEY_get1_DSA/EVP_PKEY_set1_DSA
获取/设置 EVP_PKEY 中的 DSA 密钥。
26) EVP_PKEY_get1_RSA/EVP_PKEY_set1_RSA
获取/设置 EVP_PKEY 中结构中的 RSA 结构密钥。
27) EVP_PKEY_missing_parameters
检查非对称密钥参数是否齐全,用于 DSA 和 ECC 密钥。
28) EVP_PKEY_new
生成一个 EVP_PKEY 结构。
29) EVP_PKEY_size
获取非对称密钥的字节大小。
30) EVP_PKEY_type
获取 EVP_PKEY 中表示的非对称密钥的类型。
31) int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify)
获取用户输入的口令;buf 用来存放用户输入的口令,length 为 buf 长度,prompt为提示给用户的信息,如果为空,它采用内置的提示信息, verify 为 0 时,不要求验证用户输入的口令,否则回要求用户输入两遍。返回 0 表示成功。
32) EVP_set_pw_prompt
设置内置的提示信息,用于需要用户输入口令的场合。
————————————————
版权声明:本文为CSDN博主「scuyxi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/scuyxi/article/details/60621075

在OpenSSL库中,`EVP_PKEY*`表示一种加密密钥结构,通常用于公钥和私钥操作。为了将这种类型的私钥转换成 `unsigned char *`(即字节数组),需要通过一系列步骤来进行解密和数据提取。 以下是具体的步骤: ### 步骤 1: 加载私钥 首先,你需要加载私钥到 OpenSSL 的上下文环境中。这通常涉及到创建一个 `EVP_PKEY_CTX` 结构,并设置一些参数。例如,如果你有一个DER编码的私钥文件,你可以使用 `PEM_read_bio_PrivateKey` 函数将其读入。 ```c EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); int ret = PEM_read_bio_RSAPrivateKey(bio, &key, password_callback, (void*)this); ``` 这里的 `bio` 应该是一个包含私钥数据的 BIO 对象。 ### 步骤 2: 配置解密 接下来,配置解密过程。这包括指定使用何种算法(如RSA)、提供密钥和是否启用密码保护等。 ```c if (!EVP_PKEY_keygen_init(ctx)) { // 错误处理... } // 设置RSA算法并填充密钥 if (!EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) || !EVP_PKEY_CTX_set_rsa_private_key(ctx, key)) { // 错误处理... } if (!EVP_PKEY_derive_init(ctx)) { // 错误处理... } ``` ### 步骤 3: 解密密钥 现在可以开始实际的解密过程了。 ```c unsigned char *private_key_data; size_t private_key_len; if (!EVP_PKEY_derive(ctx, &private_key_data, &private_key_len)) { // 错误处理... } // private_key_data 现在包含了私钥的数据作为字节数组, // 私钥长度由 private_key_len 给出。 ``` ### 步骤 4: 清理资源 最后,记得清理之前分配的资源。 ```c free(private_key_data); // 如果你不打算保留私钥数据 EVP_PKEY_free(key); EVP_PKEY_CTX_cleanup(ctx); EVP_PKEY_CTX_free(ctx); ``` ### 相关问题: 1. **如何验证解密后的私钥数据的有效性?** 验证私钥数据的有效性通常是通过尝试使用它来解密已知的密文或生成数字签名的方式来进行。 2. **如果忘记密码,如何从私钥中恢复原始数据?** 如果忘记了密码,通常无法直接从私钥中恢复原始数据,除非密码被保存在某个安全的地方或者有备份。对于密码保护的私钥,只能重新导入原始密码。 3. **在哪些场景下不需要关心私钥转换的问题?** 当不需要对私钥进行额外处理、只是需要它作为某种形式的标识符或存档时,可能就不需要关心私钥的具体内容转换成字节流的操作。例如,在某些证书管理或只读访问私钥的情况下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值