Golang (eleven) TLS-related knowledge (b) OpenSSL to generate a certificate

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)
    //}
}
View Code
  • 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)
}
View Code
  • 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

3. References

Guess you like

Origin www.cnblogs.com/wangao1236/p/11609429.html