Skip to content

Latest commit

 

History

History
774 lines (541 loc) · 24 KB

certification.MD

File metadata and controls

774 lines (541 loc) · 24 KB

Certification

Public key algorithm


Currently there are three public key algorithm in popular. RSA public key DSA Public key and ECDSA Public key. openssl provides ways to generate those different public keys in command line

RSA public key

RSA stands for Rivest, Shamir and Adelman, which is most popular public-key algorithm, it could be used for key-exchange (encrypt data) and sign data. since rsa used for key-exchange, the compromise of a private key can be used to decrypt any previously traffic, it is recommended to use perfect forward secrecy afforded by Diffe-Hellman key exchange.

Algorithm There exists two numbers e and d which could make for a given m

public key is composed with e and n private key is componsed with d and n, for rsa private key (PEM),e is also included.

openssl sub commands

openssl genrsa: gen rsa private key openssl rsa: handle with rsa keys

The following commands could be used to generate a RSA private key in PEM format. this PEM format is in RSA Private key format which contains the public key modulus.

openssl genrsa -out rsa_priv.pem 2048

to check the content of the key.pem file. the -noout flag indicates not output the private key content. from the output, we can see this pem file contains both private key and public key.

openssl rsa -text -in rsa_priv.pem -noout
===
output:
         version           Version,
         modulus           INTEGER,  -- n
         publicExponent    INTEGER,  -- e
         privateExponent   INTEGER,  -- d
         prime1            INTEGER,  -- p
         prime2            INTEGER,  -- q
         exponent1         INTEGER,  -- d mod (p-1)
         exponent2         INTEGER,  -- d mod (q-1)
         coefficient       INTEGER,  -- (inverse of q) mod p
         otherPrimeInfos   OtherPrimeInfos OPTIONAL

to retrieve the rsa public key from the key.pem out, we can issue

openssl rsa -in rsa_priv.pem -pubout -out rsa_pub.pem

to check the public key content,we can issue

openssl rsa -text -pubin -in rsa_pub.pem -noout
==
output:
  modulus           INTEGER,  -- n
  publicExponent    INTEGER   -- e

To check if two key file are related, we can check the n modulus contains in the key file is equals or not

openssl rsa -pubin -in rsa_pub.pem -modulus -noout | openssl md5
openssl rsa -in rsa_priv.pem -modulus -noout | openssl md5

The above rsa_pub.pem is pure public key, which could not be used as certification, to use certification, we need to create x509 public key (aka certificate)

Reference: rfc3447

Reference: public key

DSA public key

DSA: Digital Signature Algorithm

Algorithm

For given three numbers g, p and q, there are a pair of number x and y, which could make

q is generated by g and p.

public key: y

private key: x

Openssl sub commands

openssl dsaparam: gen dsa params.

openssl gendsa: gen dsa private key

openssl dsa : handle with dsa keys

The following command is used to generate dsa public key. as the above algorithm, dsa need a param which composed with g,p and q, so to generate dsa public/private key, we need first generate the dsa params.

Generate dsaparam dsa_param.pem

openssl dsaparam -out dsa_param.pem 1024

we can see the content of dsa_param.pem

openssl dsaparam -in dsa_param.pem -text -noout
==
output
P: xxx
Q: xxx
G: xxx

Use dsa_param.pem to generate dsa key: dsa_priv.pem

openssl gendsa dsa_param.pem -out dsa_priv.pem

we can check the contenxt of dsa_priv.pem, we can see the dsa private key contains both private and public
key, samilar with rsa keys 

openssl dsa -in dsa_priv.pem -text -noout -modulus
==
output 
priv:
pub:
P:
Q:
G:

Alternately, The above two steps could be combine together using -genkey of dsaparam

openssl dsaparam -genkey -out dsa_priv.pem

Extract public key from dsa private key

openssl dsa -in dsa_priv.pem -pubout -out dsa_pub.pem

check the content
openssl dsa -pubin -in dsa_pub.pem -text -noout
==
output
pub:
P:
Q:
G:

ECDSA Public Keys

