《信息安全系统设计与实现下》-OpenSSL下载与VS2019,CodeBlocks配置
目录
1 OpenSSL下载与配置
1.1.OpenSSL下载与VS2019配置
参考https://blog.csdn.net/X_To_Y/article/details/110410901(我认为步骤是最全的一个而且可用)
1.2.CodeBlocks配置openssl
-
加静态库
(先激活项目)菜单栏->Project->Build Options->Debug->Linker settings->Add 自己openssl安装目录下/lib下所有.lib文件(选择时使用Ctrl+A)
-
加动态库
菜单栏->Project->Build Options->Debug->Search directories->Linker->Add 动态库的目录(参考前面安装时的选项,设置后为/bin下)
-
加头文件
菜单栏->Project->Build Options->Debug->Search directories->Compiler->Add 安装目录/include
2 代码编译运行
2.1Base64编解码
代码同老师博客
运行截图:
2.2 sm3摘要
修改原来tDigest(),原来使用的是md5
unsigned char md_value[EVP_MAX_MD_SIZE]; //保存输出的摘要值的数组
unsigned int md_len, i;
EVP_MD_CTX* sm3_ctx; //EVP消息摘要结构体
sm3_ctx = EVP_MD_CTX_new();
char msg1[] = "Test Message1"; //待计算摘要的消息1
char msg2[] = "Test Message2"; //待计算摘要的消息2
EVP_MD_CTX_init(sm3_ctx); //初始化摘要结构体
EVP_DigestInit_ex(sm3_ctx, EVP_sm3(), NULL); //设置摘要算法和密码算法引擎,这里密码算法使用sm3,算法引擎使用OpenSSL默认引擎即软算法
EVP_DigestUpdate(sm3_ctx, msg1, strlen(msg1));//调用摘要UpDate计算msg1的摘要
EVP_DigestUpdate(sm3_ctx, msg2, strlen(msg2));//调用摘要UpDate计算msg2的摘要
EVP_DigestFinal_ex(sm3_ctx, md_value, &md_len);//摘要结束,输出摘要值
EVP_MD_CTX_reset(sm3_ctx); //释放内存
printf("原始数据%s和%s的摘要16进制值为:\n", msg1, msg2);
for (i = 0; i < md_len; i++)
{
printf("0x%02x ", md_value[i]);
}
printf("\n");
运行截图
2.3 sm4加解密
修改原来的tEVP_Encrypt()(使用的是des_ebe3_cbc),添加了解密部分,使用sm4
unsigned char key[EVP_MAX_KEY_LENGTH]; //密钥
unsigned char iv[EVP_MAX_KEY_LENGTH];//初始化向量
EVP_CIPHER_CTX* en_ctx;//EVP算法上下文
en_ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX* de_ctx;
de_ctx = EVP_CIPHER_CTX_new();
unsigned char out[1024], de_out[1024];//输出密文缓冲区
int outl, de_outlen;//密文长度
int outltmp, de_outlent;
const char* msg = "Hello OpenSSL";//待加密的数据
int rv, de_rv;
int i;
//设置key和iv(可以采用随机数和可以是用户输入)
for (i = 0; i < 24; i++)
{
key[i] = i;
}
for (i = 0; i < 8; i++)
{
iv[i] = i;
}
//初始化密码算法结构体
EVP_CIPHER_CTX_init(en_ctx);
//设置算法和密钥以
rv = EVP_EncryptInit_ex(en_ctx, EVP_sm4_cbc(), NULL, key, iv);
if (rv != 1)
{
printf("Err\n");
return;
}
//数据加密
rv = EVP_EncryptUpdate(en_ctx, out, &outl, (const unsigned char*)msg, strlen(msg));
if (rv != 1)
{
printf("Err\n");
return;
}
//结束数据加密,把剩余数据输出。
rv = EVP_EncryptFinal_ex(en_ctx, out + outl, &outltmp);
if (rv != 1)
{
printf("Err\n");
return;
}
outl = outl + outltmp;
printf("原文为:%s\n", msg);
//打印输出密文
printf("密文长度:%d\n密文16进制数据:\n", outl);
for (i = 0; i < outl; i++)
{
printf("0x%02x ", out[i]);
}
printf("\n");
de_ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(en_ctx);
de_rv = EVP_DecryptInit_ex(de_ctx, EVP_sm4_cbc(), NULL, key, iv);
if (de_rv != 1) {
printf("Err\n");
return;
}
de_rv = EVP_DecryptUpdate(de_ctx, de_out, &de_outlen, (const unsigned char*)out, outl);
if (rv != 1) {
printf("Err\n");
return;
}
rv = EVP_DecryptFinal_ex(de_ctx, de_out + de_outlen, &de_outlent);
if (rv != 1) {
printf("Err\n");
return;
}
de_outlen += de_outlent;
printf("密文是:");
for (i = 0; i < outl; i++)
{
printf("%c", out[i]);
}
printf("结束添加汉字\n");
printf("解密信息长度:%d\n解密信息数据:\n", outl);
for (i = 0; i < de_outlen; i++)
{
printf("%c", de_out[i]);
}
运行截图