c语言中使用openssl对rsa私钥解密

单次加密数据的最大长度(block_len),由RSA秘钥模长RSA_size()和填充模式有关

复制代码
  填充模式:RSA_PKCS1_PADDING, block_len=RSA_size() - 11
  填充模式:RSA_PKCS1_OAEP_PADDING,block_len=RSA_size() - 41
  填充模式:RSA_NO_PADDING(不填充),block_len=RSA_size()

本示例用RSA_PKCS1_PADDING填充,所以一次加密117字节,一次解密128字节,超过的字符需要循环解密。

c 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include<openssl/bio.h>
#include<openssl/evp.h>

char* prikey="-----BEGIN RSA PRIVATE KEY-----\n\
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGB\
ALr1s+g6od9C0Jj/a+oEhSUGLOoM8QwAJlTkVTLeKrvEtZCP\
4AQRvsmH7akOo86ja2o33qK+p54AFoKr0T0GaQP6NfsklipK\
N0azBIiwo/tTlwOJUjW3fLQMMNRX/9ZtIYMGSPIOL4FdYJhT\
oJC/dPZ1khaJvf7Oi0rxPuMNVekZAgMBAAECgYBWi9smi83X\
TlTGHqdUA5enFf7AshD73y3fanvOOm5J0bvDGfc3qwdIv7XS\
5sYJqDjXSNm1ONDbIWtKPkN0Hn2J3wDMKzECvvlc+Jb9n1Sm\
7HblKI5PqB3578lcYUQ0M1fIa4AbUBPruInAkAOwuUWvfzmt\
gVky19BXDZNnS+UmAQJBAP389aYz/NfKMSvEq7zht8IQsqXA\
VQinoRLWGTg8uWTd6OZktuBxm9qQDSugIHQlS99PZrSL2xXf\
45bfYKWq7nkCQQC8cNJ+MBr787VmaHdaUK7K32S5NtgJ3g1O\
Nyuzuwi3fj/+PDxB2SMOSWMX5j10N2iGSQ9ctVpXlfaVtQPw\
LaehAkEAvyyU9enxqbct9aTOI5i+SNtqrGotVxtdmSD/0J2c\
ajjB4hDyudOpnQSKdUjMxL+B8W8Bfmo6mKdx1hEC3Q/g+QJB\
AKAlvi5yEazInQTwiWafJT3TBxYFTytrpKExcBmqPak8SYR2\
irtnn0xYADhiex3WrSVa2AxxL9s53ruygCtRkaECQCUkMs3i\
e2OUKa8MQBhup7cbhXiSunO354Xnc4ddjbgPLwW7tGoWEezi\
jNsiJ6XBSMcx6zifs1ybCbeDvdaT/Jo=\
\n-----END RSA PRIVATE KEY-----\n";

typedef struct{
	unsigned char *data; //解密数据
	int len;            //解密数据长度
}decrypt_data_t;


static void crypt_rsa_decrypt(unsigned char *endata,int enlen,decrypt_data_t *out_data){
	RSA *rsa;
	BIO *bio;
	if((bio = BIO_new_mem_buf(prikey, -1)) == NULL)       //从字符串读取RSA公钥
    {
    	printf("BIO_new_mem_buf failed!\n");
    }
	if((rsa=PEM_read_bio_RSAPrivateKey(bio,NULL,NULL,NULL))==NULL)
	{
		printf("PEM_read_bio_RSAPrivateKey failed!");
    }

	int key_len = RSA_size(rsa);
	int ret=0,pos=0;
	int blocklen = 128;
	out_data->data = (unsigned char *)malloc(enlen+1);
	memset(out_data->data,0,enlen+1);
	unsigned char *sub_str = (unsigned char *)malloc(key_len+1);
	unsigned char *out_str = (unsigned char *)malloc(key_len+1);
	memset(sub_str,0,key_len+1);
	memset(out_str,0,key_len+1);
	while(enlen-pos >0){
		if(enlen-pos >blocklen){
			memset(sub_str,0,key_len+1);
			memcpy(sub_str,endata+pos,blocklen);
			ret = RSA_private_decrypt(blocklen,(unsigned char *)sub_str,(unsigned char*)out_str,rsa,RSA_PKCS1_PADDING);
			printf("RSA_private_decrypt ret:%d\n",ret);
			pos +=blocklen;
			if(ret >0){								
				memcpy(out_data->data+out_data->len,out_str,ret);
				out_data->len += ret;
			}
		}else{				
			memset(sub_str,0,key_len+1);
			memcpy(sub_str,endata+pos,enlen-pos);
			ret = RSA_private_decrypt(enlen-pos,(unsigned char *)sub_str,(unsigned char*)out_str,rsa,RSA_PKCS1_PADDING);
			printf("RSA_private_decrypt ret:%d\n",ret);
			pos = enlen;
			if(ret >0){								
				memcpy(out_data->data+out_data->len,out_str,ret);
				out_data->len += ret;
			}		
		}
	}
	
	if(sub_str){
		free(sub_str);
		sub_str = NULL;
	}
	if(out_str){
		free(out_str);
		out_str = NULL;
	}
	RSA_free(rsa);
	BIO_free_all(bio);
	
}
相关推荐
你怎么知道我是队长2 小时前
C语言---枚举变量
c语言·开发语言
李慕婉学姐3 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
吃茄子的猫3 小时前
quecpython中&的具体含义和使用场景
开发语言·python
云栖梦泽3 小时前
易语言中小微企业Windows桌面端IoT监控与控制
开发语言
数据大魔方3 小时前
【期货量化实战】日内动量策略:顺势而为的短线交易法(Python源码)
开发语言·数据库·python·mysql·算法·github·程序员创富
Edward.W4 小时前
Python uv:新一代Python包管理工具,彻底改变开发体验
开发语言·python·uv
小熊officer4 小时前
Python字符串
开发语言·数据库·python
月疯5 小时前
各种信号的模拟(ECG信号、质谱图、EEG信号),方便U-net训练
开发语言·python
荒诞硬汉5 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国5 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos