当前位置: 首页 > 工具软件 > mbedTLS > 使用案例 >

mbedtls加密组件使用示例

漆雕正奇
2023-12-01

1 mbedtls aes组件的使用

1.1 AES ECB加解密接口使用

int main(int argc, char *argv[])
{
	char key[256];
	char *inbuf = calloc(1, 257);
	char *outbuf = calloc(1, 257);
	char *buf = calloc(1,257);
	char *tmp_outbuf = outbuf;
	char *tmp_buf = buf;
	mbedtls_aes_context aes_ctx;
	mbedtls_aes_init(&aes_ctx);
	for (int i = 0; i < 256;i++){
		inbuf[i] = '0' + i % 16;

	}
	printf("\n inbuf = %s\n",inbuf);
	memset(key, 0x55, 256);
	mbedtls_aes_setkey_enc(&aes_ctx, key, 128);//设置解密key,128bit
	for (int i = 0; i < 16;i++){
		mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, inbuf, tmp_outbuf);
		inbuf += 16;
		tmp_outbuf += 16;
	}
	mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
	tmp_outbuf = outbuf;
	for (int i = 0; i < 16; i++){
		mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, tmp_outbuf, tmp_buf);
		tmp_outbuf += 16;
		tmp_buf += 16;
	}
	mbedtls_aes_free(&aes_ctx);
	printf("\n buf = %s\n",buf);
	getchar();
}

1.2 AEC CBC加解密接口使用

	int olen;					//编码后长度
	char encrypt_buf[512] = { 0 };//用于加密后存放字符串
	int encrypt_len;			//加密后长度
	char buf[512] = "abcdefg42t432876482364623874623846283ywadasdhiatdawdagdawidqhawiyweheyuw9r";	//初始化字符串
	char secretKey[128] = {1,2,3};
	int len = (strlen(buf) / 16 ) * 16;
	

	mbedtls_aes_context ctx;
	mbedtls_aes_init(&ctx);		//初始化结构体
	mbedtls_aes_setkey_enc(&ctx, secretKey, 128);	//密码(密钥)

	char iv[16] = { 0 };

	mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, len, iv, buf, encrypt_buf);	//第三个参数为文档中的偏移量

	memset(buf,0,sizeof(buf));
	memset(iv,0,sizeof(iv));
	mbedtls_aes_setkey_dec(&ctx, secretKey, 128);
	mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, len, iv, encrypt_buf, buf);	//第三个参数为文档中的偏移量

	
	printf("\nbuf = %s\n",buf);


	mbedtls_aes_free(&ctx);

1.3 AES 使用CFB加解密接口使用

int main(int argc, char *argv[])
{
	int olen;					//编码后长度
	char encrypt_buf[512] = { 0 };//用于加密后存放字符串
	int encrypt_len;			//加密后长度
	char buf[512] = "234abcdefg42t432876482364623874623846283ywadasdhiatdawdagdawidqhawiyweheyuwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwfvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv9r";	//初始化字符串
	char secretKey[128] = {1,2,3};
	int len = 129;
	printf("\n len = %d\n",len);

	mbedtls_aes_context ctx;
	mbedtls_aes_init(&ctx);		//初始化结构体
	mbedtls_aes_setkey_enc(&ctx, secretKey, 128);	//密码(密钥)

	char iv[16] = { 0 };
	size_t iv_off = 1;
	int ret = mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_ENCRYPT, len, &iv_off,iv, buf, encrypt_buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n",ret);
	memset(buf,0,sizeof(buf));
	memset(iv,0,sizeof(iv));
	printf("\n iv_off = %d\n",iv_off);
	iv_off = 1;
	//mbedtls_aes_setkey_dec(&ctx, secretKey, 128);
	mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_DECRYPT, len, &iv_off,iv, encrypt_buf, buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n", ret);
	
	printf("\nbuf = %s\n",buf);


	mbedtls_aes_free(&ctx);

	getchar();
}

1.4 AES 使用OFB加解密接口使用

