Encrypt existing PEM keyfile

36 views
Skip to first unread message

Robert Moskowitz

unread,
Sep 24, 2024, 1:44:03 PM9/24/24
to openss...@openssl.org
Right now I want to use openssl command line to be able to take as input
an unecrypted PEM Keyfile (EdDSA) and output it password protected.

I have created the keyfile in python using:

        f.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption(),
            ))

I have found that to have written it encrypted, that should be

encryption_algorithm=serialization.BestAvailableEncryption(b'xyz'))

But I want to be able to work this out step by step, adding the
encryption of the PEM keyfile.

Thus the desire to take an existing unprotected PEM and put out a
password protected one that I can read in to another script.

Looked all over in the docs and asked Dr. Google, but my search foo is
still weak and not finding this out.

Would someone point the way for me?  :)

Also is the "BestAvailableEncryption" the way to write it password
protected in the first place?

Thanks!


Viktor Dukhovni

unread,
Sep 26, 2024, 11:35:49 AM9/26/24
to openss...@openssl.org
On Tue, Sep 24, 2024 at 01:43:43PM -0400, Robert Moskowitz wrote:

> Right now I want to use openssl command line to be able to take as
> input an unecrypted PEM Keyfile (EdDSA) and output it password
> protected.
>
> I have created the keyfile in python using:
>
>         f.write(private_key.private_bytes(
>             encoding=serialization.Encoding.PEM,
>             format=serialization.PrivateFormat.PKCS8,
>             encryption_algorithm=serialization.NoEncryption(),
>             ))
>
> I have found that to have written it encrypted, that should be
>
> encryption_algorithm=serialization.BestAvailableEncryption(b'xyz'))
>
> But I want to be able to work this out step by step, adding the encryption
> of the PEM keyfile.

Are you looking for help with the Python API, or the OpenSSL
command-line? Perhaps there's a better forum for help with the
Python API?

> Thus the desire to take an existing unprotected PEM and put out a password
> protected one that I can read in to another script.
>
> Looked all over in the docs and asked Dr. Google, but my search foo is still
> weak and not finding this out.
>
> Would someone point the way for me?  :)

The "openssl genpkey" command has a "-<cipher>" option, where <cipher>
is the name of the one of the EVP encryption algorithms, say
"aes-128-cbc", ...

$ openssl genpkey -algorithm ed25519
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIByaUJVa2ZMoXYz/xPpQfQle6Shg0bjzXy5ZN6IxqKEB
-----END PRIVATE KEY-----

$ openssl genpkey -algorithm ed25519 -aes-128-cbc
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAhcqj+s5kb1CQICCAAw
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEBH0i7XariZNZwrYvnp0/n8EQLw/
syV97eF0VjcwYRcvM8uuC7MuJZb/q7xCDACD5gHWK0st0QVb7PlJpSA3e3PJ4bae
nyzLRcituSx1KLMLXrM=
-----END ENCRYPTED PRIVATE KEY-----

Or in two steps:

$ openssl genpkey -algorithm ed25519 | openssl pkey -aes-128-cbc
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAgUKiNRdwGFmgICCAAw
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEJx+3f5TpnYWL9QeDsK4kuwEQDkI
IWwhA9pdGDcKHCtNY2veeOw+hndZUNEWof1mvWOHn27Cj5TlOdS4Gc8NRlCH3Rae
dLAPESBcQnBSyMRIYLY=
-----END ENCRYPTED PRIVATE KEY-----

--
Viktor.

Robert Moskowitz

unread,
Sep 26, 2024, 1:07:01 PM9/26/24
to openss...@openssl.org
Greetings Viktor!

On 9/26/24 11:35, Viktor Dukhovni wrote:
> On Tue, Sep 24, 2024 at 01:43:43PM -0400, Robert Moskowitz wrote:
>
>> Right now I want to use openssl command line to be able to take as
>> input an unecrypted PEM Keyfile (EdDSA) and output it password
>> protected.
>>
>> I have created the keyfile in python using:
>>
>>         f.write(private_key.private_bytes(
>>             encoding=serialization.Encoding.PEM,
>>             format=serialization.PrivateFormat.PKCS8,
>>             encryption_algorithm=serialization.NoEncryption(),
>>             ))
>>
>> I have found that to have written it encrypted, that should be
>>
>> encryption_algorithm=serialization.BestAvailableEncryption(b'xyz'))
>>
>> But I want to be able to work this out step by step, adding the encryption
>> of the PEM keyfile.
> Are you looking for help with the Python API, or the OpenSSL
> command-line? Perhaps there's a better forum for help with the
> Python API?

I am working the Python API angle separately.  But I realized I could
shortcut that work by encrypting the PEM key files I already made and
then stepping into the Python stuff.  I made some good headway on that
last night now that I have key files properly encrypted.  This way I
also "know" that what I am doing in Python is using aes128, as that is a
little vague.  At least to me.

