RSA - 基于文件代码实现

#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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值