Use OpenSSL to build an HTTPS service by yourself

1. Theoretical knowledge

1.1 What is https

The traditional HTTP protocol communicates in plain text, and does not provide any method of data encryption. It is easy for an attacker in the middle to crack the communication content or pretend to be a server to communicate with a client, and there is a big problem in security.

The HTTPS protocol is a network protocol constructed by HTTP plus TLS/SSL protocols for encrypted transmission and identity authentication. It mainly uses digital certificates, encryption algorithms, asymmetric keys and other technologies to complete Internet data transmission encryption to achieve Internet transmission security protection.

Knowledge about asymmetric encryption and public key and private key will not be repeated, you can understand it yourself.

PS: TLS is a transport layer encryption protocol. Its predecessor was the SSL protocol released by Netscape in 1995. However, in many cases, SSL is still used to refer to TLS/SSL.

1.2 https communication process

Source of the picture below: rookie tutorial

rekhX6.png

1. The client initiates an HTTPS request

The user accesses the https website and connects to port 443 of the server. The request information contains a list of symmetric encryption algorithms supported by the client.

2. Server configuration

A server supporting the HTTPS protocol must have a digital certificate containing its own authentication information and public key, as well as its own private key.

3. Issuing a certificate

The server issues its own digital certificate. This step actually includes selecting the algorithm for two-way communication from the list of symmetric encryption algorithms supported by the client. Because asymmetric encryption is a resource-intensive process, it is generally only used after negotiation. Symmetric encryption algorithm used for communication.

Of course, this step only negotiates the name of the symmetric encryption algorithm in plain text. Later, asymmetric encryption will be used to transmit the secret key for the symmetric encryption algorithm. Due to the effectiveness of asymmetric encryption, this secret key will not be cracked. Symmetrically encrypted transmission will not be cracked.

4. The client verifies the validity of the certificate

The client verifies the validity of the certificate. If there is no problem with the certificate, it generates a random value (symmetric encryption key), and then encrypts the random value with the public key in the certificate.

5. Transmit the secret key for symmetric communication

The random value encrypted with the public key is sent to the server.

6. Server decryption key

After decrypting with its own private key, the server gets the random value (symmetric encryption key) sent by the client.

7. Two-way symmetric encrypted communication

Then use the previously negotiated symmetric encryption algorithm and the secret key for encrypted transmission to communicate.

1.3 SSL certificate issuance process

In the above https communication process, the most critical step is how the client verifies the validity of the certificate issued by the server, because issuing a certificate is a process of clear text transmission, and the certificate may be intercepted, packaged, or tampered during the transmission process. , Then how does the client determine that it has received the certificate of the website it wants to visit?

Since the client is the party that initiates the communication, the two parties do not have a negotiated encryption algorithm, and the server cannot hold the client's public key information, so the certificate cannot be encrypted and sent, so to solve this problem, a third-party trusted organization must be introduced. (CA), if the client trusts it, it can authenticate the server certificate. Specifically, it uses its own private key to sign the server certificate. The signed information is contained in the certificate, so that the client only needs to hold The public key of each CA can decrypt the signature information to verify the validity of the certificate.

rek5nK.png

The figure above is the issuance process of SSL certificate:

  1. The browser needs to remember the major CAs. How does the browser remember CA? When the browser is being developed, each CA gives its root certificate to the browser, then the most important information in the CA root certificate is the public key of the CA organization, in addition to the identification information of the CA organization in order to match the server The authority that signed it is stated in the certificate.

  2. Major websites, such as Alipay, hand over their certificates to the CA. What CA needs to do at this time is to verify the identity of the website through various statutory agencies. If the CA determines that the website is genuine, it needs to sign the website's certificate with its own private key. In addition to its own URL and other identification information, the certificate handed by the website to the CA must also contain the website’s own public key information, because the certificate cannot be moved after signing, and the client needs the server’s public key to encrypt the information. .

  3. Here we return to the previous HTTPS communication process. After the browser gets the certificate, it first verifies the certificate according to the information of the certificate, such as which CA signed it, and combines it with the root certificate list of the CA that the browser has. Specifically, it uses the public key of the corresponding CA to decrypt the signature information in the certificate, and then compares it with the certificate information. If the verification is passed, the validity of the certificate can be determined.

