openssl-RSA签名和验签

openssl-私钥签名(SHA256withRSA)、公钥验签(SHA1withRSA)

一、来由-决定思路

1、近期调试的一个客户端,为了防止接口请求被劫持、 篡改, 需通过证书对请求数据进行签名操作, 来确保请求数据的完整性;要用私钥对数据进行RSA签名,用的SHA256withRSA, 然后使用 Base64 封装签名结果,将数据发送到服务器,服务器对数据进行验签。
2、针对服务器返回结果数据, 客户端需要进行验签操作来确保接收到的数据的完整性, 要用公钥验证签名,用的SHA1withRSA。
3、不论是计算签名还是进行数据验签,主要是看计算摘要的接口。
4、使用到的证书格式为pem格式的。

二、以下是核心代码

//私钥签名 SHA256withRSA
/*
*  @param   [in] filename 证书路径
*  @param   [in] src 待签名源数据
*  @param   [in] srclen 待签名源数据
*  @param   [out] sign 签名
*  @param   [out] signlen 签名长度
*  @return  -
*/
static int My_Rsa_PrikeySign(char *filename, unsigned char *src, int srclen, unsigned char *sign, int *signlen)
{
    
    
	int iRet = 0;
	unsigned char uchash[256] = {
    
    0};//计算的摘要
		
    if(filename == NULL || src == NULL || sign == NULL)
    {
    
    
		printf("parameter error\r\n");
		return -1;
    }
    
    RSA *rsa_pri_key = RSA_new();

    FILE *fp = NULL;
	//打开文件
    fp = fopen(filename, "rt");
    if ( fp == NULL )
    {
    
    
		RSA_free(rsa_pri_key);
		printf("fopen [%s] error\r\n", filename);
		return -2;
    }
	//读取PEM证书文件
    if(PEM_read_RSAPrivateKey(fp, &rsa_pri_key, 0, 0) == NULL)
    {
    
    
		RSA_free(rsa_pri_key);
 		fclose( fp );
 		printf("PEM_read_RSAPrivateKey error\r\n");
 		return -3;
    }
	//关闭句柄
    fclose( fp );

	//使用的SHA256计算摘要,若是SHA1则替换成对应的函数
    SHA256(src, srclen, uchash);
   	//print_hex("hash", uchash, 32);

	//计算签名,前三个参数传入SHA256对应的参数
    iRet = RSA_sign(NID_sha256, uchash, 32, sign, signlen, rsa_pri_key);
    if(1 != iRet)
    {
    
    
    	RSA_free(rsa_pri_key);
   		printf("RSA_sign error, iRet is:[%d], sign_len is:[%d]\r\n", iRet, signlen);
   		return -4;
   	}
   	
 	printf("RSA_sign ok\n");
    RSA_free(rsa_pri_key);
	return 0;
}


//公钥签名验证 SHA1withRSA
/*
*  @param   [in] filename 证书路径
*  @param   [in] src 待验签源数据
*  @param   [in] srclen 待验签源数据
*  @param   [in] sign 签名
*  @param   [in] signlen 签名长度
*  @return  - 返回0成功,非0失败
*/
static int My_Rsa_PublicVerify(char *filename, unsigned char *src, int srclen, unsigned char *sign, int signlen)
{
    
    
	int iRet = 0;
	unsigned char uchash[256] = {
    
    0};//计算的摘要
	
    if(filename == NULL || src == NULL || sign == NULL)
    {
    
    
		printf("parameter error\r\n");
		return -1;
    }
		
    RSA *rsa_pub_key = RSA_new();

    FILE *fp = NULL;
    fp = fopen(filename, "rt");
    if( fp == NULL )
    {
    
    
		RSA_free(rsa_pub_key);
		printf("fopen [%s] error\r\n", filename);
		return -2;
    }
	
    if(!PEM_read_RSA_PUBKEY(fp, &rsa_pub_key, 0, 0))
    {
    
    
		RSA_free(rsa_pub_key);
		fclose( fp );
		printf("PEM_read_RSA_PUBKEY error\r\n");
		return -3;
    }
    fclose( fp );
    
	//使用的SHA1计算摘要,若是其他算法则替换成对应的函数
    SHA1(src, srclen, uchash);
	//print_hex("hash", uchash, 20);
	
	//计算签名,前三个参数传入SHA1对应的参数
    iRet = RSA_verify(NID_sha1, uchash, 20, sign, signlen, rsa_pub_key);
    if(1 != iRet)
    {
    
    
		RSA_free(rsa_pub_key);
		printf("RSA_verify error, iRet is:[%d], sign_len is:[%d]\r\n", iRet, signlen);
		return -4;
    }
    
 	printf("RSA_verify ok\n");
	RSA_free(rsa_pub_key);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46089486/article/details/103976706