Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
7.6.1 Problem
You want to use RSA to encrypt data, and you need to generate a public key and its corresponding private key. 7.6.2 Solution
Use a cryptography library's built-in functionality to generate an RSA key pair. Here we'll describe the OpenSSL API. If you insist on implementing RSA yourself (generally a bad idea), see the following discussion. 7.6.3 Discussion
The OpenSSL library provides a function, RSA_generate_key( ), that generates a {public key, private key} pair, which is stored in an RSA object. The signature for this function is: RSA *RSA_generate_key(int bits, unsigned long exp, void (*cb)(int, int, void), void *cb_arg); This function has the following arguments:
If you need to generate an "n-bit" key manually, you can do so as follows:
Here's an example, using the OpenSSL BIGNUM library, of computing all the values you need for a key, given two primes p and q: #include <openssl/bn.h> typedef struct { BIGNUM *n; unsigned long e; /* This number should generally be small. */ } RSA_PUBKEY; typedef struct { BIGNUM *n; BIGNUM *d; /* The actual private key. */ /* These aren't necessary, but speed things up if used. If you do use them, you don't need to keep n or d around. */ BIGNUM *p; BIGNUM *q; BIGNUM *dP, *dQ, *qInv; } RSA_PRIVATE; void spc_keypair_from_primes(BIGNUM *p, BIGNUM *q, unsigned long e, RSA_PUBKEY *pubkey, RSA_PRIVATE *privkey) { BN_CTX *x = BN_CTX_new( ); BIGNUM p_minus_1, q_minus_1, one, tmp, bn_e; pubkey->n = privkey->n = BN_new( ); privkey->d = BN_new( ); pubkey->e = e; privkey->p = p; privkey->q = q; BN_mul(pubkey->n, p, q, x); BN_init(&p_minus_1); BN_init(&q_minus_1); BN_init(&one); BN_init(&tmp); BN_init(&bn_e); BN_set_word(&bn_e, e); BN_one(&one); BN_sub(&p_minus_1, p, &one); BN_sub(&q_minus_1, q, &one); BN_mul(&tmp, &p_minus_1, &q_minus_1, x); BN_mod_inverse(privkey->d, &bn_e, &tmp, x); /* Compute extra values. */ privkey->dP = BN_new( ); privkey->dQ = BN_new( ); privkey->qInv = BN_new( ); BN_mod(privkey->dP, privkey->d, &p_minus_1, x); BN_mod(privkey->dQ, privkey->d, &q_minus_1, x); BN_mod_inverse(privkey->qInv, q, p, x); } 7.6.4 See Also
Recipe 7.1, Recipe 7.2, Recipe 7.5 |