Recently, a client's demand is to establish a secure link with the server, which needs to be implemented by SSL two-way authentication. At the beginning, I was confused by
various certificate certifications -_-, it took a long time to sort out the ideas to meet the needs, so write this article to record and share. First introduce what is SSL, and then give the demo source code.
SSL/TSL
brief introduction
SSL is a secure sockets layer, and TLS is the successor of SSL, called transport layer security. It is a security protocol that provides
security and data integrity for network communications. TLS and SSL encrypt the network connection at the transport layer.
For example, if the HTTP protocol is transmitted in plain text, after adding the SSL layer, there is the elegant name HTTPS. Its development has experienced the following periods in turn
SSL1.0: abolished
SSL2.0: RFC6176, has been abolished
SSL3.0: RFC6101, basically abolished
TLS1.0: RFC2246, most of them currently use this method
TLS1.1: RFC4346
TLS1.2: RFC5246, not widely used
TLS1.3: RFC 8446, published in August 2018
certificate
CA:
certificate authority. It is similar to the National Entry-Exit Administration Department, which issues passports to others; it is also similar to the State Administration for Industry and Commerce, which issues business licenses to companies.
It has two main properties:
CA itself is trusted // internationally recognized
Issue certificates to his trusted applicants // Just as with passports, to determine your legal identity, you cannot be a criminal or a rebel. Of course, you need to be protected, and at the same time, the CA can revoke your certificate at any time.
What does the certificate look like? In fact, you have a bunch of CA certificates in your computer. Can you take a look:
360 Browser: Options/Settings-> Advanced Settings -> Privacy and Security -> Manage HTTPS/SSL Certificate -> Certificate Authority
Firefox: Preferences -> Advanced -> Certificate -> View Certificate -> Certificate Authority
Chrome browser: Settings -> Advanced -> Manage certificates -> Authorization center
ubuntu: /etc/ssl/certs
These are all CA certificates!
What is the relationship between CA's certificate ca.crt and SSL Server's certificate server.crt?
The SSL Server generates a private key/public key pair by itself. server.key/server.pub // Private key encryption, public key decryption!
server.pub generates a request file server.req. The request file contains some server information, such as domain name/applicant/public key, etc.
The server submits the request file server.req to the CA. After the CA verifies that it is right, it will use the ca.key and the request file to generate the server.crt.
Since ca.key and ca.crt are a pair, ca.crt can decrypt server.crt.
In practical applications: If the SSL Client wants to verify the SSL server, then the SSL server must pass his certificate server.crt to the client. Then the client uses ca.crt to verify the validity of server.crt. If it is a phishing website, then the CA will not issue him a valid server.crt certificate, so the client will use ca.crt to verify, and it will fail. For example, if the browser acts as a client, you want to visit the legitimate Taobao website https://www.taobao.com, and if you accidentally visit https://wwww.jiataobao.com, then the browser will detect this fake Taobao The illegality of the website reminds users not to continue to visit! In this way, all https access of the client is guaranteed to be safe.
SSL handshake
The SSL/TLS negotiation process can be referred to this article.
Certificate generation
makefile.sh
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the axTLS project nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# Generate the certificates and keys for testing.
#
PROJECT_NAME="TLS Project"
# Generate the openssl configuration files.
cat > ca_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Dodgy Certificate Authority
EOF
cat > server_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME
CN = 192.168.111.100
EOF
cat > client_cert.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
O = $PROJECT_NAME Device Certificate
CN = 192.168.111.101
EOF
mkdir ca
mkdir server
mkdir client
mkdir certDER
# private key generation
openssl genrsa -out ca.key 1024
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024
# cert requests
openssl req -out ca.req -key ca.key -new \
-config ./ca_cert.conf
openssl req -out server.req -key server.key -new \
-config ./server_cert.conf
openssl req -out client.req -key client.key -new \
-config ./client_cert.conf
# generate the actual certs.
openssl x509 -req -in ca.req -out ca.crt \
-sha1 -days 5000 -signkey ca.key
openssl x509 -req -in server.req -out server.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -req -in client.req -out client.crt \
-sha1 -CAcreateserial -days 5000 \
-CA ca.crt -CAkey ca.key
openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -in server.crt -outform DER -out server.der
openssl x509 -in client.crt -outform DER -out client.der
mv ca.crt ca.key ca/
mv server.crt server.key server/
mv client.crt client.key client/
mv ca.der server.der client.der certDER/
rm *.conf
rm *.req
rm *.srl
Make the following modifications and the terminal executes.
Change the IP address in the CN domain to the IP address of your host/device
[Optional] Change the encryption digit 1024 to the encryption digit you need
ca directory: save ca's private key ca.key and certificate ca.crt
certDER directory: save the certificate as a binary file ca.der client.der server.der
client directory: client.crt client.key
server directory: server.crt server.key
achieve
One-way authentication
Source code
server
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True, ssl_context=('server.crt', 'server.key'))
client
import urllib.request
import ssl
if __name__ == '__main__':
CA_FILE = "ca.crt"
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.check_hostname = False
context.load_verify_locations(CA_FILE)
context.verify_mode = ssl.CERT_REQUIRED
try:
request = urllib.request.Request('https://127.0.0.1:5000/')
res = urllib.request.urlopen(request, context=context)
print(res.code)
print(res.read().decode("utf-8"))
except Exception as ex:
print("Found Error in auth phase:%s" % str(ex))
The test of https was originally using a browser, as long as the ca certificate is installed locally, it may be accessed using a browser, but because the authentication process needs to detect and verify the hostname, the self-signed certificate information used in the test is randomly filled in, so even if the certificate is installed to browse The device will also prompt that the link is not secure. Therefore, the client uses the load_verify_locations() method of the ssl module to load the root certificate, and sets check_hostname to False.
The ssl certification mainly uses python's ssl module. If you are unclear, you can also read the official document yourself