Relay on the ellipic curve division (ECD). ECDSA keys are much smaller than RSA and DSA, and ECDSA predefined a list of params which could be used to generate keys.

openssl ecparam: handle ecparam and gen ec private keys.

openssl ec: handle with ec keys

Get list of predefined ec param

openssl ecparam -list_curves
==
output
secp112r1 : SECG/WTLS curve over a 112 bit prime field
 secp112r2 : SECG curve over a 112 bit prime field
 secp128r1 : SECG curve over a 128 bit prime field
 secp128r2 : SECG curve over a 128 bit prime field
 secp160k1 : SECG curve over a 160 bit prime field
 secp160r1 : SECG curve over a 160 bit prime field
 secp160r2 : SECG/WTLS curve over a 160 bit prime field
 secp192k1 : SECG curve over a 192 bit prime field
 secp224k1 : SECG curve over a 224 bit prime field
 secp224r1 : NIST/SECG curve over a 224 bit prime field
 secp256k1 : SECG curve over a 256 bit prime field
 secp384r1 : NIST/SECG curve over a 384 bit prime field
 secp521r1 : NIST/SECG curve over a 521 bit prime field
 prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field
 prime192v2: X9.62 curve over a 192 bit prime field
 prime192v3: X9.62 curve over a 192 bit prime field
 prime239v1: X9.62 curve over a 239 bit prime field
 ...

we could rely on those params to create ec params short name, choose prime192v2 from above

openssl ecparam -name prime192v2 -out ecparam.pem

Check the content
openssl ecparam -in ecparam.pem -text
==
ASN1 OID: prime192v1
NIST CURVE: P-192
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBAQ==
-----END EC PARAMETERS-----

Alternately, same with rsa, we can directly generate the private key by providing the params name

openssl ecparam -name prime192v2 -genkey -noout -out ec_key.pem

Then we can use the ec param created above to create ec private key. the ec_key.pem like rsa and dsa key, are composed with params, public and private key.

openssl ecparam -in ecparam.pem -genkey -noout -out ec_key.pem

extra contenxt

openssl ec -in ec_key.pem -text -noout
==
result

priv:
pub:
ASN1 OID:
NIST CURVE:

extract the public key from private key

openssl ec -in ec_key.pem -pubout -out ec_pub.pem

openssl ec -pubin -in ec_pub.pem -text -noout
==
pub:
ASN1 OID:
NIST CURVE:

reference: matching a private key to a public key


x509 certificate


The above private key and public key are pure private/public key, which could not be treated as x509 certificate. x509 certificate is composed with two parts

  • public key
  • User identify

and x509 certificate could be signed by own private key or by ca private key. if it is signed by its own private key, it is a self-signed certificate, if it signed by CA, it is CA signed certification

see the picture below:

The following is details description and steps using openssl to handle x509 certification. Some description for the openssl command

  1. openssl x509

    Certification display and signing utility, reference: openssl x509

    Options:

    -req: by default, x509 expect the certificate as input, if -req is added, csr is expected as input.

    -signkey: cause the input file be signed using supplied private key.

  2. openssl req

    Certification request and generating utility, reference: openssl req

    -x509: by default, the req output is csr, if -x509 is added, the outpus is a self signed certification.

    -new: generates a new csr, promt the user for relevant filed values. if -key is not provided, it will generate the private key using the specified configuration file.

    -key: read the private key

    -newkey: generate csr and new private key together. support rsa:<length> ,dsa:<dsaparam> and ec:<length>

    -out: by default, the certification key will print in standout if -out is not privided.

    -pubout: By default public key is not print in standout, if -pubout, print the public key to standout.

    -keyout: by default, private key is named as privkey.pem, using this option can rename the private key file.

Generate x509 self-signed certificate

  • generate rsa self-signed certificate using existing private key.

if private key exists, generate a self-signed x509 certification using promoted information.

openssl req -x509 -new -key rsa_priv.pem -out rsa_cert.pem

