Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2)

Claude Robitaille claude-robitaille at
Thu Jul 23 15:04:30 UTC 2020

Super, that works beautifully. Thanks!!

Now, for sake of completeness, if I wanted to do the opposite, i.e. decrypt a key, I guess the steps are the same, using PEM_read_bio_PKCS8 at the end. Except that the salt and IV must be extracted from the PEM string. What is the function to do that?
From: openssl-users <openssl-users-bounces at> on behalf of Viktor Dukhovni <openssl-users at>
Sent: July 22, 2020 7:17 PM
To: openssl-users at <openssl-users at>
Subject: Re: Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2)

On Wed, Jul 22, 2020 at 08:36:30PM +0000, Claude Robitaille wrote:

> This is NOT about using the command line utility, it is about using
> the library in a program and exporting a private key, while encrypting
> it.

Encrypted public keys are created via the PKCS8 API.

> Now, for my application. I am not sure how to do this. I normally use
> PEM_write_bio_PKCS8PrivateKey to generate a PEM string. That function
> do accept a passphrase and a cipher but it is not possible to set
> parameters. The default values, as I could gather by reading on the
> Internet are weak so I just do not want to lower the Web Crypto API
> end. How to proceed? Is there another function that can be used?

The function you're looking for is PEM_write_bio_PKCS8_PRIV_KEY_INFO().
With error checks elided, it boils down to:

    1. const EVP_CIPHER *cipher = EVP_get_cipherbyname(SN_aes_256_cbc);
    2. X509_ALGOR *pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, NID_hmacWithSHA512);

        The function in question needs documentation, it would be fanstastic
        if someone stepped up to document it, or at least open an issue
        asking for same:

            X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                                          unsigned char *salt, int saltlen,
                                          unsigned char *aiv, int prf_nid);

        When the IV is null a random IV is generated.
        When the salt is NULL and saltlen == 0 a random salt is used.
        /* When saltlen is 0 and salt is not NULL you may get a segfault! */

        The return value is freed with: void X509_ALGOR_free(X509_ALGOR *);

    3.  PKCS8_PRIV_KEY_INFO *p8inf =  EVP_PKEY2PKCS8(pkey);
    4.  X509_SIG *p8 = PKCS8_set0_pbe(pass, strlen(pass), p8inf, pbe);

         Here, you might want to pay attention to the character set in
         which the password is encoded, if it is not all ASCII, it
         should be UTF-8 (

    5.   BIO *bio_out = ...
    6.   ret = PEM_write_bio_PKCS8(out_bio, p8);

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the openssl-users mailing list