Abstract:Generally, there is plaintext transmission of request information in HTTP, which is easy to be intercepted. The integrity of the data is not checked and is easy to be tampered with; No verification of the identity of the other side, there is a risk of impersonation. Faced with these problems, how to break?

This article was shared from the Huawei Cloud Community “how to implement HTTPS using Python + Flask”, the original author: SNHer.

Why HTTPS

General HTTP has the following problems: the request information plaintext transmission, easy to be intercepted; The integrity of the data is not checked and is easy to be tampered with; No verification of the identity of the other side, there is a risk of impersonation.

What are the advantages of HTTPS?

Use HTTPS to authenticate users and servers to ensure data is sent to the correct client and server.

2. HTTPS is a network protocol built by SSL+HTTP protocol that can be used for encryption transmission and identity authentication. It is more secure than HTTP protocol and can prevent data from being stolen and changed in the process of transmission to ensure the integrity of data.

HTTPS is the most secure solution under the current architecture, and while it is not absolutely secure, it significantly increases the cost of man-in-the-middle attacks.

What is a certificate in HTTPS



CA: A Certificate Authority, similar to the National Entry-Exit Administration, issues passports to people. 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 and internationally recognized;
  • Issue certificates to his trusted applicants. Just like with a passport, it’s important to make sure you’re legal. You can’t be a criminal or an insurgent. Of course, you need to be charged protection money, and the CA can revoke your certificate at any time.

What is the relationship between CA’s certificate and SSL Server’s certificate?

  • The SSL Server itself generates a private/public key pair, server.key/server.pub. Server.pub generates a request file, server.req. The request file contains some information about the server, such as the domain name/applicant/public key.
  • The server sends the request file server.req to the CA, and after the CA verifies the request file, it will encrypt the server.crt with the CA. Key and the CA.
  • In practice: If the SSL Client wants to validate the SSL Server. Then the SSL server must pass its certificate server. CRT to the client. The client then uses ca. CRT to verify the validity of the server. CRT. If it is a phishing site, the CA will not issue it with a valid server. CRT certificate, so the client will fail to verify it with the CA.

3. Generate certificates and keys

A shell script

#! /bin/bash PROJECT_NAME="https 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 Certificate Authority EOF cat > server_cert.conf << EOF [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] O = $PROJECT_NAME CN = EOF cat > client_cert.conf << EOF [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] O = $PROJECT_NAME Device Certificate CN = EOF mkdir ca Mkdir server mkdir client # generate the private key openssl genrsa - out ca. The key 1024 openssl genrsa - out server. The key 1024 openssl genrsa - out Create a certificate request file based on the private key. Enter some meta information about the certificate: Openssl req-out server.req-key server.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 # Config the private key and the request file. Openssl x509-req-in server.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 mv ca.crt ca.key ca/ mv server.crt server.key server/ mv client.crt client.key client/ rm *.conf rm *.req rm *.srl

Interpretation of some commands

Openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [numbits] -out filename: Saves the generated private key to a filename file, or standard output if no output file is specified. -numbits: Specifies the length of the private key to be generated. Default is 1024. This item must be the last argument on the command line. - des | - des3 | - idea: specify encryption private key file with the algorithm, so that every time the private key file is used to input password, too much trouble so rarely used. -passout args: Passout the format of the password when encrypting the private key file. If it is not specified when encrypting the private key file, it is prompted for the password. Openssl req-out ca.req-key ca.key-new-config./ca_cert.conf Main command option: -new: Specifies an existing secret key file to generate a secret key request, which only works with the Create Certificate request option -new. Openssl x509-req-in ca. Req-out ca. CRT-SHA1-DAYS 5000 - signKey ca. Key openssl x509-req-in ca. Req-out ca. CRT-SHA1-DAYS 5000 - signKey ca The x509 command has functions such as exporting certificate information, signing certificate request files, generating self-signed certificates, converting certificate formats, etc. -in filename: Specifies the certificate input file. If the "-req" option is also specified, it means that the input file is the certificate request file. Then "-signkey" is used to provide the private key used in self-signing. -out filename: Specifies the output file -days: Specifies how long the certificate is valid. Default is 30 days

Install Flask

You need to install Python’s OpenSSL library, using PIP

pip install pyOpenSSL

5. HTTPS one-way authentication handshake process



Python implementation

Server side:

from flask import Flask app = Flask(__name__) @app.route('/login') def hello_world(): return 'Hello World! "If __name__ = =" __main__ ': app. The run (host = "0.0.0.0", the port = 8091, ssl_context = (' server. The CRT,' server. The 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. The request (' https://127.0.0.1:8091/login ') 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))

6. HTTPS two-way authentication handshake process

Python implementation

Client:

from flask import Flask, request, Response import json app = Flask(__name__) @app.route("/login") def hello(): return "Hello World!" @app.route('/login1', methods=['POST']) def login(): username = request.form.get("username") password = request.form.get("password") login_config = { "name": "pwd1" } if username in login_config.keys(): if password == login_config[username]: return Response(json.dumps(True), status=200, mimetype='application/json') return Response(json.dumps(False), status=200, mimetype='application/json') if __name__ == "__main__": App. The run (host = "0.0.0.0", the port = 8091, ssl_context = (' server/server. The CRT ', 'server/server. The 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 dict = { "username": "name", "password": "pwd1", } data = urllib.parse.urlencode(dict).encode('utf-8') try: Request = urllib. Request. The request (' https://127.0.0.1:8091/login ') 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)) try: Request = urllib. Request. The request (' https://127.0.0.1:8091/login1 ', data = data, method='POST') 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))

Refer to the link

Openssl command (1): OpenSSL req command

OpenSSL Introduction – Directive X509

OpenSSL x509 command: OpenSSL x509 command

The OpenSSL command – as pkcs12

Ten minutes to understand HTTP and HTTPS protocols?

HTTPS one-way authentication and two-way authentication

Python’s implementation of SSL/TLS authentication

Click on the attention, the first time to understand Huawei cloud fresh technology ~