we could check the rsa_cert.pem 
openssl x509 -in rsa_cert.pem -noout -text
==
Certificate:
    Data:
        Version: 3 (0x2) .  # x509 verisons, support v1,v2 and v3
        Serial Number:
            ff:0a:ff:45:8a:4b:6d:5e .  # this is the unique id 
    Signature Algorithm: sha256WithRSAEncryption . # algorithm used to generate the signauture
        Issuer: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=tao/[email protected]  ## who issue the certificate
        Validity               # date validity 
            Not Before: Jul  3 09:26:21 2019 GMT
            Not After : Aug  2 09:26:21 2019 GMT
        Subject: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=tao/[email protected] . ## user name
        Subject Public Key Info:         ## public key info
            Public Key Algorithm: rsaEncryption     
                Public-Key: (2048 bit)
                Modulus:
                    xxxxxxxxx
                Exponent: 65537 (0x10001)
        X509v3 extensions:    ## v3 extensions
            X509v3 Subject Key Identifier:
                D2:60:47:AA:89:3F:21:F3:5C:38:BC:27:A1:43:74:AA:19:BE:08:3F
            X509v3 Authority Key Identifier:
                keyid:D2:60:47:AA:89:3F:21:F3:5C:38:BC:27:A1:43:74:AA:19:BE:08:3F

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption .  ## the signature for the who
        xxxxxxx


  • generate ecdsa certificate
openssl req -x509 -new -key ec_key.pem -out ec_cert1.pem

check the key
openssl x509 -in ec_cert1.pem -text
==
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            d5:01:27:dc:50:18:07:5c
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=AU, ST=AU, L=AU, O=AU, OU=AU, CN=AU/emailAddress=AU
        Validity
            Not Before: Jul  3 10:07:38 2019 GMT
            Not After : Aug  2 10:07:38 2019 GMT
        Subject: C=AU, ST=AU, L=AU, O=AU, OU=AU, CN=AU/emailAddress=AU
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (192 bit)
                pub:
                    xxx
                ASN1 OID: prime192v1
                NIST CURVE: P-192
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                5E:1E:DB:B4:6A:DA:EB:67:99:77:38:50:7E:39:B9:41:2C:95:62:27
            X509v3 Authority Key Identifier:
                keyid:5E:1E:DB:B4:6A:DA:EB:67:99:77:38:50:7E:39:B9:41:2C:95:62:27

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
       xxx

  • generate dsa certificate
openssl req -x509 -new -key dsa_priv.pem -out dsa_cert.pem

openssl x509 -in dsa_cert.pem -text -noout
output
==
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            8a:83:12:ea:5f:08:50:9f
    Signature Algorithm: dsa_with_SHA256
        Issuer: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=tao/[email protected]
        Validity
            Not Before: Jul  3 10:17:50 2019 GMT
            Not After : Aug  2 10:17:50 2019 GMT
        Subject: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=tao/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: dsaEncryption
                pub:
                    xxx
                P:
                    xxx
                Q:
                    xxx
                G:
                    xxx
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                71:B7:5F:4F:EB:7C:84:67:7E:75:F2:CC:8F:6C:E5:04:A3:88:02:90
            X509v3 Authority Key Identifier:
                keyid:71:B7:5F:4F:EB:7C:84:67:7E:75:F2:CC:8F:6C:E5:04:A3:88:02:90

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: dsa_with_SHA256
         r:
            xxx
         s:
            xxx
  • Generate the private key and x509 self-sgined certification together
using rsa
openssl req -x509 -newkey rsa:2048 -keyout rsa_priv.pem -out rsa_cert.pem

using dsa params
openssl req -x509 -newkey dsa:dsa_param.pem -keyout dsa_priv.pem -out dsa_cert.pem

 using ecdsa params
