<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Super, that works beautifully. Thanks!!</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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?<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> openssl-users <openssl-users-bounces@openssl.org> on behalf of Viktor Dukhovni <openssl-users@dukhovni.org><br>
<b>Sent:</b> July 22, 2020 7:17 PM<br>
<b>To:</b> openssl-users@openssl.org <openssl-users@openssl.org><br>
<b>Subject:</b> Re: Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2)</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On Wed, Jul 22, 2020 at 08:36:30PM +0000, Claude Robitaille wrote:<br>
<br>
> This is NOT about using the command line utility, it is about using<br>
> the library in a program and exporting a private key, while encrypting<br>
> it.<br>
<br>
Encrypted public keys are created via the PKCS8 API.<br>
<br>
> Now, for my application. I am not sure how to do this. I normally use<br>
> PEM_write_bio_PKCS8PrivateKey to generate a PEM string. That function<br>
> do accept a passphrase and a cipher but it is not possible to set<br>
> parameters. The default values, as I could gather by reading on the<br>
> Internet are weak so I just do not want to lower the Web Crypto API<br>
> end. How to proceed? Is there another function that can be used?<br>
<br>
The function you're looking for is PEM_write_bio_PKCS8_PRIV_KEY_INFO().<br>
With error checks elided, it boils down to:<br>
<br>
    1. const EVP_CIPHER *cipher = EVP_get_cipherbyname(SN_aes_256_cbc);<br>
    2. X509_ALGOR *pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, NID_hmacWithSHA512);<br>
<br>
        The function in question needs documentation, it would be fanstastic<br>
        if someone stepped up to document it, or at least open an issue<br>
        asking for same:<br>
<br>
            X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,<br>
                                          unsigned char *salt, int saltlen,<br>
                                          unsigned char *aiv, int prf_nid);<br>
<br>
        When the IV is null a random IV is generated.<br>
        When the salt is NULL and saltlen == 0 a random salt is used.<br>
        /* When saltlen is 0 and salt is not NULL you may get a segfault! */<br>
<br>
        The return value is freed with: void X509_ALGOR_free(X509_ALGOR *);<br>
<br>
    3.  PKCS8_PRIV_KEY_INFO *p8inf =  EVP_PKEY2PKCS8(pkey);<br>
    4.  X509_SIG *p8 = PKCS8_set0_pbe(pass, strlen(pass), p8inf, pbe);<br>
         <br>
         Here, you might want to pay attention to the character set in<br>
         which the password is encoded, if it is not all ASCII, it<br>
         should be UTF-8 (<a href="https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc8018&amp;data=02%7C01%7C%7C6ecb294783f64bd662eb08d82e969dbe%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637310571707466330&amp;sdata=QJ0dIUR%2FOsrgZn2SpnoRLHQRNZ1E7T4sB0O1CJyWIK8%3D&amp;reserved=0">https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc8018&amp;data=02%7C01%7C%7C6ecb294783f64bd662eb08d82e969dbe%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637310571707466330&amp;sdata=QJ0dIUR%2FOsrgZn2SpnoRLHQRNZ1E7T4sB0O1CJyWIK8%3D&amp;reserved=0</a>)<br>
<br>
    5.   BIO *bio_out = ...<br>
    6.   ret = PEM_write_bio_PKCS8(out_bio, p8);<br>
<br>
-- <br>
    Viktor.<br>
</div>
</span></font></div>
</body>
</html>