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);
	
}
相关推荐
Fairy_sevenseven3 分钟前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
蜡笔小新星10 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
凯子坚持 c10 分钟前
C语言复习概要(三)
c语言·开发语言
无限大.22 分钟前
c语言200例 067
java·c语言·开发语言
余炜yw24 分钟前
【Java序列化器】Java 中常用序列化器的探索与实践
java·开发语言
无限大.25 分钟前
c语言实例
c语言·数据结构·算法
篝火悟者25 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python
Death20028 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半88829 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
惜.己29 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5