>> Thus the desire to take an existing unprotected PEM and put out a password
>> protected one that I can read in to another script.
>>
>> Looked all over in the docs and asked Dr. Google, but my search foo is still
>> weak and not finding this out.
>>
>> Would someone point the way for me?  :)
> The "openssl genpkey" command has a "-<cipher>" option, where <cipher>
> is the name of the one of the EVP encryption algorithms, say
> "aes-128-cbc", ...
>
> $ openssl genpkey -algorithm ed25519

I learned this some 2 years ago on this list.  Got that.  But making
keyfiles is no longer the challenge it is working with encrypted ones. 
So I needed encrypted ones.  Well I COULD have made fresh ones with
openSSL, but what is the fun of that?

So I am moving forward once more.

Thank you all for your time reading my missives and such.  See you
around the water cooler.

David von Oheimb

unread,
Sep 26, 2024, 1:47:39 PM9/26/24
to Robert Moskowitz, openss...@openssl.org
On 26.09.24 02:42, Robert Moskowitz wrote:
openssl pkey -in testprv.pem -aes128 -out testoprv.pem

And with the command line, you cannot overwrite the in file.  I tried.  :)

This is due to a pretty silly oversight:
for no good reason, the tool opens the output file before reading the input file, truncating it to zero length.
Took less than a minute to detect and fix: https://github.com/openssl/openssl/pull/25552


On 9/25/24 05:49, Robert Moskowitz wrote:
ARGH!!!  :)

Like I said, my search foo is weak.

And I use "openssl pkey" often enough to display the PEM content.

Sigh.    Thanks.

Welcome.

BTW, regarding the OpenSSL C API, looking at the respective openssl app implementation usually provides hints which functions to use
(while the structure of the code of many those apps can be rather messy and useful functions may be hard to find).

In this case, apps/pkey.c directly reveals PEM_write_bio_PrivateKey().
For reading private keys, things are handled in a more general and much more complicated fashion in apps/lib/apps.c.
Yet as one might guess, there are similarly simple functions like PEM_write_PrivateKey().

    David



Robert Moskowitz

unread,
Sep 28, 2024, 1:10:42 AM9/28/24
to David von Oheimb, openss...@openssl.org
ARGH!!!  :)

Like I said, my search foo is weak.

And I use "openssl pkey" often enough to display the PEM content.

Sigh.    Thanks.

On 9/25/24 00:16, David von Oheimb wrote:
Hi, looks like you missed https://docs.openssl.org/master/man1/openssl-pkey/

David

Sep 24, 2024 19:44:11 Robert Moskowitz <r...@htt-consult.com>:

--
You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.
To view this discussion on the web visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/9893dea9-dfcc-4525-a36a-af7d371bfde2%40htt-consult.com.

David von Oheimb

unread,
Sep 28, 2024, 1:10:42 AM9/28/24
to Robert Moskowitz, openss...@openssl.org
Hi, looks like you missed https://docs.openssl.org/master/man1/openssl-pkey/

David

Sep 24, 2024 19:44:11 Robert Moskowitz <r...@htt-consult.com>:

Right now I want to use openssl command line to be able to take as input an unecrypted PEM Keyfile (EdDSA) and output it password protected.

Robert Moskowitz

unread,
Sep 28, 2024, 1:10:42 AM9/28/24
to David von Oheimb, openss...@openssl.org
openssl pkey -in testprv.pem -aes128 -out testoprv.pem

And with the command line, you cannot overwrite the in file.  I tried.  :)

thanks


On 9/25/24 05:49, Robert Moskowitz wrote:

Viktor Dukhovni

unread,
Sep 28, 2024, 8:56:02 AM9/28/24
to openss...@openssl.org
On Thu, Sep 26, 2024 at 07:46:59PM +0200, 'David von Oheimb' via openssl-users wrote:
> On 26.09.24 02:42, Robert Moskowitz wrote:
> > openssl pkey -in testprv.pem -aes128 -out testoprv.pem
> >
> > And with the command line, you cannot overwrite the in file.  I tried.  :)
>
> This is due to a pretty silly oversight:
> for no good reason, the tool opens the output file before reading the input
> file, truncating it to zero length.
> Took less than a minute to detect and fix:
> https://github.com/openssl/openssl/pull/25552

Frankly, though the proposed on Github new code reads the key into
memory before truncating the input/output file, this usage pattern is
unsafe.

If the program or the OS crashes before the output is committed to
persistent storage, the key is lost.

It could be argued that OpenSSL could instead refuse to use the same
file for both input and output, thereby discouraging modes of operation
that cannot be made safely atomic.

Writing the output to a *new* file file is less liable to lose the key.
If the key is freshly minted, and does not need to be retained unless
encrypted successfully, then it should be *generated* already encrypted,
without writing the unecrypted key to persistent storage.

- Use a generation method that encrypts in one step.

$ openssl genpkey -algorithm ed25519 -aes-128-cbc

- Generate the key into a pipe with the pipe reader doing the
encryption.

$ openssl genpkey -algorithm ed25519 |
openssl pkey -aes-128-cbc

--
Viktor.
Reply all
Reply to author
Forward
0 new messages