rsa⼤数加密c语⾔,C语⾔:基于OpenSSL-RSA实现RSA⾮对
称加解密
关于OpenSSL的介绍和安装在此不多赘述,可以在⽹上到很多相关资料,各位感兴趣可以去了解下(⾃觉对OpenSSL开源库只是初级使⽤阶段,也就不在此“秀下限”了),直接进⼊主题,本篇源码基于OpenSSL中RSA实现,除此之外还可以基于EVP实现。
⽰例代码:【RSA-1024bit-PKCS1Padding|x509公钥加密|pkcs12私钥解密】
****************************************************************************************
"crtdef.h":
#ifndef __CRTDEF_H
#define __CRTDEF_H
/* x509公钥⽂件 */
#define PUBKEY "/home/nemo/etc/"
/* pkcs12私钥⽂件及密码 */
#define PRIKEY "/home/nemo/etc/rsa/private_111111.pfx"
#define PRIPWD "111111"
/* 校验错误函数宏 */
#define CHECK( func ) { \
if( EXIT_FAILURE == (func) ){ \
exit( EXIT_FAILURE ); \
} \
}
#endif
****************************************************************************************
"rsa.c":
/* 算法:RSA-1024bit-PKCS1Padding
* 公钥加密:x509结构(.cer)
* 私钥解密:pkcs12结构(.pfx)+密码 */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "crtdef.h"
/* 公钥证书加密
* RSA(1024位)/PKCS1Padding算法
* 明⽂最⼤长度:128-11=117字节
* 密⽂长度:128字节
* 返回:成功则返回密⽂长度,失败则返回"EXIT_FAILURE" */
static int encryptRsa( char *plainData, char *cipherData, int plainDataSize ) {
int nResult = 0;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
BIO *bn = NULL;
RSA *pubkey = NULL;
/* 01:加载所有的运算法则 */
OpenSSL_add_all_algorithms();
/* 02:解析cer公钥证书 */
/* 2.1.打开证书⽂件 */
bn = BIO_new_file( PUBKEY, "r" );
if( NULL == bn ){
nResult = EXIT_FAILURE;
fprintf( stderr, "BIO_new_file() Failed!\n" );
goto _err;
}
/* 2.2.读取X509结构 */
cert = PEM_read_bio_X509( bn, NULL, NULL, NULL );
if( NULL == cert ){
nResult = EXIT_FAILURE;
fprintf( stderr, "PEM_read_bio_X509() Failed!\n" );
goto _err;
}
/* 2.3.分解X509结构得到EVP_PKEY */
#if 0
cert = d2i_X509_bio( bn, NULL ); /* DER格式 */
#endif
cert = PEM_read_bio_X509( bn, NULL, NULL, NULL ); /* PEM格式 */
if( NULL == pkey ){
nResult = EXIT_FAILURE;
fprintf( stderr, "X509_get_pubkey() Failed!\n" );
makefile phonyERR_print_errors_fp( stderr );
goto _err;
}
/* 03:EVP_PKEY转换成RSA的KEY */
pubkey = EVP_PKEY_get1_RSA( pkey );
if( NULL == pubkey ){
nResult = EXIT_FAILURE;
fprintf( stderr, "EVP_PKEY_get1_RSA() Failed!\n" );
ERR_print_errors_fp( stderr );
goto _err;
}
/* 04:公钥加密:RSA_PKCS1_PADDING */
nResult = RSA_public_encrypt( plainDataSize, (unsigned char *)plainData, (unsigned char *)cipherData, pubkey, RSA_PKCS1_PADDING );
if( nResult < 0 ){
nResult = EXIT_FAILURE;
fprintf( stderr, "RSA_public_encrypt() Failed!\n" );
ERR_print_errors_fp( stderr );
goto _err;
}
_err:
/* 释放BIO */
if( bn != NULL ){
BIO_free( bn );
bn = NULL;
}
/* 释放X509 */
if( cert != NULL ){
X509_free( cert );
cert = NULL;
}
/* 释放EVP_PKEY */
if( pkey != NULL ){
EVP_PKEY_free( pkey );
pkey = NULL;
}
/* 释放RSA */
if( pubkey != NULL ){
RSA_free( pubkey );
pubkey = NULL;
}
/* 清空加载的内容 */
EVP_cleanup(); /* for EVP */
return nResult;
}
/* 私钥证书解密
* RSA(1024位)/PKCS1Padding算法
* 明⽂最⼤长度:128-11=117字节
* 密⽂长度(固定):128字节
* 返回:成功则返回明⽂长度,失败则返回"EXIT_FAILURE" */
static int decryptRsa( char *cipherData, char *plainData, int cipherDataSize ) {
int nResult = 0;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
PKCS12 *p12 = NULL;
RSA *prikey = NULL;
FILE *fp = NULL;
/* 01:加载所有的运算法则 */
OpenSSL_add_all_algorithms();
/* 02:解析pfx私钥证书 */
/
* 2.1.打开pfx⽂件 */
if( NULL == ( fp = fopen( PRIKEY, "rb" ) ) ){
nResult = EXIT_FAILURE;
fprintf( stderr, "fopen() Failed!\n" );
goto _err;
}
/* 2.2.读取PKCS12结构 */
p12 = d2i_PKCS12_fp( fp, NULL );
if( NULL == p12 ){
nResult = EXIT_FAILURE;
fprintf( stderr, "d2i_PKCS12_fp() Failed!\n" );
goto _err;
}
/* 2.3.分解PKCS12结构得到EVP_PKEY */
if( !PKCS12_parse( p12, PRIPWD, &pkey, &cert, NULL ) ){
nResult = EXIT_FAILURE;
fprintf( stderr, "PKCS12_parse() Failed!\n" );
ERR_print_errors_fp( stderr );
goto _err;
}
/* 03:EVP_PKEY转换成RSA的KEY */
prikey = EVP_PKEY_get1_RSA( pkey );
if( NULL == prikey ){
nResult = EXIT_FAILURE;
fprintf( stderr, "EVP_PKEY_get1_RSA() Failed!\n" );
ERR_print_errors_fp( stderr );
goto _err;
}
/* 04:私钥解密:RSA_PKCS1_PADDING */
nResult = RSA_private_decrypt( cipherDataSize, (unsigned char *)cipherData, (unsigned char *)plainData, prikey, RSA_PKCS1_PADDING );
if( nResult < 0 ){
nResult = EXIT_FAILURE;
fprintf( stderr, "RSA_private_decrypt() Failed!\n" );
ERR_print_errors_fp( stderr );
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论