int main(int argc, char *argv[])
{
	int olen;					//编码后长度
	char encrypt_buf[512] = { 0 };//用于加密后存放字符串
	int encrypt_len;			//加密后长度
	char buf[512] = "234abcdefg42t432876482364623874623846283ywadasdhiatdawdagdawidqhawiyweheyuwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwfvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv9r";	//初始化字符串
	char secretKey[128] = {1,2,3};
	int len = 129;
	printf("\n len = %d\n",len);

	mbedtls_aes_context ctx;
	mbedtls_aes_init(&ctx);		//初始化结构体
	mbedtls_aes_setkey_enc(&ctx, secretKey, 128);	//密码(密钥)

	char iv[16] = { 0 };
	size_t iv_off = 1;
	int ret = mbedtls_aes_crypt_ofb(&ctx, len, &iv_off,iv, buf, encrypt_buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n",ret);
	memset(buf,0,sizeof(buf));
	memset(iv,0,sizeof(iv));
	printf("\n iv_off = %d\n",iv_off);
	iv_off = 1;
	//mbedtls_aes_setkey_dec(&ctx, secretKey, 128);
	mbedtls_aes_crypt_ofb(&ctx,  len, &iv_off,iv, encrypt_buf, buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n", ret);
	
	printf("\nbuf = %s\n",buf);


	mbedtls_aes_free(&ctx);
	getchar();
}

1.5 AES 使用CTR加解密接口使用

int main(int argc, char *argv[])
{
	int olen;					//编码后长度
	char encrypt_buf[512] = { 0 };//用于加密后存放字符串
	int encrypt_len;			//加密后长度
	char buf[512] = "234abcdefg42t432876482364623874623846283ywadasdhiatdawdagdawidqhawiyweheyuwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwfvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv9r";	//初始化字符串
	char secretKey[128] = {1,2,3};
	int len = 129;
	printf("\n len = %d\n",len);

	mbedtls_aes_context ctx;
	mbedtls_aes_init(&ctx);		//初始化结构体
	mbedtls_aes_setkey_enc(&ctx, secretKey, 128);	//密码(密钥)

	char iv[16] = { 0 };
	size_t nc_off = 0;
	unsigned char nonce_counter[16] = {0};
	unsigned char stream_block[16] = {0};


	int ret = mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, nonce_counter, stream_block, buf, encrypt_buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n",ret);
	memset(buf,0,sizeof(buf));
	memset(iv,0,sizeof(iv));
	memset(nonce_counter, 0, sizeof(nonce_counter));
	memset(stream_block, 0, sizeof(stream_block));
	printf("\n nc_off = %d\n",nc_off);
	nc_off = 0;

	//mbedtls_aes_setkey_dec(&ctx, secretKey, 128);
	ret = mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, nonce_counter, stream_block, encrypt_buf, buf);	//第三个参数为文档中的偏移量
	printf("\n ret = %d\n", ret);
	
	printf("\nbuf = %s\n",buf);


	mbedtls_aes_free(&ctx);


	getchar();
}

1.6 AES 使用PKCS7Padding填充方式加密

int main(int argc, char *argv[])
{
	unsigned char key[17] = "123456778";
	unsigned char iv[17] = {0};
	unsigned char output[1024];
	unsigned char output1[1024];
	size_t olen;
	size_t total_len = 0;

	mbedtls_cipher_context_t ctx;
	mbedtls_cipher_init(&ctx);
	mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_PKCS7);
	mbedtls_cipher_setup(&ctx,
	mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	mbedtls_cipher_setkey(&ctx, key, 128, MBEDTLS_ENCRYPT);
	mbedtls_cipher_set_iv(&ctx, iv, 16);
	mbedtls_cipher_reset(&ctx);

	char aa[500] = "1234567ytruwieyriuyweioruoiweufowusfhsdfhsdlfjwyoqyfa8";

	printf("\n aa len  = %d \n",strlen(aa));
	mbedtls_cipher_update(&ctx, aa, strlen(aa), output, &olen);
	printf("\nolen = %d\n", olen);
	int inlen = olen;
	 mbedtls_cipher_finish(&ctx, output + olen, &olen);
	 inlen += olen;
	 memcpy(output1 , output, inlen);
	 printf("\nolen = %d\n", olen);
	 printf("\n inlen = %d\n", inlen);
     mbedtls_cipher_free(&ctx);
	 mbedtls_cipher_context_t ctx1;
	 mbedtls_cipher_init(&ctx1);
	 mbedtls_cipher_set_padding_mode(&ctx1, MBEDTLS_PADDING_PKCS7);
	 mbedtls_cipher_setup(&ctx1,mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	 mbedtls_cipher_setkey(&ctx1, key, 128, MBEDTLS_DECRYPT);
	 memset(iv, 0, sizeof(iv));
	 mbedtls_cipher_set_iv(&ctx1, iv, 16);
	 mbedtls_cipher_reset(&ctx1);

	int OLEN1 = 0;
	memset(aa,0,sizeof(aa));
	mbedtls_cipher_update(&ctx1, output1, inlen, aa, &OLEN1);
	total_len = OLEN1;
	mbedtls_cipher_finish(&ctx1, aa + OLEN1, &OLEN1);
	total_len += OLEN1;
	aa[total_len] = 0;
	printf("\n aa = %s \n", aa);
	mbedtls_cipher_free(&ctx1);
	getchar();
}

1.7 AES 使用PKCS5Padding填充方式加密

PKCS5Padding填充加密方式是PKCS7Padding的子集,数据长度固定为8,也就是说加密是需要将长度为len 切分为8的倍数进行加密。

int main(int argc, char *argv[])
{
	unsigned char key[17] = "123456778";
	unsigned char iv[17] = {0};
	unsigned char output[1024];
	unsigned char output1[1024];
	size_t olen;
	size_t total_len = 0;

	mbedtls_cipher_context_t ctx;
	mbedtls_cipher_init(&ctx);
	mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_PKCS7);
	mbedtls_cipher_setup(&ctx,
	mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	mbedtls_cipher_setkey(&ctx, key, 128, MBEDTLS_ENCRYPT);
	mbedtls_cipher_set_iv(&ctx, iv, 16);
	mbedtls_cipher_reset(&ctx);

	char aa[9] = "12345678";

	printf("\n aa len  = %d \n",strlen(aa));
	mbedtls_cipher_update(&ctx, aa, strlen(aa), output, &olen);
	printf("\nolen = %d\n", olen);
    int inlen = olen;
	 mbedtls_cipher_finish(&ctx, output + olen, &olen);
	 inlen += olen;
	 memcpy(output1 , output, inlen);
	 printf("\nolen = %d\n", olen);
	 printf("\n inlen = %d\n", inlen);
     mbedtls_cipher_free(&ctx);
	 mbedtls_cipher_context_t ctx1;
	 mbedtls_cipher_init(&ctx1);
	 mbedtls_cipher_set_padding_mode(&ctx1, MBEDTLS_PADDING_PKCS7);
	 mbedtls_cipher_setup(&ctx1,mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	 mbedtls_cipher_setkey(&ctx1, key, 128, MBEDTLS_DECRYPT);
	 memset(iv, 0, sizeof(iv));
	 mbedtls_cipher_set_iv(&ctx1, iv, 16);
	 mbedtls_cipher_reset(&ctx1);

	int OLEN1 = 0;
	memset(aa,0,sizeof(aa));
	mbedtls_cipher_update(&ctx1, output1, inlen, aa, &OLEN1);
	total_len = OLEN1;
	mbedtls_cipher_finish(&ctx1, aa + OLEN1, &OLEN1);
	total_len += OLEN1;
	aa[total_len] = 0;

	printf("\n aa = %s \n", aa);

	mbedtls_cipher_free(&ctx1);


	getchar();
}

注:mbedtls会在xxx.c文件的最后,写一个类似mbedtls_aes_self_test的明白,不知道用法时可以参考

1.8 mbedtls AES_128_CBC使用pkcs5padding加密问题

1、填充方式概念
在采用aes加密或者其他加密方式时,我们会接触到填充方式的概念,一般有ZeroPadding、PKCS5Padding与PKCS7Padding方式。
ZeroPadding 数据长度不对齐时使用0填充,否则不填充。
PKCS7Padding <1>已对齐,填充一个长度为blockSize且每个字节均为blockSize的数据。
<2>未对齐,需要补充的字节个数为n,则填充一个长度为n且每个字节均为n的数据。
这里针对aes加密来说,blockSize就是16。
PKCS5Padding,PKCS7Padding的子集,只是块大小固定为8字节。

#include "mbedtls/aes.h"
#include "mbedtls/cipher.h"
int aes_cbc_128_test()
{
	unsigned char key[] = "12345678";
	unsigned char iv[] =  "87654321";
	static unsigned char data[1024]= "abcdefgh";
    static unsigned char input_buf[1024] = {0};
    static unsigned char output_buf[1024] = {0};
    int output_len;
    printf("\n data = %s\n",data);
	mbedtls_cipher_context_t ctx = {0};
	printf("\n >>>>>>>>>>>>>>>>>>>>%s %d\n",__func__,__LINE__);
	mbedtls_cipher_init(&ctx);
	mbedtls_cipher_setup(&ctx,
	mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_PKCS7);
	mbedtls_cipher_setkey(&ctx, key, 128, MBEDTLS_ENCRYPT);
	mbedtls_cipher_set_iv(&ctx, iv, 16);
	mbedtls_cipher_reset(&ctx);
    int x=  strlen(data);
	int len =  x + (16 - x% 16);
	int data1 =  16 - (x % 16); //aes 加密要求16对齐,所以aes是没有pkcs5padding加密的,因为pkcs5padding要求8对齐
    memset(input_buf,data1,sizeof(input_buf));
    memcpy(input_buf,data,strlen(data));
    printf( "\n len = %d\n",len );
	mbedtls_cipher_update(&ctx, input_buf, len, output_buf, &output_len);
	printf("\noutput_len = %d \n",output_len);
	int inlen = output_len;
	mbedtls_cipher_finish(&ctx, output_buf + output_len, &output_len);
	printf("\noutput_len = %d \n",output_len);
	inlen+=output_len;
    mbedtls_cipher_free(&ctx);

#if 1
     static unsigned char dec_buf[1024] = {0};
	 mbedtls_cipher_context_t ctx1;
	 mbedtls_cipher_init(&ctx1);
	 mbedtls_cipher_setup(&ctx1,mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, 128,MBEDTLS_MODE_CBC));
	 mbedtls_cipher_set_padding_mode(&ctx1, MBEDTLS_PADDING_PKCS7);
	 mbedtls_cipher_setkey(&ctx1, key, 128, MBEDTLS_DECRYPT);
	 unsigned char deciv[] =  "87654321";
	 mbedtls_cipher_set_iv(&ctx1, deciv, 16);
	 mbedtls_cipher_reset(&ctx1);
	int OLEN1 = 0;
	mbedtls_cipher_update(&ctx1, output_buf, inlen, dec_buf, &OLEN1);
	int total_len = OLEN1;
	mbedtls_cipher_finish(&ctx1, dec_buf + OLEN1, &OLEN1);
	total_len += OLEN1;
	dec_buf[total_len] = 0;
	printf("\n aa = %s \n", dec_buf);
	mbedtls_cipher_free(&ctx1);
#endif // 0
    put_buf(output_buf,inlen);
#if 1
    static int base64[2048];
    if (mbedtls_base64_encode((unsigned char *)base64, sizeof(base64), &len,(const unsigned char *)output_buf, inlen)) {
        puts("mbedtls_base64_encode failed\n");
    }
    printf("\n base64 = %s\n", base64);
#endif
}


1.9签名和验签

定义生成签名的接口 rsa_pkcs1v15_sha256_sign,输入参数有原始数据msg、用于签名的私钥priavte_key_pem、保存签名输出数据的地址sign_base64

int rsa_pkcs1v15_sha256_sign(const unsigned char *msg, size_t msg_len,
                               const char *priavte_key_pem, char *sign_base64, int sign_len)
{
    mbedtls_pk_context pk;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;

    uint8_t sig_buff[SIGNATURE_MAX_SIZE];
    unsigned char hash[32] = {0};
    size_t sig_len = 0;
    int ret = 0;
    char *b64_out = NULL;
    int b64_len = 0;
    const char *pers = "mbedtls_pk_sign";       // Personalization data,
    // that is device-specific identifiers. Can be NULL.
    
    // 初始化随机数生成器
    mbedtls_entropy_init( &entropy );
    mbedtls_ctr_drbg_init( &ctr_drbg );
 
    //初始化上下文
    mbedtls_pk_init( &pk );

    mbedtls_ctr_drbg_seed( &ctr_drbg,
                           mbedtls_entropy_func,
                           &entropy,
                           (const unsigned char *) pers,
                           strlen( pers ) );

 //导入私钥
    ret = mbedtls_pk_parse_key(&pk, (const unsigned char *)priavte_key_pem,
                               strlen(priavte_key_pem)+1,
                               NULL, 0);
    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    // 计算 sha256 消息摘要
    ret = mbedtls_md(mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                     (const unsigned char *)msg, msg_len, hash);
    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }
 
    // 签名
    ret = mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, hash, sizeof (hash), sig_buff, &sig_len, mbedtls_ctr_drbg_random, &ctr_drbg);

    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    b64_out = malloc(sig_len*2);
    if(b64_out == NULL)
    {
        ret = -1;
        goto exit;
    }
 
    // 对签名数据进行 base64 编码
    ret = mbedtls_base64_encode((unsigned char *)b64_out, sig_len*2,
                                (size_t *)&b64_len, (unsigned char *)sig_buff, (size_t)sig_len);

    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    if(sign_len<b64_len)
    {
        ret = -1;
        goto exit;
    }

    strncpy(sign_base64, b64_out, sign_len);

exit:

    if(b64_out)
    {
        free(b64_out);
    }

    mbedtls_pk_free( &pk );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

    return ret;

}

