上一篇提到使用openssl讀取RSA的密鑰文件,在此基礎上,本篇介紹具體的RSA加密和解密使用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* rsa.cc
* - Show the usage of RSA encryption/decryption
*/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
 
int main(int argc, char** argv) {
    RSA* rsa;
    unsigned char* input_string;
    unsigned char* encrypt_string;
    unsigned char* decrypt_string;
    int i;
 
    // check usage
    if (argc != 2) {
        fprintf(stderr, "%s <plain text>\n", argv[0]);
        exit(-1);
    }
 
    // set the input string
    input_string = (unsigned char*)calloc(strlen(argv[1]) + 1,
            sizeof(unsigned char));
    if (input_string == NULL) {
        fprintf(stderr, "Unable to allocate memory for input_string\n");
        exit(-1);
    }
    strncpy((char*)input_string, argv[1], strlen(argv[1]));
 
    // Generate RSA parameters with 1024 bits (using exponent 3)
    rsa = RSA_generate_key(1024, 3, NULL, NULL);
 
    // set encryption RSA instance (with only n and e), to resemble
    // the key distribution process
    unsigned char* n_b = (unsigned char*)calloc(RSA_size(rsa), 
            sizeof(unsigned char));
    unsigned char* e_b = (unsigned char*)calloc(RSA_size(rsa), 
            sizeof(unsigned char));
    int n_size = BN_bn2bin(rsa->n, n_b);
    int b_size = BN_bn2bin(rsa->e, e_b);
    // assume the byte strings are sent over the network
    RSA* encrypt_rsa = RSA_new();
    encrypt_rsa->n = BN_bin2bn(n_b, n_size, NULL);
    encrypt_rsa->e = BN_bin2bn(e_b, b_size, NULL);
 
    // alloc encrypt_string
    encrypt_string = (unsigned char*)calloc(RSA_size(encrypt_rsa), 
            sizeof(unsigned char));    
    if (encrypt_string == NULL) {
        fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
        exit(-1);
    }
 
    // encrypt (return the size of the encrypted data)
    // note that if RSA_PKCS1_OAEP_PADDING is used, 
    // flen must be < RSA_size - 41 
    int encrypt_size = RSA_public_encrypt(strlen((char*)input_string),
            input_string, encrypt_string, encrypt_rsa, RSA_PKCS1_OAEP_PADDING);
 
    // alloc decrypt_string
    decrypt_string = (unsigned char*)calloc(RSA_size(rsa), 
            sizeof(unsigned char));
    if (decrypt_string == NULL) {
        fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
        exit(-1);
    }
 
    // decrypt
    int decrypt_size = RSA_private_decrypt(encrypt_size,
            encrypt_string, decrypt_string, rsa, RSA_PKCS1_OAEP_PADDING);
 
    // print
    printf("input_string = %s\n", input_string);
    printf("encrypted string = ");
    for (i=0; i<encrypt_size; ++i) {
        printf("%x%x", (encrypt_string[i] >> 4) & 0xf, 
                encrypt_string[i] & 0xf);    
    }
    printf("\n");
    printf("decrypted string (%d) = %s\n", decrypt_size, decrypt_string);
 
    return 0;
}

編譯Makefile:

CC=g++
CFLAGS=-Wall -g -O2
LIBS=-lcrypto
 
all: rsa 
 
rsa: rsa.cc
    $(CC) $(CFLAGS) rsa.cc -o $@ $(LIBS)
 
clean:
    @rm -f rsa