Topic: How to encrypt an RSA 2048 Private key in PKCS#8 format

Hi,

I am trying  export a  rsa:2048 private key (in pem ) into PKCS#8 format. In openssl, I have used below command to do this.

openssl pkcs8 -topk8 -in server-key.pem -out server-keyPkcs8Enc.pem

After searching in the source code ,  I could see the below API.

WOLFSSL_API
int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa,
                                    const EVP_CIPHER *enc,
                                    unsigned char *kstr, int klen,
                                    pem_password_cb *cb, void *u);

But there is not much information about the parameters. Is there any sample using this API? Can you provide some insight to the
parameters used in this API?

Thanks.

Share

Re: How to encrypt an RSA 2048 Private key in PKCS#8 format

Hi delphiwolf,

Regretfully at this time wolfSSL does not fully support the same output noted by the command:

openssl pkcs8 -topk8 -in server-key.pem -out server-keyPkcs8Enc.pem

This essentially is doing the following steps and I will not what wolfSSL supports:

Step 1: Load in a pem formatted private key - OK supported in wolfSSL
Step 2: Convert PEM key to DER key - OK supported in wolfSSL
Step 3: Create DER formatted PKCS8 object from key - OK supported in wolfSSL
Step 4: Encrypt the PKCS8 object - NOT SUPPORTED
Step 5: Convert DER formatted PKCS8 object to PEM - NOT SUPPORTED

We can get you as for as the unencrypted DER formatted PKCS8 object at this time. The equivalent command in openssl would be:

openssl -pkcs8 -nocrypt -topk8 -inform pem -in server-key.pem -outform der -out server-keyPkcs8.der

Would that be acceptable for your needs? If so please see example code below:

#include <stdio.h>

#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/asn_public.h>

byte key[] = "\n\
-----BEGIN RSA PRIVATE KEY-----\n\
MIIEpQIBAAKCAQEAwJUI4VdB8nFtt9JFQScBZcZFrvK8JDC4lc4vTtb2HIi8fJ/7\n\
qGd//lycUXX3isoH5zUvj+G9e8AvfKtkqBf8yl17uuAh5XIuby6G2JVz2qwbU7lf\n\
P9cZDSVP4WNjUYsLZD+tQ7ilHFw0s64AoGPF9n8LWWh4c6aMGKkCba/DGQEuuBDj\n\
xsxAtGmjRjNph27Euxem8+jdrXO8ey8htf1mUQy9VLPhbV8cvCNz0QkDiRTSELlk\n\
wyrQoZZKvOHUGlvHoMDBY3gPRDcwMpaAMiOVoXe6E9KXc+JdJclqDcM5YKS0sGlC\n\
Qgnp2Ai8MyCzWCKnquvE4eZhg8XSlt/Z0E+t1wIDAQABAoIBAQCa0DQPUmIFUAHv\n\
n+1kbsLE2hryhNeSEEiSxOlq64t1bMZ5OPLJckqGZFSVd8vDmp231B2kAMieTuTd\n\
x7pnFsF0vKnWlI8rMBr77d8hBSPZSjm9mGtlmrjcxH3upkMVLj2+HSJgKnMw1T7Y\n\
oqyGQy7E9WReP4l1DxHYUSVOn9iqo85gs+KK2X4b8GTKmlsFC1uqy+XjP24yIgXz\n\
0PrvdFKB4l90073/MYNFdfpjepcu1rYZxpIm5CgGUFAOeC6peA0Ul7QS2DFAq6EB\n\
QcIw+AdfFuRhd9Jg8p+N6PS662PeKpeB70xs5lU0USsoNPRTHMRYCj+7r7X3SoVD\n\
LTzxWFiBAoGBAPIsVHY5I2PJEDK3k62vvhl1loFk5rW4iUJB0W3QHBv4G6xpyzY8\n\
ZH3c9Bm4w2CxV0hfUk9ZOlV/MsAZQ1A/rs5vF/MOn0DKTq0VO8l56cBZOHNwnAp8\n\
yTpIMqfYSXUKhcLC/RVz2pkJKmmanwpxv7AEpox6Wm9IWlQ7xrFTF9/nAoGBAMuT\n\
3ncVXbdcXHzYkKmYLdZpDmOzo9ymzItqpKISjI57SCyySzfcBhh96v52odSh6T8N\n\
zRtfr1+elltbD6F8r7ObkNtXczrtsCNErkFPHwdCEyNMy/r0FKTV9542fFufqDzB\n\
hV900jkt/9CE3/uzIHoumxeu5roLrl9TpFLtG8SRAoGBAOyY2rvV/vlSSn0CVUlv\n\
VW5SL4SjK7OGYrNU0mNS2uOIdqDvixWl0xgUcndex6MEH54ZYrUbG57D8rUy+UzB\n\
qusMJn3UX0pRXKRFBnBEp1bA1CIUdp7YY1CJkNPiv4GVkjFBhzkaQwsYpVMfORpf\n\
H0O8h2rfbtMiAP4imHBOGhkpAoGBAIpBVihRnl/Ungs7mKNU8mxW1KrpaTOFJAza\n\
1AwtxL9PAmk4fNTm3Ezt1xYRwz4A58MmwFEC3rt1nG9WnHrzju/PisUr0toGakTJ\n\
c/5umYf4W77xfOZltU9s8MnF/xbKixsX4lg9ojerAby/QM5TjI7t7+5ZneBj5nxe\n\
9Y5L8TvBAoGATUX5QIzFW/QqGoq08hysa+kMVja3TnKW1eWK0uL/8fEYEz2GCbjY\n\
dqfJHHFSlDBD4PF4dP1hG0wJzOZoKnGtHN9DvFbbpaS+NXCkXs9P/ABVmTo9I89n\n\
WvUi+LUp0EQR6zUuRr79jhiyX6i/GTKh9dwD5nyaHwx8qbAOITc78bA=\n\
-----END RSA PRIVATE KEY-----\n\n";

