0. Introduction
- Before the next article last article we introduced digital signatures, digital certificates and other basic concepts and principles
- This article, we try to generate their own certificate
- References: the TLS Complete Guide (B): OpenSSL Guide
1. OpenSSL Introduction
- OpenSSL is an open source project, which basically consists of three components:
- openssl: multi-purpose command-line tool
- libcrypto: encryption algorithms library
- libssl: encryption module application library that implements ssl and tls
- OpenSSL certificate management is mainly used for secret key, symmetric encryption and asymmetric encryption
1.1 Instruction
- Common instructions comprising: genrsa-, REQ, X509
1.1.1 genrsa
- Mainly used for generating the private key selection algorithm, the encrypted symmetric encryption key using a private key and a secret key of length
- Basic usage: OpenSSL genrsa [args] [numBits]
[args]: args1 generated on whether to use the private key file encryption symmetric encryption algorithm: - des: the DES CBC mode encryption - DES3: 3DES Encryption mode CBC - aes128: the AES128 encryption CBC mode - AES192: CBC mode AES192 encryption - AES256: the CBC mode encryption AES256 args2 symmetric encryption password - passout passwords where the passwords for the symmetric encryption (des, 3des, aes) password (used this parameter is omitted links interactive console password prompt) args3 output file - OUT file: output certificate private file [numbits]: key length, the length of the private key is understood
- Generate a 2048 bits RSA private key, and with des3 encrypted (password is 123456), saved as server.key file: OpenSSL genrsa-des3--passout Pass: 123456 -out server.key 1024
1.1.2 req
- Req basic functions of the two main reasons: to generate a certificate request and generate a self-signed certificate (of course this is not all of its functions, but the two most common)
- Basic usage: OpenSSL REQ [args] outfile
[args] args1 is input file formats: - Inform Arg - Inform DER using the input file format is DER - Inform the PEM using an input file format is the PEM args2 Output file format: - outform Arg - outform DER using the output file format DER - outform output file format using PEM PEM args3 a file to be processed - in inputfilepath args4 be output file - OUT outputfilepath decryption password args5 private key file to be used to request a certificate signature generated - passin passwords args6 for requesting the certificate signature to be generated the private key file - key file encoding format args7 the specified input key - keyform Arg -DER keyform - keyform NET - keyform PEM args8 generate a new certificate request - new new args9 output a X509 certificate format used when signing certificate - X509 args10 use X509 signed certificates valid time -days // -days 3650 valid for 10 years args11 generation RSA private key file a length of bits, for issuing, with -key mutually exclusive, generates a certificate request or a key generated automatically self-signed certificates, then the key generated by the name - Specifies keyout parameters - the newkey RSA: bits args12 provided hASH algorithm - [Digest], specify the hash algorithm specified when the applicant provided when creating a digital signature information request - MD5 -sha1 // high version of the browser began to distrust this algorithm - MD2 - MDC2 -MD4 args13 specified openssl configuration file, not a lot of content easily through the configuration parameters, you can specify the configuration file - config filepath args14 display format txt (for viewing certificate, the private key information) -text
- Generate a certificate request private key using the CSR: OpenSSL the -key server.key-REQ -new -out-in server.csr
- Generate a self-signed certificate using the private CRT: OpenSSL REQ -new -key ca.key-x509--days 3650 -out ca.crt
1.1.3 x509
- x509 certificate display content can be achieved, format conversion, to CSR signatures X.509 certificate management
- Basic usage: OpenSSL X509 [args]
[args] args1 is input file formats: - Inform Arg - Inform DER using the input file format is DER - Inform the PEM using an input file format is the PEM args2 Output file format: - outform Arg - outform DER using the output file format DER - outform PEM use the output file format is PEM args3 is pending X509 certificate file - in inputfilepath args4 be output X509 certificate file - OUT outputfilepath args5 indicates that the input file is a "request for issuance of a certificate file (CSR)", waiting to be issued - REQ args6 signed certificate effective time -days // -days 3650 valid for 10 years args7 designated for requesting a certificate issued by a root CA certificate - CA Arg args8 root CA certificate format (default PEM) - CAform Arg args9 certificate private key file is used to specify the CA certificate signing request - cakey Arg args10 specified root CA private key certificate format (default PEM format) - CAkeyform Arg args11 specified sequence document (serial number file) - CAserial Arg args12 If the serial number file (serial number file) is not specified, it is automatically created - CAcreateserial args12 set HASH algorithm - [Digest], specify the applicant's information when creating a request digitally hash algorithm specified signature - MD5 -sha1 // high version of the browser began to distrust this algorithm - MD2 - MDC2 -md4
- The root CA certificate and private key ca.crt ca.key of the "request issuance of the certificate," issued-in server.csr for generating x509 certificate format: OpenSSL x509 -req -days 3650 CA -IN-in server.csr -CA ca.crt -CAkey .key -CAcreateserial -out serverx509.crt
2. Specific use
2.1 RSA key pair generation
- Genrsa generated using RSA key pair: OpenSSL genrsa -out server.key 2048
2.2 generation identity card applications
- Use req command prior to server.key input, generates a request ID (CSR) File: OpenSSL req -new -nodes the -key server.key -subj "/ the CN = localhost" -out-in server.csr
- CSR's public key extracted from server.key, the domain name is localhost
- If you start https service, use the CRT CSR signed, the client must access the localhost to access to the HTTPS service
- CSR about configuring multiple domain names and IP, will be introduced later
2.3 generate a digital certificate
- Use the specified x509 private server, key signing server.csr, the output of the digital certificate (CRT): OpenSSL x509 -req -sha256 -IN server.csr -signkey server.key -days 365 -out server.crt
- Here uses its own private key to sign CSR
2.4 HTTPS verification
- After generating a certificate, we can write a Golang https service verification certificate just generated
- The server code is as follows:
nil { log.Fatal("ListenAndServe: ", e) } //if e := http.ListenAndServe("0.0.0.0:5200", nil); e != nil { // log.Fatal("ListenAndServe: ", e) //} }
- Client code as follows:
package main import ( "crypto/tls" "crypto/x509" "io" "io/ioutil" "log" "net/http" "os" ) func loadCA(caFile string) *x509.CertPool { pool := x509.NewCertPool() ca, err := ioutil.ReadFile(caFile) if err != nil { log.Fatal("ReadFile: ", err) } pool.AppendCertsFromPEM(ca) return pool } func main() { //c := &http.Client{ // Transport: &http.Transport{ // TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // }} c := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: loadCA("/home/ao/Documents/certs/review/server.crt")}, }} resp, err := c.Get("https://localhost:5200") if err != nil { log.Fatal("http.Client.Get: ", err) } defer resp.Body.Close() io.Copy(os.Stdout, resp.Body) }
- Start the server: Go RUN server.go
- Start the client: Go RUN client.go
$ go run client.go
hello, world!
- Client request to change the domain name is 127.0.0.1, the client results are as follows:
$ go run client.go 2019/09/30 15:11:41 http.Client.Get: Get https://127.0.0.1:5200: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs exit status 1
- The server output is as follows:
2019/09/30 15:11:41 http: TLS handshake error from 127.0.0.1:33596: remote error: tls: bad certificate
- If the client 127.0.0.1 remain unchanged, change http.Transport of TLSClientConfig when configured as insecure, you can return to normal:
$ go run client.go 2019/09/30 15:11:41 http.Client.Get: Get https://127.0.0.1:5200: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs exit status 1
- At this time, just like the browser maintain the trust a Web site certificate, continue to choose to view the action is the same
2.5 Configuring IP domain name
- Above we use localhost, as CSR in the domain name, the domain name must lead to a request
- If we use the local IP as the domain name it: OpenSSL REQ -nodes -new -key server.key -subj "/CN=127.0.0.1" -out server.csr
- At this time the client requests https://127.0.0.1:5200 Returns:
$ go run client.go 2019/09/30 15:19:24 http.Client.Get: Get https://127.0.0.1:5200: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs exit status 1
- When enable insecure normal return
- Described here, we can not simply -subj "/ CN = [IP]" implemented by CSR contains the domain name
- Rebuild CSR and CRT
$ openssl genrsa -out server.key 2048 $ echo subjectAltName = IP:127.0.0.1 > extfile.cnf $ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -extfile extfile.cnf -out server.crt
- When it re-test found that the request 127.0.0.1
2.6 does not use a self-signed certificate
- We use the above-mentioned self-signed certificate, let's try to simulate a CA-signed certificate:
- First generation CA secret key and self-signed certificate, the middle does not generate CSR:
$ openssl genrsa -out ca.key 2048 $ openssl req -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj "/CN=localhost.ca.com"
- Generate private keys, certificates, and the CA signature:
$ openssl genrsa -out server.key 2048 $ openssl req -new -key server.key -subj "/CN=127.0.0.1" -out server.csr $ openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile extfile.cnf
- After testing, correct
2.7 CSR configure multiple domain names and IP
- -Subj configuration mentioned above specify only a single domain is the domain name or IP
- Here are some multi-domain configuration CSR
- A new configuration file:
[req] distinguished_name = req_distinguished_name req_extensions = v3_req [req_distinguished_name] countryName = CN countryName_default = CN stateOrProvinceName = Beijing stateOrProvinceName_default = Beijing localityName = Beijing localityName_default = Beijing organizationName = WangAo organizationName_default = WangAo organizationalUnitName = Dev organizationalUnitName_default = Dev commonName = test.openssl.com commonName_default = test.openssl.com commonName_max = 64 [v3_req] basicConstraints = CA:TRUE subjectAltName = @alt_names [alt_names] DNS.1 = test.openssl.com IP.1 = 127.0.0.1 IP.2 = 10.0.2.15
- We developed a two domain name service IP address
- The following use of CA before re-signed digital certificate:
$ openssl genrsa -out server.key 2048 $ openssl req -nodes -new -key server.key -out server.csr -subj "/CN=test.openssl.com" $ openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extensions v3_req -extfile openssl.cnf
- Developed -extensions and -extfile when signing CA digital certificate
- Respectively 127.0.0.1,10.0.2.15 and test.openssl.com request, can be successfully
3. Summary
- In this part describes the preparation of basic use OpenSSL to generate and verify digital certificates and certificate programs way
- Welcome all criticism