OpenSSL/GMSSL EVP接口说明——1.7 加密解密示例代码

该代码展示了使用OpenSSL库中的EVP接口进行SM4加密和解密的示例,包括ECB和CBC模式。测试用例包含了不同长度的明文和密文,以及对应的密钥和初始化向量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.7 加密解密示例代码

#include <string.h>

#include "openssl/evp.h" 

typedef struct sm4_test_vector_st

{

        int enc_time;//反复加密次数

        int pt_ct_len;

        const EVP_CIPHER *mode;

        unsigned char key[16];//16 bytes

        unsigned char iv[16]; //16 bytes

        unsigned char pt[32]; 

        unsigned char ct[32]; 

}sm4_test_vector;

int test_sm4()

{

        EVP_CIPHER_CTX ctx;

        const EVP_CIPHER *cipher = NULL;

        unsigned char ct[256]={0}, pt[256]={0};

        unsigned char *p_in = NULL, *p_in_cst = NULL, *p_out = NULL, *p_out_calc = NULL;

        int b_enc;

        int ret, i,j, k, inlen,outlen,ctlen, totallen=0, operate_len;

        sm4_test_vector vct[]={

                 {/*测试向量*/

                         /*次数*/  1,     /*长度*/  16,   /*mode*/ EVP_sm4_ecb(),

                         /*密钥*/    { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},

                         /* IV */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},

                         /*明文*/    { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},

                         /*密文*/    { 0x68,0x1e,0xdf,0x34,0xd2,0x06,0x96,0x5e,0x86,0xb3,0xe9,0x4f,0x53,0x6e,0x42,0x46},

                 },

                 {/*测试向量*/

                         /*次数*/  1,     /*长度*/  32,   /*mode*/ EVP_sm4_cbc(),

                         /*密钥*/ { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},

                         /* IV */ { 0XEB,0XEE,0XC5,0X68,0X58,0XE6,0X04,0XD8,0X32,0X7B,0X9B,0X3C,0X10,0XC9,0X0C,0XA7},

                         /*明文*/    { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10,

                         /*    */      0X29,0XBE,0XE1,0XD6,0X52,0X49,0XF1,0XE9,0XB3,0XDB,0X87,0X3E,0X24,0X0D,0X06,0X47 },

                         /*密文*/    { 0X3F,0X1E,0X73,0XC3,0XDF,0XD5,0XA1,0X32,0X88,0X2F,0XE6,0X9D,0X99,0X6C,0XDE,0X93,

                         /*    */      0X54,0X99,0X09,0X5D,0XDE,0X68,0X99,0X5B,0X4D,0X70,0XF2,0X30,0X9F,0X2E,0XF1,0XB7},

                 }

        };

printf("\n************************************************************\n");

        printf("开始测试SM4算法\n\n");

        cipher = EVP_sm4_ecb();

        EVP_CIPHER_CTX_init(&ctx); 

        for (i = 0;i<sizeof(vct)/sizeof(vct[0]);i++)

        {

                 printf("---------------------------------------------\n" );

                 for (k = 0;k<2;k++)//k==0 是加密,否则是解密

                 {

                         printf(".............................\n" );

                         b_enc = (k==0);     

                         p_out = p_out_calc = b_enc ? ct : pt;

                         p_in  = p_in_cst = b_enc ? vct[i].pt : ct;

                         operate_len = b_enc ? vct[i].pt_ct_len : ctlen;

                         inlen = operate_len;//1; //16

                         ret = b_enc ?

                                          EVP_EncryptInit_ex(&ctx, vct[i].mode, NULL, vct[i].key, vct[i].iv)

                                  :       EVP_DecryptInit_ex(&ctx, vct[i].mode, NULL, vct[i].key, vct[i].iv);       

                         for(j=0;j < operate_len; j += inlen)

                         {

                                  ret = b_enc ?

                                                  EVP_EncryptUpdate(&ctx,p_out,&outlen,p_in,inlen)

                                          :        EVP_DecryptUpdate(&ctx,p_out,&outlen,p_in,inlen);

                                  p_in  += inlen;

                                  p_out += outlen; 

                         }

                         ret = b_enc ?

                                          EVP_EncryptFinal_ex(&ctx,p_out,&outlen)

                                  :       EVP_DecryptFinal_ex(&ctx,p_out,&outlen);

                         p_out += outlen;

                         ctlen  = totallen = p_out - p_out_calc;

                         ret = EVP_CIPHER_CTX_cleanup(&ctx); 

                         ret = ( memcmp( b_enc?vct[i].ct:vct[i].pt, p_out_calc, vct[i].pt_ct_len ) == 0 );

                         printf("结果正确:%s\n", (ret==1) ? "yes":"no");

                         if(ret!=1)

                         {

                                  printf("%s结果长度:%d\n",b_enc? "加密":"解密", totallen);

                                  print_dbg_data( p_in_cst, operate_len, "input" ); 

                                  print_dbg_data( b_enc?vct[i].ct:vct[i].pt, vct[i].pt_ct_len, "right output" );

                                  print_dbg_data( p_out_calc, totallen, "calc  output" );  

                         }

                 } 

        }

        printf("SM4算法测试完毕\n\n");

        return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值