生成签名的测试代码

static void test_rsa_pkcs1_sign(void)
{

    int ret = 0;

    char *private_key = "-----BEGIN RSA PRIVATE KEY-----\n"
                        "MIICXQIBAAKBgQDTt8tp4xNp29CMxy6QS0NzpR6t8bAcv7ei3NkVM/Nzg3K5wWZR\n"
                        "aBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0vwISTO65/XrvR3zqXD5ZjrJF\n"
                        "mtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZlGIIiTPIklxGIGof8QIDAQAB\n"
                        "AoGAFf1BJoiD5+sBdFmsq6ZxhUWZU+ImEzpTUZpD/riEWNNGe2YLoTlg7acgZH1f\n"
                        "P2hbJ9cZdemfTuQvw52JHE0sktCUM6R0wq5rlbDj740+5yZYzs9FlUntm6UtoU9w\n"
                        "tpd62/iPxovFkguunJB2KBbtP8q0dYQntATEce1TZuS3trUCQQDl7VRYygSb3/HY\n"
                        "ij2ya1592WpgNWgmPvbpmUjGGBvjmnO8Ye1lEy6x69RmGjRrLvFfhWYwcF2HpmYQ\n"
                        "9wXKEwT1AkEA67nc/CdeT4j9jRE/QFXlhVrW8Gq8IfjXFGbGK5BqlTRbty3OpW+L\n"
                        "M9GPqiMC2XxN60peEiANlQ8aUnvbHZexjQJAcz4RGK+ov7fvL+maIuNN6SYf+zjJ\n"
                        "iuHkQBFkOGW9FMdFWxZ6Nj73GJZrTwGzZEWTFZ13KrAnMOZmIfquHCqMQQJBAL+u\n"
                        "x9ATg1FRqDyKBdEfCCDEmXuuj4VggCUK3aKXMNRbWyk9iohkh+F/Sz+icLLBreri\n"
                        "8lPy1JidS14/cRJDRBECQQCT4oNvmV5CYzqkqbgwtLPi/FIjc6Zi26DGxBzL01V+\n"
                        "yTO1ZlOOUOtY4dPBnU4COkdq6hWqum/Q6kiVj91qAUHN\n"
                        "-----END RSA PRIVATE KEY-----";
    char *msg = "A message for signing";

    char sign[1024] = {0};

    ret = rsa_pkcs1v15_sha256_sign((const unsigned char *)msg, strlen(msg), private_key, sign, sizeof (sign));


    printf("rsa_pkcs1v15_sha256_sign ret=%d\r\n", ret);

    if(ret == 0)
    {
        printf("sign:%s\r\n", sign);
    }

}

