rsa openssl实现

折腾,今天本来信心满满的要给文件做个加密,以为很快,结果找的几个博客应该是版本比较老了,运行出叉子,硬是打算放弃了,后来后知后觉的在官网上找了一个demo,总算是勉强吧例子实现了。

大概就是调用openssl的接口,总体来说还是比较简单。
我分了三个部分

  • 生成4096位的密匙对(私密和公密)保存到本地文件中
  • 使用公密对文件进行加密
  • 使用私密对文件进行解密

下面是我三个对应的代码:


生成密匙对(私密和公密)

//gen.c
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define KEY_LENGTH 4096
#define PUB_EXP 3
#define PRINT_KEYS

int main(void)
{
    size_t pri_len;           // Length of private key
    size_t pub_len;           // Length of public key
    char *pri_key;            // Private key
    char *pub_key;            // Public key

    // Generate key pair
    printf("Generating RSA (%d bits) keypair...\n", KEY_LENGTH);
    fflush(stdout);
    RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);

    // To get the C-string PEM form:
    BIO *pri = BIO_new(BIO_s_mem());
    BIO *pub = BIO_new(BIO_s_mem());

    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);

    pri_len = BIO_pending(pri);
    pub_len = BIO_pending(pub);

    pri_key = malloc(pri_len + 1);
    pub_key = malloc(pub_len + 1);

    BIO_read(pri, pri_key, pri_len);
    BIO_read(pub, pub_key, pub_len);

    pri_key[pri_len] = '\0';
    pub_key[pub_len] = '\0';
    int fd_pri = open("key.pri", O_CREAT | O_WRONLY, 0400);
    int fd_pub = open("key.pub", O_CREAT | O_WRONLY, 0400);
    if(fd_pri < 0 || fd_pub < 0){
        printf("error file![%d] - [%d]\n", fd_pri, fd_pub);
        return -1;
    }
    write(fd_pri, pri_key, pri_len);
    write(fd_pub, pub_key, pub_len);

    close(fd_pri);
    close(fd_pub);
    return 0;
}

使用公密对文件进行加密

// en.c
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define KEY_LENGTH 4096
#define PUB_EXP 3
#define PRINT_KEYS
// #define WRITE_TO_FILE
#define PUB_FILE "key.pub"
#define CFG_FILE "data.cfg"
#define CFG_FILE_S "data_s.cfg"

unsigned long get_file_size(const char *path)
{
    unsigned long filesize = -1;
    struct stat statbuff;
    if (stat(path, &statbuff) < 0){
        return filesize;
    }
    else{
        filesize = statbuff.st_size;
    }
    return filesize;
}

int main(void)
{
    char *pub_key;            // Public key
    char msg[KEY_LENGTH / 8]; // Message to encrypt
    char *encrypt = NULL;     // Encrypted message
    char *err;                // Buffer for any error messages

    int fp_pub;
    fp_pub = open(PUB_FILE, O_RDONLY);
    if (fp_pub < 0){
        printf("error file![%d]\n", fp_pub);
        return -1;
    }
    size_t pub_len = get_file_size(PUB_FILE);
    pub_key = (char *)malloc(pub_len + 1);
    lseek(fp_pub, 0L, SEEK_SET);
    read(fp_pub, (void *)pub_key, pub_len);
    pub_key[pub_len] = '\0';
    close(fp_pub);

    BIO *pub1 = BIO_new(BIO_s_mem());
    if (NULL == pub1)
        return -1;
    BIO_puts(pub1, pub_key);
    RSA *keypair2 = PEM_read_bio_RSAPublicKey(pub1, NULL, NULL, NULL);

#ifdef PRINT_KEYS
    printf("\n%s\n", pub_key);
#endif
    printf("done.\n");


    // Encrypt the message
    encrypt = malloc(RSA_size(keypair2));
    int encrypt_len;
    err = malloc(130);

    int fp_l = open(CFG_FILE, O_RDONLY);
    if(fp_l <= 0) {
        printf("open cfg error!\n");
        return -1;
    }
    // if(access(CFG_FILE,0)==0){
    //     unlink(CFG_FILE);
    // }
    int fp_c = open(CFG_FILE_S, O_CREAT | O_WRONLY, 0600);
    if (fp_c <= 0){
        printf("open cfg error!\n");
        return -1;
    }
    int len=0;
    while(1)
    {
        len = read(fp_l, msg, (KEY_LENGTH / 16) - 1);
        msg[len] = 0;
        printf(msg);
        if (len <= 0 || len > (KEY_LENGTH / 16) - 1)
            break;
        printf("\nlen:%d %d\n", len, (KEY_LENGTH / 16));
        // write(pipe_id, buf, file_len);
        if ((encrypt_len = RSA_public_encrypt(len, (unsigned char *)msg, (unsigned char *)encrypt,
                                              keypair2, RSA_PKCS1_OAEP_PADDING)) == -1)
        {
            ERR_load_crypto_strings();
            ERR_error_string(ERR_get_error(), err);
            fprintf(stderr, "Error encrypting message: %s\n", err);
            goto free_stuff;
        }
        write(fp_c, encrypt, encrypt_len);
        printf("encrypt_len: %d\n", encrypt_len);
    }

free_stuff:
    RSA_free(keypair2);
    BIO_free_all(pub1);
    free(pub_key);
    free(encrypt);
    free(err);

    close(fp_c);
    close(fp_l);

    return 0;
}

