MD5withRSA签名,验签,亲测可以使用

编译命令:需要先安装openssl

头文件rsa.h:
#ifndef __RSA_H
#define __RSA_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
unsigned char *base64(const void input, size_t length,char result, size_t size);
unsigned char debase64(char input, size_t length, char result, size_t size);
unsigned char * GetSign(char
keyFile,char
plainText,unsigned char
cipherText,unsigned int cipherTextLen);
bool VerifySign(char
certFile,unsigned char
cipherText,unsigned int cipherTextLen,char
plainText);

#endif

源码:rsa.c
#include “rsa.h”

/* 对二进制数据进行base64编码 /
/
input:数组,length:数组长度,result:存储编码后的数据,size:数组大小 */
unsigned char *base64(const void *input, size_t length,char *result, size_t size)
{
BIO *bmem, *b64;
BUF_MEM *bptr;

	b64 = BIO_new(BIO_f_base64());
	bmem = BIO_new(BIO_s_mem());
	b64 = BIO_push(b64, bmem);
	BIO_write(b64, input, length);
	BIO_flush(b64);
	BIO_get_mem_ptr(b64, &bptr);

	if(size < bptr->length-1)
	{
			printf("the size is so small\n");
			return NULL;
	}
	memcpy(result, bptr->data, bptr->length-1);
	result[bptr->length-1] = 0;
	BIO_free_all(b64);

	return result;

}
/* 对base64数据进行解码 /
/
input:待解码数组,length:数组长度,result:解码后数据暂存区,暂存区大小 */
unsigned char *debase64(char *input, size_t length, char *result, size_t size)
{
BIO * b64 = NULL;
BIO * bmem = NULL;
assert(NULL != input);
if (length > size)
return NULL;
memset(result, 0, size);

	b64 = BIO_new(BIO_f_base64());
	bmem = BIO_new_mem_buf(input, length);
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	if (NULL == b64 || NULL == bmem) 
	{
			perror("BIO_new");
			return NULL;
	}
	bmem = BIO_push(b64, bmem);
	BIO_read(bmem, result, length);
	BIO_free_all(b64);
	return result;

}
/* 生成签名函数 /
/
1:私钥文件名,2:待签名的数据,3:签名后的数据存储区,4:前面存储区长度*/
unsigned char * GetSign(char* keyFile,char* plainText,unsigned char* cipherText,unsigned int cipherTextLen)
{
FILE
fp = fopen (keyFile, “r”);
if (fp == NULL)
return NULL;

	/* Read private key */  
	EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);  
	fclose (fp);  

	if (pkey == NULL) 
	{   
			ERR_print_errors_fp (stderr);  
			return NULL;  
	}  

	/* Do the signature */  
	EVP_MD_CTX     md_ctx = EVP_MD_CTX_create();  
	EVP_SignInit   (&md_ctx, EVP_md5());  
	EVP_SignUpdate (&md_ctx, plainText, strlen(plainText));  
	int err = EVP_SignFinal (&md_ctx, cipherText, cipherTextLen, pkey);  

	if (err != 1) {  
			ERR_print_errors_fp(stderr);  
			return NULL;  
	}  
	//释放内存操作
	EVP_MD_CTX_cleanup(md_ctx);
	EVP_PKEY_free(pkey);  
	return cipherText;  

}
/* 验证签名函数 /
/
1:公钥文件名,2:签名生成的数据,3:签名生成的数据大小,4:验签结果*/
bool VerifySign(char* certFile,unsigned char* cipherText,unsigned int cipherTextLen,char* plainText)
{
FILE* fp = fopen(certFile, “r”);
if (fp == NULL)
return false;
EVP_PKEY pkey=PEM_read_PUBKEY(fp,NULL,NULL,NULL);
if (pkey == NULL)
{
printf(“pkey fail\n”);
ERR_print_errors_fp (stderr);
return false;
}
EVP_MD_CTX md_ctx;
EVP_VerifyInit (&md_ctx, EVP_md5());
EVP_VerifyUpdate (&md_ctx, plainText, strlen((char
)plainText));
int err = EVP_VerifyFinal (&md_ctx, cipherText, cipherTextLen, pkey);
EVP_PKEY_free (pkey);

	if (err != 1) {  
			ERR_print_errors_fp (stderr);  
			return false;  
	}
	fclose(fp);
	return true;  

}

测试代码test.c:
#include “RSA.h”
int main()
{
unsigned char cipher[2048];
unsigned int cipher_len;
unsigned char base[2048];
unsigned char plainText[]=“id=gw_00:0C:29:CB:E8:68&version=1&versionName=123”;
unsigned char *p=GetSign(“prikey.pem”,plainText,cipher,&cipher_len);
if(p==NULL)
{
printf(“sign error\n”);
return -1;
}
if(VerifySign(“pubkey.pem”,cipher,cipher_len,plainText))
printf(“Verify OK\n”);
else
printf(“Verify Fail\n”);
//printf(“get sign:%d\n%s\n”,cipher_len,cipher);
char *q = base64(cipher,cipher_len,base,sizeof(base));
printf(“get sign:%lu\n%s\n”,strlen(base),base);

return 0;

}

编译说明:
gcc test.c RSA.c -lssl -lcrypto

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值