输出结果

rsa_pkcs1v15_sha256_verify ret=0
hash digest before sig
47F53245CD05A2B3E811AD6515000B44604B947A57D441B02125B04F4A16BB74
rsa_pkcs1v15_sha256_sign ret=0
sign:KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=

在c中使用 mbedtls 库进行签名验签,使用到 pk.h、md.h 和 base64.h 这几个头文件定义的接口。

先定义和实现验证签名的接口 rsa_pkcs1v15_sha256_verify,输入参数有原始消息 msg,PEM 格式的公钥 public_key_pem,以及base64 编码后的签名数据 sign_base64。

#include "mbedtls/pk.h"
#include "mbedtls/md.h"
#include "mbedtls/base64.h"

/**
 * @brief rsa_pkcs1v15_sha256_verify
 * 
 * @param [in] msg
 * @param [in] msg_len
 * @param [in] public_key_pem
 * @param [in] sign_base64
 * @return int 
 *  -- 0  verify pass
 *  -- -1 verify faild
 */
int rsa_pkcs1v15_sha256_verify(const unsigned char *msg, size_t msg_len,
                               const char *public_key_pem, const char *sign_base64)
{
    mbedtls_pk_context pk = {0};
    unsigned char hash[32] = {0};
    int ret = 0;
    size_t sign_len = 0;
    size_t b64out_len = 0;
    unsigned char *b64out_data = NULL;

    // 初始化上下文
    mbedtls_pk_init( &pk);

    // 导入公钥
    ret = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)public_key_pem, strlen(public_key_pem)+1);
    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    // 对需要验签的数据进行 sha256 计算,生成消息摘要数据
    ret = mbedtls_md(mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                     (const unsigned char *)msg, msg_len, hash);
    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    // 对原始签名数据进行 base64 解码
    sign_len = strlen(sign_base64);
    b64out_data = malloc(sign_len*2);
    memset(b64out_data, 0, sign_len*2);
    ret = mbedtls_base64_decode(b64out_data, sign_len*2, &b64out_len, (const unsigned char *)sign_base64, sign_len);
    if(ret != 0)
    {
        ret = -1;
        goto exit;
    }

    // 验证签名

    ret = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, sizeof (hash), b64out_data, b64out_len);


