107

I am using following code to generate keys:

apt-get -qq -y install openssl;
mkdir -p /etc/apache2/ssl;
openssl genrsa -des3 -out server.key 1024;
openssl req -new -key server.key -out server.csr;
cp server.key server.key.org;
openssl rsa -in server.key.org -out server.key;
openssl x509 -req -days 12000 -in server.csr -signkey server.key -out server.crt;
mv server.crt  /etc/apache2/ssl/cert.pem;
mv server.key  /etc/apache2/ssl/cert.key;
rm -f server.key.orig;
rm -f server.csr

I have two questions:

  1. How can I skip the passphrase prompting? Would it be reasonably safe for me to do so? (as in it should not be downright foolish like anyone should be able to hack the certificate)

  2. How do I avoid the prompting for the country name, organization etc. I hope I can give them on command prompt (the man page shows only top level options for OpenSSL)

jww
  • 12,722

8 Answers8

182

Edit: This is by far my most popular answer, and it's been a few years on now so I've added an ECDSA variant. If you can use ECDSA you should.


You can supply all of that information on the command line.

One step self-signed password-less certificate generation:

RSA Version

openssl req \
    -new \
    -newkey rsa:4096 \
    -days 365 \
    -nodes \
    -x509 \
    -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
    -keyout www.example.com.key \
    -out www.example.com.cert

ECDSA version

openssl req \
    -new \
    -newkey ec \
    -pkeyopt ec_paramgen_curve:prime256v1 \
    -days 365 \
    -nodes \
    -x509 \
    -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
    -keyout www.example.com.key \
    -out www.example.com.cert

All of the openssl subcommands have their own man page. See man req.


Specifically addressing your questions and to be more explicit about exactly which options are in effect:

  1. The -nodes flag signals to not encrypt the key, thus you do not need a password. You could also use the -passout arg flag. See PASS PHRASE ARGUMENTS in the openssl(1) man page for how to format the arg.

  2. Using the -subj flag you can specify the subject (example is above).

bahamat
  • 5,782
12

Doesn't -passin option do the trick for you?

With file:pathname form you can be quite safe with permissions 600 for that file.

9000
  • 435
7

The accepted answer needs a couple of small corrections. EC Lines:

-newkey ec
-pkeyopt ec_paramgen_curve:prime256v1

should be:

 -newkey ec \
 -pkeyopt ec_paramgen_curve:prime256v1 \

On MacOS - OpenSSL 1.0.2f installed via brew I verified the the accepted answer as described below

  • To list available Elliptic curves:

    $ openssl ecparam -list_curves
    
  • To generate a key file:

    $ openssl ecparam -name secp256k1 -out secp256k1.pem
    
  • To generate the cert without password prompt:

    openssl req \
        -new \
        -newkey ec:secp256k1.pem \
        -days 365 \
        -nodes \
        -x509 \
        -subj "/C=US/ST=FL/L=Ocala/O=Home/CN=example.com" \
        -keyout server.key \
        -out server.crt
    
  • To view the cert:

    $ openssl x509 -noout -text -in server.crt
    
5

Try the following command:

openssl genrsa -des3 -out user.key -passout pass:foo 1024

The skipping part is: -passout pass:foo.

kenorb
  • 26,615
2

@bahamat has a great answer. Unfortunately some versions of openssl throw an error when trying to create an ECDSA certificate with one command. The error goes something like:

routines:EVP_PKEY_CTX_ctrl:invalid operation:pmeth_lib.c:404

I was using openssl 1.0.1e-fips on CentOS 7.

Creating your certificate with the following 3 commands seems to work:

openssl ecparam -genkey -name prime256v1 -out key.pem
openssl req -new -key key.pem -out csr.pem -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
openssl req -x509 -days 365 -key key.pem -in csr.pem -out certificate.pem
jxmallett
  • 121
1

