#ifdef __cplucplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <time.h>
#define PRIKEY "prikey.pem"
#define PUBKEY "pubkey.pem"
typedef enum pubKeyType
{
RSA_PUBKEY = 0,
RSA_PUBLICKEY = 1,
RSA_BULT
}RSA_PUBKEYTYPE;
struct timespec diff(struct timespec start, struct timespec end)
{
struct timespec temp;
memset(&temp, 0x00, sizeof(temp));
if ((end.tv_nsec - start.tv_nsec) < 0)
{
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
}
else
{
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
/************************************************************************
* RSA加密解密函数
*
* gcc -Wall -O2 -o test_rsa_encdec test_rsa_encdec.c -lcrypto -lssl
*
* author: gospell/wildwolf.heya
************************************************************************/
int rsa_generate_key(const char *prikeyname, const char *pubkeyname, int keylen, RSA_PUBKEYTYPE pubkeytype)
{
RSA *rsa = NULL;
BIGNUM *bne = NULL;
rsa = RSA_new();
bne = BN_new();
BN_set_word(bne, RSA_F4);
if (1 != RSA_generate_key_ex(rsa, keylen, bne, NULL))
{
printf("RSA_generate_key err!\n");
return -1;
}
//start generate private key
BIO *bp = BIO_new_file(prikeyname, "w+");
if (NULL == bp)
{
printf("generate_key bio file new err2!\n");
return -1;
}
if (PEM_write_bio_RSAPrivateKey(bp, rsa, NULL, NULL, 0, NULL, NULL) != 1)
{
printf("PEM_write_bio_RSAPrivateKey err!\n");
return -1;
}
printf("create private key ok!\n");
BIO_free_all(bp);
bp = NULL;
//start generate public key
bp = BIO_new_file(pubkeyname, "w+");
if (NULL == bp)
{
printf("generate_key bio file new err!\n");
return -1;
}
if (RSA_PUBKEY == pubkeytype)
{
if (PEM_write_bio_RSA_PUBKEY(bp, rsa) != 1)
{
printf("PEM_write_bio_RSAPublicKey err!\n");
return -1;
}
}
else if (RSA_PUBLICKEY == pubkeytype)
{
if (PEM_write_bio_RSAPublicKey(bp, rsa) != 1)
{
printf("PEM_write_bio_RSAPublicKey err!\n");
return -1;
}
}
printf("create public key ok!\n");
BIO_free_all(bp);
bp = NULL;
RSA_free(rsa);
rsa = NULL;
return 0;
}
int rsa_pub_encrypt(unsigned char *srcdata, int srcdata_len, unsigned char *desdata, char *pubkey_path, int keymode, RSA_PUBKEYTYPE pubkeytype)
{
RSA *rsa = NULL;
int result = -1;
BIO *bp = NULL;
if ((NULL == srcdata) || (0 == srcdata_len) || (NULL == desdata) || (NULL == pubkey_path))
{
printf("%s %d:input paramters err!\n", __FUNCTION__, __LINE__);
return -1;
}
bp = BIO_new_file(pubkey_path, "rb");
if (NULL == bp)
{
printf("BIO_new_file err!\n");
return -1;
}
/* 读取公钥PEM,PUBKEY格式PEM使用PEM_read_RSA_PUBKEY函数 */
if (RSA_PUBKEY == pubkeytype)
{
if ((rsa = PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPublicKey failure!\n", __FUNCTION__, __LINE__);
return -1;
}
}
else if (RSA_PUBLICKEY == pubkeytype)
{
if ((rsa = PEM_read_bio_RSAPublicKey(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPublicKey failure!\n", __FUNCTION__, __LINE__);
return -1;
}
}
//RSA_print_fp(stdout, rsa, 0);
if (srcdata_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE)
{
RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
return -1;
}
if ((result = RSA_public_encrypt(srcdata_len, srcdata, desdata, rsa, keymode)) < 0)
{
printf("%s %d:RSA_public_encrypt err! result = %d\n", __FUNCTION__, __LINE__, result);
return -1;
}
RSA_free(rsa);
rsa = NULL;
return result;
}
int rsa_pri_encrypt(unsigned char *srcdata, int srcdata_len, unsigned char *desdata, char *prikey_path, int keymode)
{
RSA *rsa = NULL;
int result = -1;
BIO *bp = NULL;
if ((NULL == srcdata) || (0 == srcdata_len) || (NULL == desdata) || (NULL == prikey_path))
{
printf("%s %d:input paramters err!\n", __FUNCTION__, __LINE__);
return -1;
}
bp = BIO_new_file(prikey_path, "rb");
if (NULL == bp)
{
printf("BIO_new_file err!\n");
return -1;
}
if ((rsa = PEM_read_bio_RSAPrivateKey(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPrivateKey\n", __FUNCTION__, __LINE__);
return -1;
}
//RSA_print_fp(stdout, rsa, 0);
if (srcdata_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE)
{
RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
return -1;
}
struct timespec time1;
struct timespec time2;
memset(&time1, 0x00, sizeof(time1));
memset(&time2, 0x00, sizeof(time2));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
result = RSA_private_encrypt(srcdata_len, srcdata, desdata, rsa, keymode);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("time1:%ld s :%ld ns\n", time1.tv_sec, time1.tv_nsec);
printf("time2:%ld s :%ld ns\n", time2.tv_sec, time2.tv_nsec);
printf("time1-time2:%ld s :%ld ns\n", diff(time1, time2).tv_sec, diff(time1, time2).tv_nsec);
//if ((result = RSA_private_encrypt(srcdata_len, srcdata, desdata, rsa, keymode)) < 0)
if (result < 0)
{
printf("%s %d:RSA_private_encrypt err! result = %d\n", __FUNCTION__, __LINE__, result);
return -1;
}
RSA_free(rsa);
rsa = NULL;
return result;
}
int rsa_pri_decrypt(unsigned char *srcdata, int srcdata_len, unsigned char *desdata, char *prikey_path, int keymode)
{
RSA *rsa = NULL;
int result = -1;
BIO *bp = NULL;
if ((NULL == srcdata) || (0 == srcdata_len) || (NULL == desdata) || (NULL == prikey_path))
{
printf("%s %d:input paramters err!\n", __FUNCTION__, __LINE__);
return -1;
}
bp = BIO_new_file(prikey_path, "rb");
if (NULL == bp)
{
printf("BIO_new_file err!\n");
return -1;
}
if ((rsa = PEM_read_bio_RSAPrivateKey(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPrivateKey\n", __FUNCTION__, __LINE__);
return -1;
}
//RSA_print_fp(stdout, rsa, 0);
struct timespec time1;
struct timespec time2;
memset(&time1, 0x00, sizeof(time1));
memset(&time2, 0x00, sizeof(time2));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
result = RSA_private_decrypt(srcdata_len, srcdata, desdata, rsa, keymode);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("time1:%ld s :%ld ns\n", time1.tv_sec, time1.tv_nsec);
printf("time2:%ld s :%ld ns\n", time2.tv_sec, time2.tv_nsec);
printf("time1-time2:%ld s :%ld ns\n", diff(time1, time2).tv_sec, diff(time1, time2).tv_nsec);
//if ((result = RSA_private_decrypt(srcdata_len, srcdata, desdata, rsa, keymode)) < 0)
if (result < 0)
{
printf("%s %d:RSA_private_decrypt err! result = %d\n", __FUNCTION__, __LINE__, result);
return -1;
}
RSA_free(rsa);
rsa = NULL;
return result;
}
int rsa_pub_decrypt(unsigned char *srcdata, int srcdata_len, unsigned char *desdata, char *pubkey_path, int keymode, RSA_PUBKEYTYPE pubkeytype)
{
RSA *rsa = NULL;
int result = -1;
BIO *bp = NULL;
if ((NULL == srcdata) || (0 == srcdata_len) || (NULL == desdata) || (NULL == pubkey_path))
{
printf("%s %d:input paramters err!\n", __FUNCTION__, __LINE__);
return -1;
}
bp = BIO_new_file(pubkey_path, "rb");
if (NULL == bp)
{
printf("BIO_new_file err!\n");
return -1;
}
/* 读取公钥PEM,PUBKEY格式PEM使用PEM_read_RSA_PUBKEY函数 */
if (RSA_PUBKEY == pubkeytype)
{
if ((rsa = PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPublicKey failure!\n", __FUNCTION__, __LINE__);
return -1;
}
}
else if (RSA_PUBLICKEY == pubkeytype)
{
if ((rsa = PEM_read_bio_RSAPublicKey(bp, &rsa, NULL, NULL)) == NULL)
{
printf("%s %d:PEM_read_RSAPublicKey failure!\n", __FUNCTION__, __LINE__);
return -1;
}
}
//RSA_print_fp(stdout, rsa, 0);
if ((result = RSA_public_decrypt(srcdata_len, srcdata, desdata, rsa, keymode)) < 0)
{
printf("%s %d:RSA_public_encrypt err! result = %d\n", __FUNCTION__, __LINE__, result);
return -1;
}
RSA_free(rsa);
rsa = NULL;
return result;
}
int main(int argc, char *argv[])
{
char endata[1024];
int endata_len = 0;
char dedata[1024];
int dedata_len = 0;
int keymode = RSA_PKCS1_PADDING;
RSA_PUBKEYTYPE pubkeytype = RSA_PUBLICKEY;
memset(endata, 0x00, sizeof(endata));
memset(dedata, 0x00, sizeof(dedata));
if (argc > 1)
{
strcpy(endata, argv[1]);
endata_len = strlen(argv[1]) + 1;
}
else
{
char *defaultstr = "helloawildwolf! abcdefwildwolf! 12345wildwolf! @#$%^wildwolf!*";
strcpy(endata, defaultstr);
endata_len = strlen(defaultstr) + 1;
}
rsa_generate_key(PRIKEY, PUBKEY, 1024, pubkeytype);
printf("\nendata:%s, endata_len = %d\n", endata, endata_len);
//签名
dedata_len = rsa_pri_encrypt((unsigned char *)endata, endata_len, (unsigned char *)dedata, PRIKEY, keymode);
printf("\n\nsignature enc is:\n %s len:%d\n\n", dedata, dedata_len);
memset(endata, 0x00, sizeof(endata));
endata_len = 0;
endata_len = rsa_pub_decrypt((unsigned char *)dedata, dedata_len, (unsigned char *)endata, PUBKEY, keymode, pubkeytype);
printf("\n\nsignature dec is:\n %s len:%d\n\n", endata, endata_len);
//数据加密
dedata_len = rsa_pub_encrypt((unsigned char *)endata, endata_len, (unsigned char *)dedata, PUBKEY, keymode, pubkeytype);
printf("\n\ndata enc is:\n %s len:%d\n\n", dedata, dedata_len);
memset(endata, 0x00, sizeof(endata));
endata_len = 0;
endata_len = rsa_pri_decrypt((unsigned char *)dedata, dedata_len, (unsigned char *)endata, PRIKEY, keymode);
printf("\n\ndata dec is:\n %s len:%d\n\n", endata, endata_len);
return 0;
}
#ifdef __cplusplus
#if cplusplus
}
#endif
#endif
RSA - 基于文件代码实现
最新推荐文章于 2024-04-10 10:18:27 发布