Due to the “plaintext” nature of HTTP, the whole transmission process is completely transparent. Anyone can intercept, modify, or forge the request/response packets on the link, and the data is not credible. Thus, the following problems arise:

  1. The message was intercepted
  2. Information was tampered with
  3. Information hijacked

What is the HTTPS

The HTTPS protocol basically relies on THE TLS/SSL protocol, and the implementation of TLS/SSL depends on three basic algorithms

  • Hash function The hash function verifies the integrity of the information
  • Symmetric encryption The symmetric encryption algorithm uses negotiated key pairs to encrypt data
  • Asymmetric encryption Asymmetric encryption implements identity authentication and key negotiation

The relationship between the SSL/TLS

SSL, also known as Secure Sockets Layer (SSL), is at Layer 5 (session Layer) in the OSI model. It was invented by Netscape in 1994 and has two versions, V2 and V3. V1 was never made public due to serious flaws. SSL proved itself to be such a good secure communication protocol by the time it made its way to V3 that the Internet Engineering Group IETF officially standardized it in 1999 by changing its name to TLS (Transport Layer Security), starting with version 1.0. So TLS1.0 is actually SSLv3.1.

Now that you understand the basic concepts, let’s take a look at how HTTPS solves these problems.

Encrypted information

We know that HTTP is sent in plain text, so it’s easy to think about encrypting the plain text, encrypting the text and decrypting it on the server. So no one knows what’s in it.

A common encryption algorithm is called RSA

const crypto = require('crypto');
function encrypt(data, key, iv) {
    let decipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    decipher.update(data);
    return decipher.final('hex');
}

function decrypt(data, key, iv) {
    let decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
    decipher.update(data, 'hex');
    return decipher.final('utf8');
}

let key = '1234567890123456';
let iv = '1234567890123456';
let data = "hello";
let encrypted = encrypt(data, key, iv);
console.log("Data encrypted :", encrypted);
let decrypted = decrypt(encrypted, key, iv);
console.log("After data decryption :", decrypted);
Copy the code

We found that the stack encryption has a secret key that can be used for encryption and decryption.

** But how do servers and clients share a secret key? There is no way to securely exchange keys on the Internet. 支那

Use asymmetric encryption with a secret key

let {
  generateKeyPairSync,
  privateEncrypt,
  publicDecrypt
} = require('crypto');
let rsa = generateKeyPairSync('rsa', {
  modulusLength: 1024.publicKeyEncoding: {
    type: 'spki'.format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8'.format: 'pem'.cipher: 'aes-256-cbc'.passphrase: 'server_passphrase'}});let message = 'hello';
console.log(rsa)
let enc_by_prv = privateEncrypt({
  key: rsa.privateKey,
  passphrase: 'server_passphrase'
}, Buffer.from(message, 'utf8'));
console.log('encrypted by private key: ' + enc_by_prv.toString('hex'));


let dec_by_pub = publicDecrypt(rsa.publicKey, enc_by_prv);
console.log('decrypted by public key: ' + dec_by_pub.toString('utf8'));
Copy the code

In this way we can secure the ownership of the secret key, hackers can not know our secret key, can not know what our information, this can be done to prevent eavesdropping information.

Although the data can be prevented from being wiretapped, it is still very likely to be tampered with;

For example: the browser sends I love you after waai encryption; The browser sends I don't love you after encryption. Hackers intercept the data, observe and analyze it, and discover patterns. When the browser sends I love you to the server to try, directly speak ciphertext tamper into WBAI; This distorts the meaning of your message;Copy the code

A digital signature

A digital signature would prevent the information from being tampered with. (Digital signatures use the digest algorithm)

We use the private key of the browser, digest the message, make a signature, and send the message to the server; The server checks the signature and finds that it is the client, then continues to execute the logic. This will prevent the information from being tampered with.

let { generateKeyPairSync, createSign, createVerify } = require('crypto');
let passphrase = 'zhufeng';
let rsa = generateKeyPairSync('rsa', {
    modulusLength: 1024.publicKeyEncoding: {
        type: 'spki'.format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8'.format: 'pem'.cipher: 'aes-256-cbc',
        passphrase
    }
});
let content = 'hello';
const sign = getSign(content, rsa.privateKey, passphrase);
let serverCertIsValid = verifySign(content, sign, rsa.publicKey);
console.log('serverCertIsValid', serverCertIsValid);
function getSign(content, privateKey, passphrase) {
    var sign = createSign('RSA-SHA256');
    sign.update(content);
    return sign.sign({ key: privateKey, format: 'pem', passphrase }, 'hex');
}
function verifySign(content, sign, publicKey) {
    var verify = createVerify('RSA-SHA256');
    verify.update(content);
    return verify.verify(publicKey, sign, 'hex');
}
Copy the code

Phishing site

Through the above way, hackers can not do wiretapping and tampering, but can do interception, pretend to be a server (commonly known as phishing website); I’ve heard of this way to trick users; So how do you prevent this?

A digital certificate issued by an authority certifying that your site is a good one.

let { generateKeyPairSync, createSign, createVerify, createHash } = require('crypto');
let passphrase = 'zhufeng';
let rsa = generateKeyPairSync('rsa', {
    modulusLength: 1024.publicKeyEncoding: {
        type: 'spki'.format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8'.format: 'pem'.cipher: 'aes-256-cbc',
        passphrase
    }
});
const info = {
    domain: "http://127.0.0.1:8080".publicKey: rsa.publicKey
};
const hash = createHash('sha256').update(JSON.stringify(info)).digest('hex');
const sign = getSign(hash, rsa.privateKey, passphrase);
const cert = { info, sign };

let certIsValid = verifySign(hash, cert.sign, rsa.publicKey);
console.log('certIsValid', certIsValid);

function getSign(content, privateKey, passphrase) {
    var sign = createSign('RSA-SHA256');
    sign.update(content);
    return sign.sign({ key: privateKey, format: 'pem', passphrase }, 'hex');
}
function verifySign(content, sign, publicKey) {
    var verify = createVerify('RSA-SHA256');
    verify.update(content);
    return verify.verify(publicKey, sign, 'hex');
}
Copy the code

Through the above process, information hijacking by bad guys can be successfully avoided.

Conclusion:

That’s what HTTPS does if it keeps us safe.