int main(int argc, char** argv)
{
    int ret;
    int writeSz = 0;

    byte out[4096];
    byte tmp[4096];
    int tmpSz = (int) sizeof(tmp);
    word32 outSz = sizeof(out);
    word32 keySz = sizeof(key);
    int algoID = RSAk;
    const byte* curveOID = NULL;
    word32 oidSz = 0;
    FILE* file;
    char fName[] = "./wolfSSL-PKCS8-out.pem";
    char fNameDer[] = "./wolfSSL-PKCS8-out.der";

    XMEMSET(out, 0, outSz);
    XMEMSET(tmp, 0, tmpSz);

    /* convert pem to der */
    ret = wolfSSL_KeyPemToDer(key, (int) keySz, tmp, tmpSz, NULL);
    if (ret <= 0) {
        printf("key pem to der failed with error: %d\n", ret);
        return -1;
    }
    printf("Key pem to der successful, returned: %d\n", ret);
    writeSz = ret;

    ret = wc_CreatePKCS8Key(out, &outSz, tmp, (word32) writeSz, algoID, curveOID, oidSz);
    if (ret < 0) {
        printf("Create PKCS8 Key failed, error returned: %d\n", ret);
        return -1;
    }

    printf("SUCCESS, ret = %d\n", ret);
    writeSz = ret;

/* write DER File */
    file = fopen(fNameDer, "wb");
    if (!file) {
        printf("Failed to open file: %s\n", fNameDer);
        return -1;
    }

    ret = (int) fwrite(out, 1, (size_t) writeSz, file);
    fclose(file);

    if (ret <= 0) {
        printf("Failed to write file\n");
        return -1;
    }

/* CURRENTLY NOT SUPPORTED:
 * NOTES:
 * Works but the header is wrong, by default the "PRIVATEKEY_TYPE"
 * actually results in the header:  "-----BEGIN RSA PRIVATE KEY-----"
 * That is incorrect for this particular use-case, it should be: "-----BEGIN PRIVATE KEY-----"
 * we need a new type RSA_PRIVATEKEY_TYPE and for PRIVATEKEY_TYPE to just be
 * private key for this to be supported.
 */
//
//    ret = wc_DerToPem(out, (word32) writeSz, tmp, (word32) tmpSz, PRIVATEKEY_TYPE);
//    if (ret <= 0) {
//        printf("Der To Pem failed with error: %d\n", ret);
//        return -1;
//    }
//
//    printf("Der to Pem returned success: %d\n", ret);
//    writeSz = ret;
//
/* write PEM File */
//    file = fopen(fName, "wb");
//    if (!file) {
//        printf("Failed to open file: %s\n", fName);
//        return -1;
//    }
//
//    ret = (int) fwrite(tmp, 1, (size_t) writeSz, file);
//    fclose(file);
//
//    if (ret <= 0) {
//        printf("Failed to write file\n");
//        return -1;
//    }

    return 0;

}

Warm Regards,

Kaleb