OPENSSL加密与解密
加密与解密
单向散列
MD5
SHA1、SHA2、SHA3
OPENSSL EVP接口:
封装了加密、摘要、编码三大类型的算法。且可替换
EVP_DigestInit_Ex(ctx, evp_md, NULL) -> EVP_DigestUpdate(ctx, data, data_size) -> EVP_DigestFinal_ex(ctx, out, &out_size)
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
参数说明:
ctx: EVP_MD_CTX类型指针,表示消息摘要上下文结构体
type: 指定要使用的摘要算法类型,如EVP_sha1()、EVP_sha256()等
impl: ENGINE类型指针,用于指定硬件引擎实现,通常设为NULL使用默认软件实现
主要功能:
初始化摘要上下文,为后续计算消息摘要做准备
可以选择不同的摘要算法(MD5、SHA1、SHA256等)
支持硬件加速实现
使用示例:
#include <openssl/evp.h>
EVP_MD_CTX *mdctx;
const EVP_MD *md;
// 创建上下文
mdctx = EVP_MD_CTX_new();
// 选择SHA-256算法并初始化
md = EVP_sha256();
EVP_DigestInit_ex(mdctx, md, NULL);
// 后续操作...
// EVP_DigestUpdate()
// EVP_DigestFinal_ex()
// 清理
EVP_MD_CTX_free(mdctx);
注意事项:
使用前需要创建EVP_MD_CTX上下文
函数返回1表示成功,0表示失败
初始化后可以重复使用Update函数添加数据
使用完需要正确释放上下文资源
SM3
- EVP_MD 摘要算法 :
EVP_MD_CTX_new():ctx上下文初始化
EVP_sm3()
- EVP简化接口
EVP_Digest(data, data_size, out, &out_size, EVP_sm3(), NULL)
特点:
一步完成所有操作,适合一次性处理小数据
代码简洁,使用方便
内部自动处理上下文的创建和释放
不适合处理大数据或流式数据
HMAC消息认证码
- 哈希运算消息认证码(Hash-based Message Authentication Code)
- 与秘钥相关的单项散列函数
- 确认消息是否被正确传输了,具体包括:消息完整性、消息认证
- 应用在SSL协议中
- 步骤:
HMAC(EVP_sha256(), //选用的hash算法
key, strlen(key), //共享秘钥
data, data_size, //MSG
mac, &mac_size //mac消息认证码)
对称加密,共享秘钥
-
使用相同的秘钥进行加密和解密
-
安全高效,性能高
-
安全问题:秘钥管理、前置泄露(秘钥丢失后会导致之前的内容被破解,可使用随机秘钥规避)、网络通信要配合非对称加密
-
分组密码模式:明文长度超过密码长度,需要迭代加密,称之为分组密码模式。例如AES 128比特(大部分情况下适用),DES 64比特(安全强度过低),国内更推荐适用国密SM4,用来替代AES
-
ECB模式:Electronic CodeBook 电子密码本模式
-
CBC模式:Cipher Block Chaining 密文分组链接模式
使用异或实现一个简易的对称算法
- 借助了异或的特性:A XOR B XOR B 等于 A (可以把A理解成明文,B理解成密文,第一次异或理解成加密,第二次异或理解成解密)
- 数据补全策略: PADDING_PKCS7 PADDING_ZERO 例如:
block = 8
12345678 9
补全后:
12345678 90000000 PADDING_ZERO
12345678 97777777 PADDING_PKCS7,另外要注意如果数据刚好是block_size,此时后面要补block_size个0