openssl的RSA加密(base64编码)
同AES加密,开头先给出openssl实现base64编码代码
【 base64编码/解码 】
/*************************************************
Function: base64Encode
Description: base64 编码
Input:
1.input 需编码的数据字符串
2.length 实际长度(不可使用strlen求取,字符串中可能含有结束符等)
3.newLine
Output:
Return: 转化后的字符串指针
Others:
*************************************************/
char * base64Encode(const char *buffer, int length, bool newLine)
{
BIO *bmem = NULL;
BIO *b64 = NULL;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
if (!newLine) {
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
}
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, buffer, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
BIO_set_close(b64, BIO_NOCLOSE);
char *buff = (char *)malloc(bptr->length + 1);
memcpy(buff, bptr->data, bptr->length);
buff[bptr->length] = 0;
BIO_free_all(b64);
return buff;
}
/*************************************************
Function: base64Decode
Description: base64 解码
Input:
1.input 需解码的数据字符串
2.length 实际长度(不可使用strlen求取,字符串中可能含有结束符等)
3.newLine
Output:
Return: 转化后的字符串指针
Others:
*************************************************/
char * base64Decode(char *input, int length, bool newLine)
{
BIO *b64 = NULL;
BIO *bmem = NULL;
char *buffer = (char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
if (!newLine) {
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
}
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
【 RSA加密/解密 】
#include "openssl/rsa.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
/*************************************************
Function: rsa_encrypt
Description: RSA加密
Input:
1.str 需加密的数据字符串
2.path_key 公钥存储文件路径
Output:
Return: 转化后的字符串指针
Others:
*************************************************/
char *rsa_encrypt(char *str,char *path_key){
char *p_en;
RSA *p_rsa;
FILE *file;
int flen,rsa_len;
int in_len, gb_str_len;
if((file=fopen(path_key,"r"))==NULL){
perror("open key file error");
return NULL;
}
if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
//if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){
ERR_print_errors_fp(stdout);
return NULL;
}
flen=strlen(str);
rsa_len=RSA_size(p_rsa);
p_en=(unsigned char *)malloc(rsa_len+1);
memset(p_en,0,rsa_len+1);
in_len = strlen(str);
if(RSA_public_encrypt(in_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_PKCS1_PADDING)<0){
printf("RSA_public_encrypt error! \n");
return NULL;
}
RSA_free(p_rsa);
fclose(file);
return p_en;
}
/*************************************************
Function: rsa_decrypt
Description: RSA解密
Input:
1.str 需解密的数据字符串
2.path_key 私钥存储文件路径
Output:
Return: 转化后的字符串指针
Others:
*************************************************/
char *rsa_decrypt(char *str,char *path_key){
char *p_de;
RSA *p_rsa;
FILE *file;
int rsa_len;
int in_len, gb_str_len;
if((file=fopen(path_key,"r"))==NULL){
perror("open key file error");
return NULL;
}
if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
ERR_print_errors_fp(stdout);
return NULL;
}
rsa_len=RSA_size(p_rsa);
p_de=(unsigned char *)malloc(rsa_len+1);
memset(p_de,0,rsa_len+1);
in_len = strlen(str);
if(RSA_private_decrypt(in_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_PKCS1_PADDING)<0){
printf("RSA_private_decrypt error! \n");
return NULL;
}
RSA_free(p_rsa);
fclose(file);
return p_de;
}
【 实际调用 】
#define PUBKEY_PATH "./rsa_public_key.pem"
#define PRIKEY_PATH "./rsa_private_key.pem"
void main()
{
int num = 0;
bool newLine = false;
char *source = "laodainiubi123456789";
char *ptr_en, *ptr_de;
char *decode_base64;
printf("source is: %s\n", source);
ptr_en = rsa_encrypt(source, PUBKEY_PATH);
printf("after rsa_encrypt: %s\n", ptr_en);
// daisy 实际长度(不可使用strlen求取,字符串中可能含有结束符等)
// 简单粗暴的方法。判断从当前指针指向的字符开始,往后3位均为空,则判定当前到达字符串末尾
while(!((*(ptr_en + num) == NULL) && (*(ptr_en + num + 1) == NULL) \
&& (*(ptr_en + num + 2) == NULL) && (*(ptr_en + num + 3) == NULL)))
{
num++;
}
printf("num = %d \n", num);
char * encode = base64Encode(ptr_en, num, newLine);
printf("after base64Encode:%s\n", encode);
char * decode = base64Decode(encode, strlen(encode), newLine);
printf("after base64Decode:%s\n", decode);
decode_base64 = rsa_decrypt(decode, PRIKEY_PATH);
printf("after rsa_decrypt:%s\n", decode_base64);
if(ptr_en!=NULL)
{
free(ptr_en);
}
if(ptr_de!=NULL)
{
free(ptr_de);
}
}
其他
【 使用openssl解析公钥私钥指数模数 】
公私钥解析出的指数模数相同,则为一对公私钥
openssl rsa -pubin -inform PEM -text < rsa_public_key.pem (rsa_public_key.pem 为公钥文件名)
openssl rsa -inform PEM -text < rsa_private_key.pem
(rsa_private_key.pem 为公钥文件名)