openssl req -x509 -newkey ec:ecparam.pem -keyout ec_priv.pem -out ec_cert.pem

  • Use csr and private key to generate x509 certificate

    To get the certificate signed by CA, instead of give them the private key (should not do this), we can create a csr and send to CA for sign, the result is a CA signed certificate. self-signed certification can also follow this process.

    To better understand this process, we could split certificate request into two steps

    1. Generate the csr based on the private key, notes there is no -x509, the result is csr, not certificate. the below command will promote you to input the configuration value

      openssl req -new -key rsa_priv.pem -out rsa.csr

      we can also create a csr.conf file to provide those values, see create csr conf

      openssl req -new -key rsa_priv.pem -out rsa.csr -conf csr.conf

    2. Generate the certificate using csr and signed by the private key.

      openssl x509 -req -in rsa.csr -signkey rsa_priv.pem -out rsa_cert.pem

Generate x509 internal CA signed certificate

For internal CA signed certification, we need CA certificate and CA private key exists to sign. ca_cert.pem and ca_priv.pem.

We will generate the csr using our own private key rsa.csr and leverage the openssl x509 to sign

`-CA`: the ca certificate file 
`-CAkey`: the ca private key

```
openssl x509 -req -in rsa.csr -CA ca_crt.pem -CAkey ca_key.pem \
  -CAcreateserial -out rsa_crt.pem -days 10000 \
  -extensions v3_ext -extfile csr.conf    
```

Generate x509 public CA-signed certificate

For extenral CA signed certification, we need send the csr generated by our private key to CA for sign. the returned is certification file in various format. notes, we need keep our private key confidential.


How https works


see the picture below

when client use browser to visit a https site, firstly, the https server will send its certification to the browser, this certification could be a self-signed certification, internal CA signed certification or public CA signed certification. A certification is combine of public key and user identity information and signatures. The browser will fisrt to verify if the hostname visited match the CN of the certification, if not, will report the unstrust warning.

Self-signed certification: if it is a self-signed certification, the client browser will report warning that the certification is not trusted. unless we install this self-signed certification into our browser and trust it.

Internal CA signed certification: if it is a internal CA signed certification, browser will try to extract the DN of the issuer and look for installed trusted CA, find the match CA and use the public key of that CA to verify the signature of server certification. if the server certificaiton is signed by the internal CA's private key, then verification will success.

match:

openssl x509 -in ca.crt -subject_hash = openssl x509 -in server.crt -issuer_hash

verify:

openssl verify -CAfile ca.crt server.crt

Private Key (intenral CA) --- sign server certification (encrypt the hash) --> signature Public Key(internal CA)--- verify sign of server certification (encrypt the hash) --> signagure1

if(signature == signagure1){ success. }

Public CA signed certification: if it is public CA signed certification, similar with internal CA signed certification, will go through the CA chain to verify the signature to the root CA. if all pass, then accept the server certification.

reference: how https works

How to difference self-signed certification and CA signed using openssl

openssl -in cert.pem -text -noout

self-signed, the issuer is same with the subject

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            b0:e9:3e:cb:df:32:ba:7f
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=TAO/[email protected]
        Validity
            Not Before: Jul  4 01:59:38 2019 GMT
            Not After : Aug  3 01:59:38 2019 GMT
        Subject: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=TAO/[email protected]
        Subject Public Key Info:

CA signed, the issuer points to a different certification, different with subject

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e1:15:46:0d:c5:eb:74:33
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=TAO/[email protected]
        Validity
            Not Before: Jul  4 02:55:09 2019 GMT
            Not After : Nov 19 02:55:09 2046 GMT
        Subject: C=CN, ST=BJ, L=BJ, O=IBM, OU=IBM, CN=*.fyre.ibm.com
        Subject Public Key Info:


How PKI works


If clients and Server are signed by the same CA, it is easy to understand certificate of A can verify the certificate of B.

If the client and server are signed by different CA, if two CA did not know each other, A can not verify B.

So in the real word, different CA are all signed by its parent CA and back to the same root CA, and this chain is installed in the computer system to make sure the recerieved can verified each other.


Certificate format and convert


There are various x509 certification file format, like PEM, DER, PKCS12, PKCS7.

PEM and PKCS7 are use BASE64 ASCII encoding.

DER and PKCS12 are binary files.

Different format has differnet recommended extension names, see picture below

PEM format

Most CA provides this format, extensions could be .pem,.crt,.key or .cer. the PEM format can include the certification file, intermediate file and priviate key in one single file, or have different file for each. we can use cat command to combine those files. certification are separate by standard separations