Personally I don't like the top answer by providing loads of parameters, it's hard to read. Thankfully OpenSSL provides a config parameter, so the generation of a certificate without password prompts can be done easier and in a more readable and reliable way:

  1. Generate the key:

    openssl genrsa 2048 > localhost.key

  2. Create the config openssl.cnf

    [dn]
    CN=localhost
    

    [req] distinguished_name = dn prompt = no

    [alt_names] DNS.1 = localhost DNS.2 = 127.0.0.1

    [v3_ca] subjectAltName=@alt_names keyUsage=digitalSignature extendedKeyUsage=serverAuth

  3. Generate the certificate:

    openssl req -x509 -new -out localhost.crt -key localhost.key -config openssl.cnf -days 11499 -nodes -extensions v3_ca -sha256

  4. Alternatively with a CSR:

    1. Generate a new CSR:

      openssl req -new -out localhost.csr -key localhost.key -config openssl.cnf

    2. View the data in the CSR:

      openssl req -in localhost.csr -text -noout

       Certificate Request:
           Data:
               Version: 1 (0x0)
               Subject: CN = localhost
               Subject Public Key Info:
                   Public Key Algorithm: rsaEncryption
                       Public-Key: (2048 bit)
                       Modulus:
                           [...]
                           67:9f
                       Exponent: 65537 (0x10001)
               Attributes:
                   (none)
                   Requested Extensions:
           Signature Algorithm: sha256WithRSAEncryption
           Signature Value:
               [...]
      
    3. Generate the certificate:

      openssl x509 -req -days 11499 -in localhost.csr -signkey localhost.key -out localhost.crt -extensions v3_ca -extfile openssl.cnf -sha256

  5. View the data in the certificate: openssl x509 -in localhost.crt -text -noout

     Certificate:
         Data:
             Version: 3 (0x2)
             Serial Number:
                 2b:1e:48:e4:58:19:b4:5e:50:c5:45:6d:0b:3d:07:c8:c5:26:86:cb
             Signature Algorithm: sha256WithRSAEncryption
             Issuer: CN = localhost
             Validity
                 Not Before: Sep  5 11:29:05 2022 GMT
                 Not After : Feb 28 11:29:05 2054 GMT
             Subject: CN = localhost
             Subject Public Key Info:
                 Public Key Algorithm: rsaEncryption
                     Public-Key: (2048 bit)
                     Modulus:
                         [...]
                     Exponent: 65537 (0x10001)
             X509v3 extensions:
                 X509v3 Subject Alternative Name:
                     DNS:localhost, DNS:127.0.0.1
                 X509v3 Key Usage:
                     Digital Signature
                 X509v3 Extended Key Usage:
                     TLS Web Server Authentication
                 X509v3 Subject Key Identifier:
                     5D:72:9B:F4:3E:76:37:15:81:59:28:10:97:A7:A9:5E:37:D9:C5:EF
         Signature Algorithm: sha256WithRSAEncryption
         Signature Value:
             [...]
    
0

https://linux.die.net/man/1/openssl use -passin env:var

Example

export PASSIN="mycertsecretpass"
openssl pkcs12  -passin env:PASSIN -in ${cn}.pfx -nocerts -nodes > ${cn}.key.pem
Rohit Gupta
  • 5,096
0

If you are creating a self-signed certificate to test HTTPS, then you will probably need to add x509 v3 extensions (most notably, subjectAltName) for it to work in most mainstream browsers, but you can also specify them on the terminal (as of OpenSSL 1.1.1):

openssl req -x509 -new -nodes                                      \
  -newkey RSA:2048                                                 \
  -days 365                                                        \
  -subj '/C=US/ST=Denial/L=Earth/O=Dis/CN=anything_but_whitespace' \
  -addext 'subjectAltName = DNS:localhost'                         \
  -addext 'authorityKeyIdentifier = keyid,issuer'                  \
  -addext 'basicConstraints = CA:FALSE'                            \
  -addext 'keyUsage = digitalSignature, keyEncipherment'           \
  -addext 'extendedKeyUsage=serverAuth'                            \
  -out self-signed.crt                                             \
  -keyout private.key

(This won't work in Firefox though.)

toraritte
  • 1,128