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
>>
>
>

Reply via email to