Solved. Thanks, Mounir. Changing my PEM_read_bio_RSA_PublicKey() to PEM_read_bio_RSA_PUBKEY() did the trick. I don't understand why there are two of these, but I'm new to OpenSSL, so I won't complain about that which I don't sufficiently understand.
Dave On Fri, Feb 18, 2011 at 10:15 AM, David Henry <daverm...@gmail.com> wrote: > Thanks for the response, but adding the -pubout switch did not change > anything. Actually, I had already been using it, but forgot to type it in my > email. Just to make sure though, I recreated the keys and tried again with: > > > openssl genrsa -out rsaprivatekey.pem 2048 > > > openssl rsa -in rsaprivatekey.pem -out rsapublickey.pem -pubout > > I copied and pasted them from the command line this time to make sure I > didn't miss anything. But the problem remains; my programatically-created > keys work, but my command line-created keys do not. I don't understand how > this can be. > > Dave > > > On Thu, Feb 17, 2011 at 10:41 PM, Mounir IDRASSI <mounir.idra...@idrix.net > > wrote: > >> Hi, >> >> Your command line that create the public key is missing the -pubout switch >> that tells the rsa utility to output a public key. So, this command should >> look like : openssl rsa -in rsaprivatekey.pem -out rsapublickey.pem -pubout >> . Without it, it will just output the private key as is. >> >> Moreover, the openssl rsa utility saves the public key using the function >> PEM_write_bio_RSA_PUBKEY and not PEM_write_bio_RSAPubicKey. So, if you want >> your program to be compatible with its output, then you should use >> PEM_write_bio_RSA_PUBKEY and PEM_read_bio_RSA_PUBKEY for saving/loading >> public key files. >> >> I hope this will help, >> -- >> Mounir IDRASSI >> IDRIX >> http://www.idrix.fr >> >> >> On 2/18/2011 4:59 AM, David Henry wrote: >> >>> I've written a bare bones enveloping example that takes a string, seals >>> it in an envelope, and then goes about opening it. Everything works just >>> fine if I generate my RSA keys programatically. Unfortunately, it does not >>> work if I encrypt the session keys with an RSA public key that was created >>> on the command line like: >>> >>> > openssl genrsa -out rsaprivatekey.pem >>> > openssl rsa -in rsaprivatekey.pem -out rsapublickey.pem >>> >>> I would greatly appreciate if someone could explain why my >>> programatically-created keys work, but the command-line ones do not. The >>> code that generates usable keys looks like this: >>> >>> int main() { >>> // generate & check keys ---- >>> RSA* rsa = RSA_generate_key(2048, RSA_F4, NULL, 0); >>> int check_key = RSA_check_key(rsa); >>> while (check_key <= 0) { >>> cerr << "error generating keys -- regenerating..."; >>> rsa = RSA_generate_key(2048, RSA_F4, NULL, 0); >>> check_key = RSA_check_key(rsa); >>> } >>> RSA_blinding_on(rsa, NULL); >>> >>> // write out pem-encoded public key ---- >>> BIO* rsaPublicBio = BIO_new_file("rsapublickey.pem", "w"); >>> PEM_write_bio_RSAPublicKey(rsaPublicBio, rsa); >>> >>> // write out pem-encoded encrypted private key ---- >>> BIO* rsaPrivateBio = BIO_new_file("rsaprivatekey.pem", "w"); >>> PEM_write_bio_RSAPrivateKey(rsaPrivateBio, rsa, NULL, NULL, 0, NULL, >>> NULL); >>> >>> BIO_free(rsaPublicBio); >>> BIO_free(rsaPrivateBio); >>> RSA_free(rsa); >>> >>> ... >>> >>> return 0; >>> } >>> >>> The program that uses the keys is: >>> >>> #include <cstdio> >>> #include <cstring> >>> #include <openssl/ssl.h> >>> #include <openssl/rand.h> >>> #include <openssl/ecdsa.h> >>> >>> #define BUF_SIZE 4096 >>> #define BLOCK_SIZE 32 >>> >>> int main() { >>> // uninitialized symmetric cipher context ---- >>> EVP_CIPHER_CTX* ctx = new EVP_CIPHER_CTX; >>> >>> // symmetric cipher ---- >>> const EVP_CIPHER* type = EVP_aes_256_cbc(); >>> >>> unsigned char >>> message[BUF_SIZE] = >>> >>> >>> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; >>> printf("Unencoded string = {%s}\n", message); >>> >>> int npubk = 1; >>> unsigned char** ek = new unsigned char*[npubk]; >>> int* ekl = new int[npubk]; >>> EVP_PKEY** pubk = new EVP_PKEY*[npubk]; >>> >>> // read in pem-encoded public key ---- >>> BIO* rsa_pub_bio = BIO_new_file("rsapublickey.pem", "r"); >>> RSA* rsa_pub = RSA_new(); >>> PEM_read_bio_RSAPublicKey(rsa_pub_bio, &rsa_pub, NULL, NULL); >>> BIO_free(rsa_pub_bio); >>> >>> // encrypt symmetric session keys ---- >>> for (int i = 0; i < npubk; i++) { >>> pubk[i] = EVP_PKEY_new(); >>> EVP_PKEY_assign_RSA(pubk[i], rsa_pub); >>> ek[i] = new unsigned char[EVP_PKEY_size(pubk[i])]; >>> ekl[i] = EVP_PKEY_size(pubk[i]); >>> } >>> >>> // random initialization vector ---- >>> unsigned char* iv = new unsigned char[EVP_MAX_IV_LENGTH]; >>> RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH); >>> >>> int message_len; // initialized by EVP_SealUpdate & EVP_SealFinal >>> unsigned char encrypt_buf[BUF_SIZE + BLOCK_SIZE]; >>> >>> EVP_SealInit(ctx, type, ek, &ekl[0], &iv[0], &pubk[0], npubk); >>> // EVP_SealUpdate changes message_len to # bytes in message ---- >>> EVP_SealUpdate(ctx, encrypt_buf, &message_len, message, strlen((const >>> char*) message)); >>> printf("buf_len: %d\n", message_len); >>> int total_len = message_len; // line must be between SealUpdate & >>> SealFinal >>> // EVP_SealFinal changes message_len value to # bytes of encryption >>> overhead ---- >>> EVP_SealFinal(ctx, &encrypt_buf[message_len], &message_len); >>> >>> int i; >>> printf("Encoded string = {"); >>> for (i = 0; i < message_len; i++) { >>> printf("%02x", encrypt_buf[i]); >>> } >>> >>> for (i = 0; i < message_len; i++) { >>> printf("%02x", encrypt_buf[i + total_len]); >>> } >>> printf("}\n"); >>> >>> unsigned char decrypt_buf[BUF_SIZE]; >>> int decrypt_len; // initialized by EVP_OpenUpdate & EVP_OpenFinal >>> >>> // read in pem-encoded encrypted private key ---- >>> BIO* rsa_priv_bio = BIO_new_file("rsaprivatekey.pem", "r"); >>> RSA* rsa_priv = RSA_new(); >>> PEM_read_bio_RSAPrivateKey(rsa_priv_bio, &rsa_priv, NULL, NULL); >>> BIO_free(rsa_priv_bio); >>> >>> EVP_PKEY* privk = EVP_PKEY_new(); >>> EVP_PKEY_assign_RSA(privk, rsa_priv); >>> >>> EVP_OpenInit(ctx, type, *ek, ekl[0], &iv[0], privk); >>> // EVP_OpenUpdate changes decrypt_len to # bytes in decrypted message >>> ---- >>> EVP_OpenUpdate(ctx, decrypt_buf, &decrypt_len, encrypt_buf, total_len >>> + message_len); >>> total_len = decrypt_len; // line must be between OpenUpdate & >>> OpenFinal >>> EVP_OpenFinal(ctx, &decrypt_buf[total_len], &decrypt_len); >>> // EVP_OpenFinal changes decrypt_len value to # bytes of encryption >>> overhead ---- >>> decrypt_buf[total_len + decrypt_len] = '\0'; >>> >>> printf("Unencoded string = {%s}\n", decrypt_buf); >>> >>> delete ctx; >>> EVP_PKEY_free(privk); >>> for (int i = 0; i < npubk; i++) { >>> EVP_PKEY_free(pubk[i]); >>> delete ek[i]; >>> } >>> delete[] ek; >>> delete[] ekl; >>> delete[] pubk; >>> delete[] iv; >>> >>> return 0; >>> } >>> >>> >>> >> ______________________________________________________________________ >> OpenSSL Project http://www.openssl.org >> User Support Mailing List openssl-users@openssl.org >> Automated List Manager majord...@openssl.org >> > >