目錄
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]);
}
運行截圖