使用私密对文件进行解密

// de.c
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define KEY_LENGTH 4096
#define PUB_EXP 3
#define PRINT_KEYS
// #define WRITE_TO_FILE
#define PRI_FILE "key.pri"
#define CFG_FILE "data1.cfg"
#define CFG_FILE_S "data_s.cfg"

unsigned long get_file_size(const char *path)
{
    unsigned long filesize = -1;
    struct stat statbuff;
    if (stat(path, &statbuff) < 0)
    {
        return filesize;
    }
    else
    {
        filesize = statbuff.st_size;
    }
    return filesize;
}

int main(void)
{
    char *pri_key;            // Private key
    char msg[KEY_LENGTH / 8]; // Message to encrypt
    char *decrypt = NULL;     // Encrypted message
    char *err;                // Buffer for any error messages

    int fp_pri;
    fp_pri = open(PRI_FILE, O_RDONLY);
    if (fp_pri < 0)
    {
        printf("error file![%d]\n", fp_pri);
        return -1;
    }
    size_t pri_len = get_file_size(PRI_FILE);
    pri_key = (char *)malloc(pri_len + 1);
    lseek(fp_pri, 0L, SEEK_SET);
    read(fp_pri, (void *)pri_key, pri_len);
    pri_key[pri_len] = '\0';
    close(fp_pri);

    BIO *pri1 = BIO_new(BIO_s_mem());
    if (NULL == pri1)
        return -1;
    BIO_puts(pri1, pri_key);
    RSA *keypair3 = PEM_read_bio_RSAPrivateKey(pri1, NULL, NULL, NULL);

#ifdef PRINT_KEYS
    printf("\n%s\n", pri_key);
#endif
    printf("done.\n");

    decrypt = malloc(RSA_size(keypair3));
    err = malloc(130);

    int fp_c = open(CFG_FILE_S, O_RDONLY);
    if (fp_c <= 0){
        printf("open cfg error!\n");
        return -1;
    }
    int fp_l = open(CFG_FILE, O_CREAT | O_WRONLY, 0600);
    if (fp_l <= 0){
        printf("open cfg error!\n");
        return -1;
    }
    int len = 0;
    while (1)
    {
        len = read(fp_c, msg, 512);
        msg[len] = 0;
        if (len <= 0 || len > 512)
            break;
        if ((len = RSA_private_decrypt(len, (unsigned char *)msg, (unsigned char *)decrypt,
                                       keypair3, RSA_PKCS1_OAEP_PADDING)) == -1)
        {
            ERR_load_crypto_strings();
            ERR_error_string(ERR_get_error(), err);
            fprintf(stderr, "Error decrypting message: %s\n", err);
            goto free_stuff;
        }
        decrypt[len] = 0;
        printf("\n%s\n%d %ld\n", decrypt, len, strlen(decrypt));
        write(fp_l, decrypt, strlen(decrypt));
    }

    // printf(encrypt);
free_stuff:
    RSA_free(keypair3);
    BIO_free_all(pri1);
    free(pri_key);
    free(decrypt);
    free(err);

    close(fp_c);
    close(fp_l);

    return 0;
}

还有就是关于这三个文件的编译,我这里简单的做了一个makefile,供大家参考:

gen:gen.c
	gcc -ggdb -Wall -Wextra -o gen gen.c -lcrypto
de: de.c
	gcc -ggdb -Wall -Wextra -o de de.c -lcrypto
en: en.c
	gcc -ggdb -Wall -Wextra -o en en.c -lcrypto

参考

使用 OpenSSL API 进行安全编程
Simple Public Key Encryption with RSA and OpenSSL
由于改的demo,注释比较少,不懂的可以留言交流。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值