2. Build https service

Native environment: Ubuntu 20.04, openssl 1.1.1h

After understanding the working process of https, we can use the open source secure transport layer cryptographic library openssl to build an experimental https service.

Think about what we need?

  • A server that provides https services needs to have a digital certificate certified by the CA and its own public key and private key (the public key is placed in the certificate)
  • CA certification is chargeable, so we need to build a CA organization by ourselves
  • The self-built CA organization needs to have a root certificate (including a public key) to identify its identity, and a private key used to sign the server certificate
  • An https site that issues its own digital certificate when receiving client access
  • The client needs to hold the root certificate of the CA, so we need to manually import the certificate of the self-built CA

2.1 Self-built CA

First create a myCA directory to store information about self-built CA:

# 创建用户目录下的 https 目录作为实验目录,在其中创建 myCA 目录存放 CA 相关信息
# myCA/signedcerts:存放经 CA 认证的证书副本
# myCA/private:存放 CA 私钥
cd && mkdir -p https/myCA/signedcerts && mkdir https/myCA/private && cd https/myCA

# 创建证书库,这两个文件存放了 CA 每一次颁发证书的记录
echo '01' > serial && touch index.txt

Use any editor you are familiar with to create a new caconfig.cnf file in the myCA directory to configure CA information. The parts that need to be noted are:

  • username: change to your own username

  • default_md: The default digest algorithm when signing the certificate, do not use algorithms below sha2, otherwise the server will fail to start (the old version may not have this restriction)

# My sample caconfig.cnf file.
#
# Default configuration to use when one is not provided on the command line.
#
[ ca ]
default_ca      = local_ca
#
#
# Default location of directories and files needed to generate certificates.
#
[ local_ca ]
dir             = /home/{
    
    username}/https/myCA    # CA 目录
certificate     = $dir/cacert.pem
database        = $dir/index.txt
new_certs_dir   = $dir/signedcerts
private_key     = $dir/private/cakey.pem
serial          = $dir/serial
#      
#
# Default expiration and encryption policies for certificates.
# 认证其他服务器证书设置
default_crl_days        = 365                  # 默认吊销证书列表更新时间
default_days            = 1825                 # 默认证书有效期
default_md              = sha256               # 默认对证书签名时的摘要算法
#      
policy          = local_ca_policy
x509_extensions = local_ca_extensions
#      
#
# Default policy to use when generating server certificates.  The following
# fields must be defined in the server certificate.
#
[ local_ca_policy ]
commonName              = supplied
stateOrProvinceName     = supplied
countryName             = supplied
emailAddress            = supplied
organizationName        = supplied
organizationalUnitName  = supplied
#      
#
# x509 extensions to use when generating server certificates.
#
[ local_ca_extensions ]
basicConstraints        = CA:false
#      
#
# The default root certificate generation policy.
# 生成 CA 根证书设置
[ req ]
default_bits    = 2048                                          # 默认生成证书请求时的秘钥长度
default_keyfile = /home/{
    
    username}/https/myCA/private/cakey.pem # 默认私钥存放位置
default_md      = sha256                                        # 默认证书签名时使用的摘要算法
#     
prompt                  = no
distinguished_name      = root_ca_distinguished_name
x509_extensions         = root_ca_extensions
#
#
# Root Certificate Authority distinguished name.  Change these fields to match
# your local environment!
#
[ root_ca_distinguished_name ]
commonName              = myCA              # CA 机构名
stateOrProvinceName     = JS                # 所在省份
countryName             = CN                # 所在国家(仅限两字符)
emailAddress            = [email protected]    # 邮箱
organizationName        = USTC              # 组织名
organizationalUnitName  = SE                # 单位名
#      
[ root_ca_extensions ]
basicConstraints        = CA:true

Then generate a self-signed CA root certificate and secret key. The CA root certificate is self-signed, that is, it uses its own private key to sign its own certificate, because it is a trusted organization and does not require others to authenticate:

# 设置 openssl 环境变量,以 CA 身份运行接下来的 openssl 命令
export OPENSSL_CONF=~/https/myCA/caconfig.cnf

# 生成 rsa 秘钥对和 pem 格式的 CA 自签名根证书,有效期 1825天
# 需要输入密码,每次对服务器证书进行签名都需要这个密码,最少4位
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825

The above steps generate the root certificate and private key file of the self-built CA organization:

  • myCA/cacert.pem: CA root certificate
  • myCA/private/cakey.pem: CA private key

2.2 Create a server certificate and sign it with CA

First create a server directory to store server-related information:

# 在 myCA 同级目录下创建 server 目录存放服务器相关信息
cd .. && mkdir server && cd server

Use any editor you are familiar with to create a new server.cnf file in the server directory to configure server information:

#
# server.cnf
#

[ req ]
prompt                  = no
distinguished_name      = server_distinguished_name

[ server_distinguished_name ]
commonName              = localhost         # 服务器域名,由于在本地测试,设为 localhost 即可
stateOrProvinceName     = JS                # 服务器所在省份
countryName             = CN                # 服务器所在国家(仅限2字符)
emailAddress            = [email protected]    # 邮箱
organizationName        = USTC              # 组织名
organizationalUnitName  = SE                # 单位名

Generate a secret key pair and an unsigned server certificate file:

# 设置 openssl 环境变量,以服务器身份运行接下来的 openssl 命令
export OPENSSL_CONF=~/https/server/server.cnf

# 生成临时服务器秘钥和未经签名的证书文件
openssl req -newkey rsa:2048 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM

# 将临时私钥转换为未加密状态,也可以直接改名,这样就是加密状态,要输入密码才能启动服务器
openssl rsa < tempkey.pem > server_key.pem

Then use the self-built CA to sign the server certificate:

# 设置 openssl 环境变量,以 CA 身份运行接下来的 openssl 命令
export OPENSSL_CONF=~/https/myCA/caconfig.cnf
# 对服务器证书进行签名
openssl ca -in tempreq.pem -out server_crt.pem

Delete the temporary certificate and private key file:

rm tempkey.pem && rm tempreq.pem

Now, the self-signed server certificate and private key file are generated:

  • server/server_crt.pem: server certificate
  • server/server_key.pem: server private key

2.3 Use https to access the server

Take apache as an example to configure the https service, first install apache:

sudo apt install apache2

Apache is accessed by http by default. We need to configure its https service and enable it. First, cd to the available site directory of apache:

cd /etc/apache2/sites-available/

There is a default ssl site default-ssl.conf. We don’t need to create a new site, just modify the ssl configuration in it and enable it. Modifying this file requires sudo permission. After opening it, find the certificate and private key settings and modify it to yourself The location of the server certificate and private key file:

SSLCertificateFile  /home/{
    
    username}/https/server/server_crt.pem
SSLCertificateKeyFile /home/{
    
    username}/https/server/server_key.pem

Then restart the apache server:

# 启用默认 ssl 站点和 ssl 模块
a2ensite default-ssl.conf
a2enmod ssl
# 重启 apache 服务
systemctl restart apache2

At this step, our https service has been set up. Next, manually import the root certificate of the self-built CA in the browser. Take Chrome as an example, go to Settings -> Privacy and Security -> Security -> Manage Certificates -> Authorized institution, click Import, select the certificate file cacert.pem in the myCA directory, confirm to import, and then you can find our CA root certificate in the list, and look at the certificate information:

rtq3Zt.png

Open the browser to visit: https://localhost:

rt7OQs.png

https access is successful, check the certificate information issued by the server:

rtHRtU.png

Manually set up the https service to complete.

Guess you like

Origin blog.csdn.net/zzh2910/article/details/111090411