MD5withRSA实现签名与验签

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。该方法加密是不可逆的过程,就是说只能加密不能解密(除了被破解的情况)。

RSA加密是非对称加密,其使用加解密的秘钥是分开的。加密后得到的是一串二进制字符串,通常需要将其进行base64编码再传输。

以下是代码:RSA.h

/*************************************************
***   MD5withRSA:RSA.h
***	  autor:BruvinLu
***   time:2019-4-23
**************************************************/

#ifndef __RSA_H
#define __RSA_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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_test.c

/*****************************************
****  	TEST
****	
****	time:2019-4-23
******************************************/
#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;
}

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;  
}

参考博客:https://blog.csdn.net/kikajack/article/details/80703894

你可能感兴趣的:(学习笔记,Linux,C)