Two-way SSL Principles and Practice

principle

Anyone who knows a little bit about the principles of HTTPS knows that TLS provides confidentiality, integrity, authenticity, identity verification...

Whether in dual SP or in daily practice, the familiar thing is confidentiality. Asymmetric negotiation of session keys is used, and the session key is used to encrypt the session.

So where does authenticity and identity verification come in?

Identity verification, also known as authentication, means verifying that you are who you are. It depends on whether it is one-way or two-way.

If it is one-way, it defaults to the client authentication server, which is the minimum requirement in our security design. If you have a public network, you need to use HTTPS. If the certificate is bound to a domain name, access via IP will prompt a box saying "Unsafe". You must trust to continue, or if you use a server certificate issued by an unauthorized/trusted CA, you will also get a pop-up box [Unsafe]. This pop-up box [Unsafe] specifically refers to the process of client verification of the server.

If it is two-way, it is based on the one-way client verifying the server, plus the server verifying the client. Why do this? Just imagine, if our system only allows designated customers to access, then we don’t have Ukey, so this method is very suitable, another whitelist.

Attached picture: In one-way SSL, a certificate issued by an unauthorized/trusted CA, or a certificate issued by an authorized/trusted CA, but the certificate is bound to a domain name, and you must use IP to access it. You must click Advanced and trust the site to access it. This is Equivalent to manual trust/authentication

Insert image description here

By the way, let’s talk about the relationship between SSL and TLS.

There was SSL first, and then slowly iterated on and TLS replaced SSL. After SSL 3.0, TLS 1.0 appeared. TLS 1.0 can be understood as SSL 3.1, but the current secure TLS versions are 1.2 and 1.3. Maybe it’s just habits that we We often talk about two-way SSL, SSL VPN...

nginx

There is nothing much to say about one-way SSL. We mainly want to talk about two-way SSL.

All one-way SSL requires is the server's certificate. Two-way SSL involves the CA certificate and client certificate, and verifying the client certificate. You must separate the two. Understand the principle, and we will implement it.

reference

https://www.jianshu.com/p/59ecf0120048

Execute the generation of CA certificate, server certificate and client certificate under Linux with openssl installed. If you are more proficient, you can directly summarize the commands in the chapter and directly combine the commands to generate CA, client and server certificates into a shell. key generation

Generate self-signed CA certificate

Generate CA's private key file

openssl genrsa -out ca.key 2048

Generate CA certificate, -subj parameter can eliminate the need for interactive

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=CN/O=People's Republic of China/CN=China CA"

View the contents of the CA certificate through openssl tool

openssl x509 -text -noout -in ca.crt

Generate a self-signed server certificate

The -subj parameter is very important. /CN needs to fill in the specific domain name and match the server_name of nginx.

The Chrome browser is very strict about certificates, and the certificate must have a SAN (Subject Alternative Name).
v3_req means to generate a certificate for X.509 v3 and SAN. The two parameters -extfile and -extensions are optional. If there are no these two parameters, the certificate does not have SAN. It is recommended to add these two parameters.

Generate the server's private key file

openssl genrsa -out server.key 2048

Generate the certificate signing file of the server, that is, the file with csr suffix

openssl req -new -key server.key -out server.csr -subj "/C=CN/O=People's Republic of China/CN=example.com"

Use CA to issue server certificates. Please pay attention here. Take a look at the installation path of openssl. My configuration is here /etc/pki/tls/openssl.cnf. If you don’t know where it is, you can search it.

openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extfile <(sed "/\[ v3_req \]/ a\subjectAltName = @alt_names" /etc/pki/tls/openssl.cnf <(printf "\n[alt_names]\nDNS.1=example.com\nDNS.2=www.example.com")) -extensions v3_req

View the contents of the server certificate through the openssl tool

openssl x509 -text -noout -in server.crt

Generate client certificate

The steps for the client certificate are the same as those for the server certificate, but the parameters are different.

Generate the client's private key file

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/C=CN/O=People's Republic of China/CN=Private certificate assigned to Tom"

Use CA to issue client certificate

openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650

Export to p12 format

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

Warm reminder: Press the Enter key without a password.

View the contents of the client certificate through the openssl tool

openssl x509 -text -noout -in client.crt

At this point, the certificates for the CA, server, and client have been generated.

Insert image description here

Configure nginx and enable SSL two-way authentication