exit:
    if(b64out_data)
    {
        free(b64out_data);
    }
    mbedtls_pk_free( &pk );

    return ret;

}
测试验签代码如下

static void test_rsa_pkcs1_verify(void)
{

    int ret = 0;
 // 公钥
    char *pub_key = "-----BEGIN PUBLIC KEY-----\n"
                    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTt8tp4xNp29CMxy6QS0NzpR6t\n"
                    "8bAcv7ei3NkVM/Nzg3K5wWZRaBTMovbzKCXdXYdC6GutVkG+CEetO3XHM4LhDqW0\n"
                    "vwISTO65/XrvR3zqXD5ZjrJFmtCAvkCwtMAPjqXZ/RJnd8yrXuoz5cRqVgKmq5TZ\n"
                    "lGIIiTPIklxGIGof8QIDAQAB\n"
                    "-----END PUBLIC KEY-----";
    // 原始消息
    char *msg = "A message for signing";
 
    // base64 编码之后的签名数据
    char * sign = "KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo"
                  "+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJt"
                  "NSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=";

    ret = rsa_pkcs1v15_sha256_verify((const unsigned char *)msg, strlen(msg), pub_key, sign);


    printf("rsa_pkcs1v15_sha256_verify ret=%d\r\n", ret);

}
输出,返回值为0,验签成功。

rsa_pkcs1v15_sha256_verify ret=0
 类似资料: