Skip to content

Instantly share code, notes, and snippets.

@SamuelDudley
Forked from mtigas/gist:952344
Created October 21, 2019 06:07
Show Gist options
  • Select an option

  • Save SamuelDudley/e555e4fa2d962d92aa9c807e0d28cdfd to your computer and use it in GitHub Desktop.

Select an option

Save SamuelDudley/e555e4fa2d962d92aa9c807e0d28cdfd to your computer and use it in GitHub Desktop.

Revisions

  1. @mtigas mtigas revised this gist Apr 10, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -64,7 +64,7 @@ openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
    # client_id is *only* for the output filenames
    # incrementing the serial number is important
    CLIENT_ID="01-alice"
    CLIENT_SERIAL_NUMBER=01
    CLIENT_SERIAL=01

    ###### PICK ONE OF THE TWO FOLLOWING ######
    ###### (instrux in the CA section above) ######
  2. @mtigas mtigas revised this gist Apr 10, 2019. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -61,7 +61,10 @@ openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
    ### Create the Client Key and CSR

    ```bash
    # client_id is *only* for the output filenames
    # incrementing the serial number is important
    CLIENT_ID="01-alice"
    CLIENT_SERIAL_NUMBER=01

    ###### PICK ONE OF THE TWO FOLLOWING ######
    ###### (instrux in the CA section above) ######
    @@ -81,7 +84,7 @@ openssl ecparam -genkey -name secp256r1 | openssl ec -out ${CLIENT_ID}.key
    openssl req -new -key ${CLIENT_ID}.key -out ${CLIENT_ID}.csr

    # issue this certificate, signed by the CA root we made in the previous section
    openssl x509 -req -days 3650 -in ${CLIENT_ID}.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out ${CLIENT_ID}.pem
    openssl x509 -req -days 3650 -in ${CLIENT_ID}.csr -CA ca.pem -CAkey ca.key -set_serial ${CLIENT_SERIAL} -out ${CLIENT_ID}.pem
    ```

    #### Bundle the private key & cert for end-user client use
  3. @mtigas mtigas revised this gist Apr 10, 2019. 1 changed file with 12 additions and 10 deletions.
    22 changes: 12 additions & 10 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -61,46 +61,48 @@ openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
    ### Create the Client Key and CSR

    ```bash
    CLIENT_ID="01-alice"

    ###### PICK ONE OF THE TWO FOLLOWING ######
    ###### (instrux in the CA section above) ######
    # rsa
    openssl genrsa -aes256 -passout pass:xxxx -out client.pass.key 4096
    openssl rsa -passin pass:xxxx -in client.pass.key -out client.key
    rm client.pass.key
    openssl genrsa -aes256 -passout pass:xxxx -out ${CLIENT_ID}.pass.key 4096
    openssl rsa -passin pass:xxxx -in ${CLIENT_ID}.pass.key -out ${CLIENT_ID}.key
    rm ${CLIENT_ID}.pass.key
    # ec
    openssl ecparam -genkey -name secp256r1 | openssl ec -out client.key
    openssl ecparam -genkey -name secp256r1 | openssl ec -out ${CLIENT_ID}.key
    ###### END "PICK ONE" SECTION ######

    # whichever you picked, you should now have a `client.key` file.

    # generate the CSR
    # i think the Common Name is the only important thing here. think of it like
    # a display name or login.
    openssl req -new -key client.key -out client.csr
    openssl req -new -key ${CLIENT_ID}.key -out ${CLIENT_ID}.csr

    # issue this certificate, signed by the CA root we made in the previous section
    openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client.pem
    openssl x509 -req -days 3650 -in ${CLIENT_ID}.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out ${CLIENT_ID}.pem
    ```

    #### Bundle the private key & cert for end-user client use

    basically https://www.digicert.com/ssl-support/pem-ssl-creation.htm , with the entire trust chain

    cat client.key client.pem ca.pem > client-full-with-privkey.pem
    cat ${CLIENT_ID}.key ${CLIENT_ID}.pem ca.pem > ${CLIENT_ID}.full.pem

    #### Bundle client key into a PFX file
    Most browsers will happily use this if they don't like the raw ascii PEM file. You'll _possibly_ need to set a password here, which you'll need on the browser/client end when you import the key+cert PFX bundle.

    openssl pkcs12 -export -out client-full-with-privkey.pfx -inkey client.key -in client.crt -certfile ca.crt
    openssl pkcs12 -export -out ${CLIENT_ID}.full.pfx -inkey ${CLIENT_ID}.key -in ${CLIENT_ID}.pem -certfile ca.pem

    ### Install Client Key on client device (OS or browser)
    Use `client-full-with-privkey.pfx` and/or `client-full-with-privkey.pem`. Actual instructions vary.
    Use `client.full.pfx` (most commonly accepted in GUI apps) and/or `client.full.pem`. Actual instructions vary.

    ### Install CA cert on nginx
    So that the Web server knows to ask for (and validate) a user's Client Key
    against the internal CA certificate.

    ssl_client_certificate /path/to/ca.crt;
    ssl_client_certificate /path/to/ca.pem;
    ssl_verify_client optional; # or `on` if you require client key

    Configure nginx to pass the authentication data to the backend application:
  4. @mtigas mtigas revised this gist Apr 5, 2019. 1 changed file with 12 additions and 3 deletions.
    15 changes: 12 additions & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,19 @@
    # Client-side SSL
    For excessively paranoid client authentication.

    ---

    > Updated Apr 5 2019: because this is a gist from 2011 that people stumble into and _maybe_ you should AES instead of 3DES in the year of our lord 2019.
    >
    > I've noticed that across platforms, some browsers/devices like like PFX bundles, others like PEMs, some things will import ECC certs just fine but fail to list them in the "select certificate" menu when the server wants it. Server-side stuff seems good, with most things supporting ECC, but clients are a crapshoot. I'd say unless you've got some time to experiment, you may want to stick to RSA. (In my own dev servers i just ended up configuring one set each of a full RSA CA+client stack and a full ECC CA+client stack, and then I just try both ECC & RSA client certs. if your server only lets you use one CA cert root, **you can concatenate multiple CA PEMs together** and then use that combined file.)
    Updated Apr 5 2019:

    because this is a gist from 2011 that people stumble into and _maybe_ you should AES instead of 3DES in the year of our lord 2019.

    some other notes:

    I've noticed that across platforms, some browsers/devices like like PFX bundles, others like PEMs, some things will import ECC certs just fine but fail to list them in the "select certificate" menu when the server wants it. Server-side stuff seems good, with most things supporting ECC, but clients are a crapshoot. I'd say unless you've got some time to experiment, you may want to stick to RSA.

    (In my own dev servers i just ended up configuring both an RSA CA and an ECC CA and using them both on the server, and provisioning one of each type for each client and trying them both. if, like nginx, your server only lets you use one CA cert root, **you can concatenate multiple CA PEMs together** and then [use that combined file](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate).)

    ---

    ## Using self-signed certificate.
    ### Create a Certificate Authority root
  5. @mtigas mtigas revised this gist Apr 5, 2019. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,10 @@
    # Client-side SSL
    For excessively paranoid client authentication.

    Updated Apr 5 2019: because this is a gist from 2011 that people stumble into and _maybe_ you should AES instead of 3DES in the year of our lord 2019.

    > Updated Apr 5 2019: because this is a gist from 2011 that people stumble into and _maybe_ you should AES instead of 3DES in the year of our lord 2019.
    >
    > I've noticed that across platforms, some browsers/devices like like PFX bundles, others like PEMs, some things will import ECC certs just fine but fail to list them in the "select certificate" menu when the server wants it. Server-side stuff seems good, with most things supporting ECC, but clients are a crapshoot. I'd say unless you've got some time to experiment, you may want to stick to RSA. (In my own dev servers i just ended up configuring one set each of a full RSA CA+client stack and a full ECC CA+client stack, and then I just try both ECC & RSA client certs. if your server only lets you use one CA cert root, **you can concatenate multiple CA PEMs together** and then use that combined file.)
    ## Using self-signed certificate.
    ### Create a Certificate Authority root
  6. @mtigas mtigas revised this gist Apr 5, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -67,7 +67,7 @@ openssl ecparam -genkey -name secp256r1 | openssl ec -out client.key
    openssl req -new -key client.key -out client.csr

    # issue this certificate, signed by the CA root we made in the previous section
    openssl x509 -req -days 3650 -in clint.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client.pem
    openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client.pem
    ```

    #### Bundle the private key & cert for end-user client use
  7. @mtigas mtigas revised this gist Apr 5, 2019. 1 changed file with 76 additions and 21 deletions.
    97 changes: 76 additions & 21 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,34 +1,88 @@
    # Client-side SSL
    For excessively paranoid client authentication.

    Updated Apr 5 2019: because this is a gist from 2011 that people stumble into and _maybe_ you should AES instead of 3DES in the year of our lord 2019.

    ## Using self-signed certificate.
    ### Create a Certificate Authority root (which represents this server)
    Organization & Common Name: Some human identifier for this server CA.
    ### Create a Certificate Authority root
    This'll represent you / your org / your server -- basically the thing that vouches for the validity of a key.

    ```bash
    ###### PICK ONE OF THE TWO FOLLOWING ######

    # OPTION ONE: RSA key. these are very well-supported around the internet.
    # you can swap out 4096 for whatever RSA key size you want. this'll generate a key
    # with password "xxxx" and then turn around and re-export it without a password,
    # because genrsa doesn't work without a password of at least 4 characters.
    #
    # some appliance hardware only works w/2048 so if you're doing IOT keep that in
    # mind as you generate CA and client keys. i've found that frirefox & chrome will
    # happily work with stuff in the bigger 8192 ranges, but doing that vs sticking with
    # 4096 doesn't buy you that much extra practical security anyway.

    openssl genrsa -aes256 -passout pass:xxxx -out ca.pass.key 4096
    openssl rsa -passin pass:xxxx -in ca.pass.key -out ca.key
    rm ca.pass.key

    # OPTION TWO: make an elliptic curve-based key.
    # support for ECC varies widely, and support for the predefined curves also varies.
    # it's "secp256r1" in this case, which is as well-supported as it gets but if you want to
    # avoid NIST-provided things, or if you want to go with bigger/newer keys, you can
    # swap that out:
    #
    # * check your openssl supported curves: `openssl ecparam -list_curves`
    # * check client support for whatever browser/language/system/device you want to use:
    # https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations#Supported_elliptic_curves

    openssl ecparam -genkey -name secp256r1 | openssl ec -out ca.key

    ###### END "PICK ONE" SECTION ######

    # whichever you picked, you should now have a `ca.key` file.

    # now generate the CA root cert
    # when prompted, use whatever you'd like, but i'd recommend some human-readable Organization
    # and Common Name.
    openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
    ```

    openssl genrsa -des3 -out ca.key 4096
    openssl req -new -x509 -days 365 -key ca.key -out ca.crt
    ### Create the Client Key and CSR

    ```bash
    ###### PICK ONE OF THE TWO FOLLOWING ######
    ###### (instrux in the CA section above) ######
    # rsa
    openssl genrsa -aes256 -passout pass:xxxx -out client.pass.key 4096
    openssl rsa -passin pass:xxxx -in client.pass.key -out client.key
    rm client.pass.key
    # ec
    openssl ecparam -genkey -name secp256r1 | openssl ec -out client.key
    ###### END "PICK ONE" SECTION ######

    ### Create the Client Key and CSR
    Organization & Common Name = Person name
    # whichever you picked, you should now have a `client.key` file.

    openssl genrsa -des3 -out client.key 4096
    openssl req -new -key client.key -out client.csr
    # self-signed
    openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
    # generate the CSR
    # i think the Common Name is the only important thing here. think of it like
    # a display name or login.
    openssl req -new -key client.key -out client.csr

    #### Convert Client Key to PKCS
    So that it may be installed in most browsers.
    # issue this certificate, signed by the CA root we made in the previous section
    openssl x509 -req -days 3650 -in clint.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out client.pem
    ```

    openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
    #### Bundle the private key & cert for end-user client use

    #### Convert Client Key to (combined) PEM
    Combines `client.crt` and `client.key` into a single PEM file for programs using openssl.
    basically https://www.digicert.com/ssl-support/pem-ssl-creation.htm , with the entire trust chain

    openssl pkcs12 -in client.p12 -out client.pem -clcerts
    cat client.key client.pem ca.pem > client-full-with-privkey.pem

    #### Bundle client key into a PFX file
    Most browsers will happily use this if they don't like the raw ascii PEM file. You'll _possibly_ need to set a password here, which you'll need on the browser/client end when you import the key+cert PFX bundle.

    openssl pkcs12 -export -out client-full-with-privkey.pfx -inkey client.key -in client.crt -certfile ca.crt

    ### Install Client Key on client device (OS or browser)
    Use `client.p12`. Actual instructions vary.
    Use `client-full-with-privkey.pfx` and/or `client-full-with-privkey.pem`. Actual instructions vary.

    ### Install CA cert on nginx
    So that the Web server knows to ask for (and validate) a user's Client Key
    @@ -42,9 +96,10 @@ Configure nginx to pass the authentication data to the backend application:
    * [Client Side Certificate Auth in Nginx](http://blog.nategood.com/client-side-certificate-authentication-in-ngi), section “Passing to PHP.”
    * [SSL module documentation](http://wiki.nginx.org/NginxHttpSslModule)

    See also:

    * my other gist, on doing the key / CSR dance for your HTTPS server: https://gist.github.com/mtigas/6177424
    * mozilla's SSL configuration generator: https://mozilla.github.io/server-side-tls/ssl-config-generator/

    ## Using CACert Keys
    * Get [client key from CACert](https://www.cacert.org/account.php?id=36)
    * Install client key in client device.
    * Install [CACert root certs](https://www.cacert.org/index.php?id=3) in server and client device.
    * Configure nginx, as above.
    (removed)
  8. @mtigas mtigas created this gist May 2, 2011.
    50 changes: 50 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    # Client-side SSL
    For excessively paranoid client authentication.

    ## Using self-signed certificate.
    ### Create a Certificate Authority root (which represents this server)
    Organization & Common Name: Some human identifier for this server CA.

    openssl genrsa -des3 -out ca.key 4096
    openssl req -new -x509 -days 365 -key ca.key -out ca.crt


    ### Create the Client Key and CSR
    Organization & Common Name = Person name

    openssl genrsa -des3 -out client.key 4096
    openssl req -new -key client.key -out client.csr
    # self-signed
    openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

    #### Convert Client Key to PKCS
    So that it may be installed in most browsers.

    openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

    #### Convert Client Key to (combined) PEM
    Combines `client.crt` and `client.key` into a single PEM file for programs using openssl.

    openssl pkcs12 -in client.p12 -out client.pem -clcerts

    ### Install Client Key on client device (OS or browser)
    Use `client.p12`. Actual instructions vary.

    ### Install CA cert on nginx
    So that the Web server knows to ask for (and validate) a user's Client Key
    against the internal CA certificate.

    ssl_client_certificate /path/to/ca.crt;
    ssl_verify_client optional; # or `on` if you require client key

    Configure nginx to pass the authentication data to the backend application:

    * [Client Side Certificate Auth in Nginx](http://blog.nategood.com/client-side-certificate-authentication-in-ngi), section “Passing to PHP.”
    * [SSL module documentation](http://wiki.nginx.org/NginxHttpSslModule)


    ## Using CACert Keys
    * Get [client key from CACert](https://www.cacert.org/account.php?id=36)
    * Install client key in client device.
    * Install [CACert root certs](https://www.cacert.org/index.php?id=3) in server and client device.
    * Configure nginx, as above.