11

When a key is generated with openssl genrsa, the encryption is selected with a command line argument such as -aes128. After the key is generated, we can see what encryption was used in the file. Ex:

cat host.key

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,AF4EBC2AE861F6FE8C751F7DAD5D4721
... 
-----END RSA PRIVATE KEY-----

When a key is generated via openssl req -newkey rsa:2048 -keyout host.key, the file does not tell what encryption was used.

-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

What is it?

How does openssl rsa -in host.key know how to decrypt the key?


Update

openssl req does encrypt by default with DES-EDE3-CBC.

openssl req -new -x509 -out server.cer -keyout server.key -subj "/CN=toto/" 

Generating a 1024 bit RSA private key
..................++++++
..++++++
writing new private key to 'server.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

cat server.key

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,02306CD22AAC94CD
-----END RSA PRIVATE KEY-----

The problem is with my orignal command. It specified a config which influences key generation in some way still escaping me.

By default, the config will assume encrypt_key = yes. That leads to the key being encrypted with an unspecified algo. Specifying encrypt_key = no under the [req] section is equivalent to the -nodes argument.

The following questions remain though:

  • What encryption is applied by openssl req when a config is specified?
  • Can the algorithm be controlled?
  • How does openssl rsa guess the right cipher for decryption? It must obviously be encoded somewhere in the data...

At first it seems nice to have openssl req generate the key for me. But genrsa offers more control.

Philippe A.
  • 213
  • 2
  • 6
  • 1
    Short answer: des-ede3-cbc with 2048-round PBKDF2. Long answer by Tom Leek here: [stronger encryption for SSH keys](http://security.stackexchange.com/questions/39279/stronger-encryption-for-ssh-keys/39293#39293) – StackzOfZtuff Jul 08 '15 at 15:07
  • Why not write that in an answer I can accept? I found all my answers in there. Most importantly, it is very tempting to conclude like this: don't generate keys with `openssl req`. – Philippe A. Jul 08 '15 at 15:27

1 Answers1

5

What encryption is applied by openssl req when a config is specified?

Grepping through the source code it seems to me, that it's either triple DES or nothing. (Regardless of anything that may have been configured in your configuration file.)

$ git log apps/req.c | head -n3
commit f1cece554ddf282f1512b4da04664467746ffd24
Author: Richard Levitte <levitte@openssl.org>
Date:   Tue Jul 7 11:13:20 2015 +0200

$ grep -n -C1 cipher apps/req.c
197-    X509_REQ *req = NULL;
198:    const EVP_CIPHER *cipher = NULL;
199-    const EVP_MD *md_alg = NULL, *digest = NULL;
--
216-#ifndef OPENSSL_NO_DES
217:    cipher = EVP_des_ede3_cbc();
218-#endif
--
590-        if ((p != NULL) && (strcmp(p, "no") == 0))
591:            cipher = NULL;
592-        if (nodes)
593:            cipher = NULL;
594-
--
597-        assert(private);
598:        if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
599-                                      NULL, 0, NULL, passout)) {

Can the algorithm be controlled?

Nope. See above.

How does openssl rsa guess the right cipher for decryption? It must obviously be encoded somewhere in the data...

Yes. It's in the file. The file itself is an ASN.1 file. You can use OpenSSL to parse it.

$ openssl asn1parse -in keyviareqnewkeycommand.pem -i | cut -c-90
    0:d=0  hl=4 l=1294 cons: SEQUENCE
    4:d=1  hl=2 l=  64 cons:  SEQUENCE
    6:d=2  hl=2 l=   9 prim:   OBJECT            :PBES2
   17:d=2  hl=2 l=  51 cons:   SEQUENCE
   19:d=3  hl=2 l=  27 cons:    SEQUENCE
   21:d=4  hl=2 l=   9 prim:     OBJECT            :PBKDF2
   32:d=4  hl=2 l=  14 cons:     SEQUENCE
   34:d=5  hl=2 l=   8 prim:      OCTET STRING      [HEX DUMP]:D48091CF79B0E2D2
   44:d=5  hl=2 l=   2 prim:      INTEGER           :0800
   48:d=3  hl=2 l=  20 cons:    SEQUENCE
   50:d=4  hl=2 l=   8 prim:     OBJECT            :des-ede3-cbc
   60:d=4  hl=2 l=   8 prim:     OCTET STRING      [HEX DUMP]:EEF03DDF397E19DB
   70:d=1  hl=4 l=1224 prim:  OCTET STRING      [HEX DUMP]:A8DACADF4BABA008CF155C960FD112C

Now PBKDF2 is the key stretching/key derivation algorithm and des-ede3-cbc is the encryption algorithm.

StackzOfZtuff
  • 17,783
  • 1
  • 50
  • 86
  • 4
    This is correct for `req -newkey` in OpenSSL 1.0.0 and higher. In **0.9.8**, which goes off support in a few months but is still used, `req -newkey` writes the "legacy" format like `genrsa` (and `rsa`) using the same cipher (DES-EDE3) but a **weaker KDF** namely a variant of PBKDF1 with only **ONE** iteration. In 1.0.0+ `genpkey` functionally replaces `genrsa` among others and writes the better (PKCS#8) format, but has more complicated parameters. – dave_thompson_085 Aug 26 '15 at 05:34