Certification

---- BEGIN CERTIFICATE---- 
----END CERTIFICATE---- 

Private key

---- BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY----- 

CSR

-----BEGIN CERTIFICATE REQUEST----- 
-----END CERTIFICATE REQUEST----- 

Convert pem to der

openssl x509 -outform der -in ca.pem -out ca.der

Convert pem to pkcs7

openssl crl2pkcs7 -nocrl -certfile ca.pem -out ca.p7b -certfile CACert.cer

convert pem to pkcs12, we can put the private key, rootCA and ca certification file together into pkcs12

openssl pkcs12 -export -chain -in myca_crt.pem -inkey myca_priv.key -out myca.p12 -CAfile ./rootca.crt 

PKCS7 format

PKCS7 is also in base64 ASCII encoding format. difference is, only certification and chain could be put in PKCS7 format, private key can not. windows and tomcat use this format.

-----BEGIN PKCS7-----
-----END PKCS7-----

convert pkcs7 to pem

openssl pkcs7 -print_certs -in ca.p7b -out ca.pem

DER format

DER format are in binary format of certification, which is mostly used in java based application.

Convert der to pem

openssl x509 -inform der -in ca.der -out ca.pem

PKCS12 format

PKCS12 format is in binary format, which can store the certification, intermediate and private key in a single p12 or pfx file with password protection.

Convert PKCS12 to pem, as PKCS12 contains multiple files, we have multiple options to print out

Extract the client ca only.

-nokey: not create private key in pem

-clcerts: create client certificate in pem

openssl pkcs12 -in ca.p12 -out test1.pem -clcerts -nokeys

extract the root ca certificate

openssl pkcs12 -in ca.p12 -out rootca.pem -cacerts -nokeys

extract the private key only

-nodes: not encrypt the private key.

openssl pkcs12 -in ca.p12 -out key.pem  -nocerts -nodes

JKS format

keystore JKS is java keystore certification, which contains the certification, intermediate and private key together. the keystore could have multiple entries, each entry have a alias.

JKS is handled by java keytool

truststore truststore contains application server's trusted certificates, include the public keys and other entities, not include the private key. for the trusted certificates, the server has confirmed that public key in the certificate belongs to the certificate owner.

keystore and truststore could be used in java base application, and could be define in JVM level by -Djavax.net.ssl.keyStore and -Djavax.net.ssl.trustStore

display the keystore information

keytool -list -v  -keystore ${keystore.file} -storepass ${keystore.pass}

import PEM certification into keystore

keytool -import -noprompt -trustcacerts -alias ${cert.alias} -file ${cert.file} -keystore ${keystore.file} -storepass ${keystore.pass}

Export the certification and chain into pkcs7 format

keytool  -export -noprompt  -alias ${cert.alias} -file ${cert.file}  -keystore ${keystore.file} -storepass ${keystore.pass}

check the der format cert

keytool -v -printcert -file ca.der

import the der format into java truststore

keytool -importcert -alias startssl -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -file ca.der

check the der import

keytool -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit -list | grep startssl

Export the certification to PEM format

keytool  -export -noprompt -rfc  -alias ${cert.alias} -file ${cert.file} -keystore ${keystore.file} -storepass ${keystore.pass}

Delete the certification from the keystore.

keytool  -delete -noprompt -alias ${cert.alias}  -keystore ${keystore.file} 
-storepass ${keystore.pass}

Reference: different certification file

Reference: convert

Reference: openssl pkcs12

Reference: keytool


How SSH works


SSH keys are not like openssl generated keys. ssh private key usually not encrypted, it depends on the filesystem permission to ensure the security. ssh usually does not relay on certifications include public key, certifications are locates in different filesystem.

generate ssh key pairs:

two file will generated, rsakey and rsakey.pub, while the second is the public key.

ssh-keygen -t rsa/dsa/ecdsa/eddsa -f rsakey

we can always use the -y option to see the public key for a given private key.

ssh-keygenb -y -f rsakey