nginx can be used with either Linux or Windows. As long as there are key modules [–with-http_ssl_module] in Linux, it will be fine. Since nginx/openresty under Windows comes with all modules, I demonstrated it on Windows.

Insert image description here

7443 one-way, 8443 two-way

Be sure to pay attention to the field ssl_trusted_certificate in both directions. Without this field, an error will still be reported. I always add it.

	server {
    
    
		listen 7443 ssl;
		listen [::]:7443 ssl;
        server_name  example.com www.example.com;

        ssl_certificate E:\\tools\pki\server.crt;
        ssl_certificate_key E:\\tools\pki\server.key;
		
		location / {
    
    
			root html;
			index index.html index.htm;
		}
	}
	
	server {
    
    
		listen 8443 ssl;
		listen [::]:8443 ssl;
        server_name  example.com www.example.com;

        ssl_certificate E:\\tools\pki\server.crt;
        ssl_certificate_key E:\\tools\pki\server.key;

        ssl_verify_client       on;
        ssl_trusted_certificate E:\\tools\pki\ca.crt;
        ssl_client_certificate E:\\tools\pki\ca.crt;

		location / {
    
    
			root html;
			index index.html index.htm;
		}
	}

Use curl to test ssl two-way authentication

curl does not use the client certificate to make requests and will report a 400 error. If the client certificate used is not issued by a specific CA, a 400 error will also be reported.

If you use it without a certificate, you will be charged 400.

curl -k -vo /dev/null https://www.example.com/ --resolve www.example.com:443:127.0.0.1

Use one with certificate

curl -k -vo /dev/null https://www.example.com/ --resolve www.example.com:443:127.0.0.1 --cert ./client.crt --key ./client.key

Test ssl two-way authentication using browser

After starting nginx, as long as there are no errors in the log, you can start verification happily.

unidirectional

Let’s first look at the one-way function of 7443. As mentioned above, the one-way function is only for the client to verify the server, and the server’s certificate is issued by myself. Obviously, a box will pop up, so we need to manually trust it.

Insert image description here

It will show that it is insecure HTTPS. Of course, we can specify the algorithm and TLS version in the configuration.

Insert image description here

Two-way

The main function of two-way is server verification client. This type of scenario is suitable for:

1. Have clear whitelist requirements

2. The IP whitelist cannot meet the requirements. For example, if the IP changes or is in a large range, the firewall cannot be configured. The function of verifying the client through the server can perfectly replace the IP whitelist.

After using two-way authentication, the paired root certificate and client certificate will be generated. The root certificate has just been configured in the nginx server, and the client certificate will be sent to the customers who need to access the web. So how to send the client certificate, out-of-band, etc. It depends on the specific business situation

If there is no client certificate, it is like this

Insert image description here

Double-click to install the p12 file we exported

Insert image description here

If you did not set a password when generating the certificate just now, go to the next step.

Insert image description here

Insert image description here

If you have set a password, you must enter it here, otherwise you will not be able to get through.

Insert image description here

Insert image description here

Insert image description here

Finally, the import was successful.

Insert image description here

Close the browser you just created (in order to clear the cache, I started it incognito)

Check the client certificate in the browser and you can see the one you just installed. Note that this double-click installation is global and can be seen by every browser.

Insert image description here

When you visit again, you will be prompted to select a certificate. After selecting, you can access normally.

Insert image description here

Command summary

Generate self-signed CA certificate

openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=CN/O=People's Republic of China/CN=China CA"

Generate server certificate

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CN/O=People's Republic of China/CN=example.com"
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extfile <(sed "/\[ v3_req \]/ a\subjectAltName = @alt_names" /etc/ssl/openssl.cnf <(printf "\n[alt_names]\nDNS.1=example.com\nDNS.2=www.example.com")) -extensions v3_req

Generate client certificate

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/C=CN/O=People's Republic of China/CN=Private certificate assigned to Tom"
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650

curl command

curl -k -vo /dev/null https://www.example.com/ --resolve www.example.com:443:127.0.0.1
curl -k https://www.example.com/ --resolve www.example.com:443:127.0.0.1
curl -k -vo /dev/null https://www.example.com/ --resolve www.example.com:443:127.0.0.1 --cert ./client.crt --key ./client.key

tomcat

To use keytool to issue certificates

If it is just for testing, there is no need to add a servelet, just configure the server.xml to access it.

reference

https://www.cnblogs.com/juetoushan/articles/7506186.html

Guess you like

Origin blog.csdn.net/zy15667076526/article/details/131571443