preface

Recently, I have been working on a small personal project, in which I have used a variety of front-end and back-end technologies. While practicing and reviewing my own technologies, I have also strengthened my understanding of working principles. Digital signatures and information encryption are used for user login, online transactions, and information communication. Different encryption algorithms are used in different scenarios. Of course, you can also use the highly secure blockchain technology. In the design of the website login technology, considering the user password and other sensitive information encryption preservation, and choose the right password can get twice the result with half the effort. The author had a deep communication with Qiu Cheng, who works in alitao department in the studio, from which we gained the boss’s deep understanding of encryption and decryption technology and felt the depth, breadth and thickness of its technology. After listening to and reading a lot of literature and blogs, I got this article after my own summary and digestion. Meanwhile, I am grateful to my front guide for his help and clarification for me.

1. Encryption and decryption

Before we dive into encryption and decryption, let’s review and understand what encryption and decryption are and why they are needed.

Encryption: Encryption is the plaintext data or files that do not want to be directly seen by some or some algorithm processing, so that others can not directly read and obtain information of a piece of code, and this code is “ciphertext”, so as to achieve the purpose of data protection.

Decryption: Decryption is the reverse process of encryption. That is, the encrypted data processed by the encryption algorithm is restored to the original plaintext data using the corresponding decryption algorithm, so that you can obtain and read the encrypted data.

By reading the definition of encryption and decryption, I believe that the intelligent reader has a general understanding of their role, the author here through the image of the metaphor to illustrate the concept. In the following comparison picture, we can see that the encryption algorithm is used to encrypt the original plaintext data to obtain the ciphertext, so as to achieve the function of confidentiality. To obtain the data in the ciphertext, we need to use the corresponding decryption algorithm to obtain. Similarly, in our life, if a room without a lock is not very insecure, then need to install a lock to ensure the safety of property (maybe you put money in the bank), then the owner of the house through the key to unlock the house, lock out of the house and other operations. And the key corresponding is the key, lock and lock corresponding respectively is the lock and lock operation, of course, this is the most simple and the most common encryption and decryption of the explanation, to know that the lock and password can be cracked through violence, that is, to prevent the gentleman does not prevent the villain.

2. Symmetric encryption and asymmetric encryption

The encryption and decryption model introduced above is the simplest technology, and criminals can decrypt your key after obtaining it, while symmetric encryption is used for encryption and decryption with a single and same key. (PS: Baidu Baike shows that the key, public key and private key are all read as yue, and the key is read as Yao.)

Symmetric encryption: In the symmetric encryption algorithm, the sender and the receiver use the same key to encrypt and decrypt data during encryption and decryption. Both parties need to agree that they use the same encryption and decryption scheme — the same key.

Symmetric encryption is used when the client and server communicate with each other over HTTP. If only one secret key is used, it is easy to crack. If a different key is used each time, the management and transmission cost of mass key will be relatively high.

Asymmetric encryption: An asymmetric encryption algorithm uses a combination of a public key and a private key to encrypt and decrypt data. The public key is the shared key, and the private key is the private key. Because encryption and decryption use two different keys, it is called asymmetric encryption — different keys. Asymmetric encryption encryption and decryption mode: Use the corresponding private key to decrypt data encrypted with a public key. The data encrypted with the private key is decrypted using the corresponding public key.

When the client and server communicate over HTTPS, both symmetric encryption and asymmetric encryption are used. Asymmetric encryption, browser requests to the server, the server receives a request, the public transport to the browser, and then in the communication, the browser to send data to the server, data encrypted with the public key first, then sent to the server, the server receives, reoccupy corresponding private key to decrypt, This ensures the security of browser-server data. Because the browser sends the data to the server, only the server has the private key to decrypt it.

3. The MD5 algorithm

There are many common encryption algorithms in front and back end development, among which symmetric encryption algorithms mainly include DES, 3DES and AES, common asymmetric algorithms mainly include RSA and DSA, and hash algorithms mainly include SHA-1 and MD5.

3.1 Security Level of the Encryption Algorithm

Security level Cracking algorithm complexity algorithm
weak O(2 40) DES, MD5
traditional O(2 64) RC4, SHA-1
The benchmark O(2 80) 3DES
standard O(2 128) AES-128, SHA-256
higher O(2 192) AES-192, SHA-384
Ultra high O(2 256) AES-256, SHA-512

3.2 the MD5 algorithm

Message Digest Algorithm 5: Message Digest Algorithm 5. MD5 is a hash function widely used in computer security field to ensure the integrity of information transmission. It is a one-way encryption algorithm and an irreversible encryption method. MD5 is a digest algorithm, so it is not strictly an encryption algorithm. MD5 processes input information in 512-bit packets, and each packet is divided into 16 32-bit packets. After a series of processing, the output of the algorithm consists of four 32-bit packets, which are cascaded to generate a 128-bit hash value. In a nutshell, it’s just hashing. In blockchain, tamper-proof is possible because of cumulative hash, which uses the irreversible nature of such algorithms.

The characteristics of

The main characteristics of MD5 are: fixed length, simple calculation, anti-modification and strong anti-collision.

  • Fixed length:MD5The encrypted value has a fixed length of 128 bits and is represented by 32 hexadecimal digits.
  • Simple calculation:MD5Encryption is used by hashing algorithm (hash algorithm), carried outMD5It is easy to calculate and fast to encrypt.
  • Resistance to change:MD5The value is a hexadecimal number represented when modifying 1 byte of the original dataMD5The values are very different, and any change is noticeable.
  • Strong collision resistance:PengZhuangXingIt is throughMD5Encryption algorithmMD5Value encrypted with other plaintextMD5The probability of having the same value.Strong collision resistanceMeaning it is very difficult to find two different messages with the same hash valueMD5Probability is low.

The principle of

  • Fill in the data: First, the length of the input data (bit) for 512, if the result is not equal to 448, it is filledbitThe remainder is 448. Fill the first bit with 1 and the remaining N bitsbitAdd 0, so the data length is 512*N+448.
  • Record data length: Next, store the length of the data before filling as 64 bits, and append it to the length of the data after filling, so that the length of the data is N x 512+448+64=(N+1) x 512 bits.
  • Load standard magic numbers: In fact, the MD5 value of 128 bits is calculated as a standard magic number every 32 bits, and four standard magic numbers can be obtainedA=01234567,B=89ABCDEF,C=FEDCBA98As well asD=76543210.
  • Four-wheel operation: The data length after the above data processing is (N+1) /512, according to each 512 bits (64 bytes) as a block, a total of N+1 cycles, and the block is subdivided into 16 groups, the length of each group is 32 bits (4 bytes), these 16 groups are a round, a total of 4 cycles, namely 64 cycles. In general we need(N + 1)Each main loop contains 64 sub-loops to constantly change the variables A,B,C,D to finally get the MD5 value of the data.

The source code

We can see the source information after the installation of MD5 package, the source code depends on the crypt module.

(function(){
  var crypt = require('crypt'),
      utf8 = require('charenc').utf8,
      isBuffer = require('is-buffer'),
      bin = require('charenc').bin,

  // The core
  md5 = function (message, options) {
    // Convert to byte array
    if (message.constructor == String)
      if (options && options.encoding === 'binary')
        message = bin.stringToBytes(message);
      else
        message = utf8.stringToBytes(message);
    else if (isBuffer(message))
      message = Array.prototype.slice.call(message, 0);
    else if (!Array.isArray(message) && message.constructor ! = =Uint8Array)
      message = message.toString();
    // else, assume byte array already
    
    // m converts btyes to data information
    var m = crypt.bytesToWords(message),
        l = message.length * 8.// The length of the data message
        // Standard magic number
        a =  1732584193,
        b = -271733879,
        c = -1732584194,
        d =  271733878;

    // Swap bytes
    for (var i = 0; i < m.length; i++) {
      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
    }

    // add zero
    m[l >>> 5] | =0x80 << (l % 32);
    m[(((l + 64) > > >9) < <4) + 14] = l;

    // Method shortcuts
    var FF = md5._ff,
        GG = md5._gg,
        HH = md5._hh,
        II = md5._ii;
    /* Four round loop: 512 bits (64 bytes) */ for each packet
    for (var i = 0; i < m.length; i += 16) {

      var aa = a,
          bb = b,
          cc = c,
          dd = d;
      
      // The first loop
      a = FF(a, b, c, d, m[i+ 0].7, -680876936);/ / 1
      d = FF(d, a, b, c, m[i+ 1].12, -389564586);/ / 2
      c = FF(c, d, a, b, m[i+ 2].17.606105819);/ / 3
      b = FF(b, c, d, a, m[i+ 3].22, -1044525330);/ / 4
      a = FF(a, b, c, d, m[i+ 4].7, -176418897);/ / 5
      d = FF(d, a, b, c, m[i+ 5].12.1200080426);/ / 6
      c = FF(c, d, a, b, m[i+ 6].17, -1473231341);/ / 7
      b = FF(b, c, d, a, m[i+ 7].22, -45705983);/ / 8
      a = FF(a, b, c, d, m[i+ 8].7.1770035416);/ / 9
      d = FF(d, a, b, c, m[i+ 9].12, -1958414417);/ / 10
      c = FF(c, d, a, b, m[i+10].17, -42063);/ / 11
      b = FF(b, c, d, a, m[i+11].22, -1990404162);/ / 12
      a = FF(a, b, c, d, m[i+12].7.1804603682);/ / 13
      d = FF(d, a, b, c, m[i+13].12, -40341101);/ / 14
      c = FF(c, d, a, b, m[i+14].17, -1502002290);/ / 15
      b = FF(b, c, d, a, m[i+15].22.1236535329);/ / 16
      
      // The second loop
      a = GG(a, b, c, d, m[i+ 1].5, -165796510);
      d = GG(d, a, b, c, m[i+ 6].9, -1069501632);
      c = GG(c, d, a, b, m[i+11].14.643717713);
      b = GG(b, c, d, a, m[i+ 0].20, -373897302);
      a = GG(a, b, c, d, m[i+ 5].5, -701558691);
      d = GG(d, a, b, c, m[i+10].9.38016083);
      c = GG(c, d, a, b, m[i+15].14, -660478335);
      b = GG(b, c, d, a, m[i+ 4].20, -405537848);
      a = GG(a, b, c, d, m[i+ 9].5.568446438);
      d = GG(d, a, b, c, m[i+14].9, -1019803690);
      c = GG(c, d, a, b, m[i+ 3].14, -187363961);
      b = GG(b, c, d, a, m[i+ 8].20.1163531501);
      a = GG(a, b, c, d, m[i+13].5, -1444681467);
      d = GG(d, a, b, c, m[i+ 2].9, -51403784);
      c = GG(c, d, a, b, m[i+ 7].14.1735328473);
      b = GG(b, c, d, a, m[i+12].20, -1926607734);
      
      // The third loop
      a = HH(a, b, c, d, m[i+ 5].4, -378558);
      d = HH(d, a, b, c, m[i+ 8].11, -2022574463);
      c = HH(c, d, a, b, m[i+11].16.1839030562);
      b = HH(b, c, d, a, m[i+14].23, -35309556);
      a = HH(a, b, c, d, m[i+ 1].4, -1530992060);
      d = HH(d, a, b, c, m[i+ 4].11.1272893353);
      c = HH(c, d, a, b, m[i+ 7].16, -155497632);
      b = HH(b, c, d, a, m[i+10].23, -1094730640);
      a = HH(a, b, c, d, m[i+13].4.681279174);
      d = HH(d, a, b, c, m[i+ 0].11, -358537222);
      c = HH(c, d, a, b, m[i+ 3].16, -722521979);
      b = HH(b, c, d, a, m[i+ 6].23.76029189);
      a = HH(a, b, c, d, m[i+ 9].4, -640364487);
      d = HH(d, a, b, c, m[i+12].11, -421815835);
      c = HH(c, d, a, b, m[i+15].16.530742520);
      b = HH(b, c, d, a, m[i+ 2].23, -995338651);
      
      // Round 4
      a = II(a, b, c, d, m[i+ 0].6, -198630844);
      d = II(d, a, b, c, m[i+ 7].10.1126891415);
      c = II(c, d, a, b, m[i+14].15, -1416354905);
      b = II(b, c, d, a, m[i+ 5].21, -57434055);
      a = II(a, b, c, d, m[i+12].6.1700485571);
      d = II(d, a, b, c, m[i+ 3].10, -1894986606);
      c = II(c, d, a, b, m[i+10].15, -1051523);
      b = II(b, c, d, a, m[i+ 1].21, -2054922799);
      a = II(a, b, c, d, m[i+ 8].6.1873313359);
      d = II(d, a, b, c, m[i+15].10, -30611744);
      c = II(c, d, a, b, m[i+ 6].15, -1560198380);
      b = II(b, c, d, a, m[i+13].21.1309151649);
      a = II(a, b, c, d, m[i+ 4].6, -145523070);
      d = II(d, a, b, c, m[i+11].10, -1120210379);
      c = II(c, d, a, b, m[i+ 2].15.718787259);
      b = II(b, c, d, a, m[i+ 9].21, -343485551);
      
      /* add to the previous calculation */
      a = (a + aa) >>> 0;
      b = (b + bb) >>> 0;
      c = (c + cc) >>> 0;
      d = (d + dd) >>> 0;
    }

    return crypt.endian([a, b, c, d]);
  };

  // Auxiliary functions -- linear functions
  md5._ff  = function (a, b, c, d, x, s, t) {
    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._gg  = function (a, b, c, d, x, s, t) {
    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._hh  = function (a, b, c, d, x, s, t) {
    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._ii  = function (a, b, c, d, x, s, t) {
    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  // Package private block sizes
  md5._blocksize = 16;
  md5._digestsize = 16;
  
  // Export package files
  module.exports = function (message, options) {
    if (message === undefined || message === null)
      throw new Error('Illegal argument ' + message);

    var digestbytes = crypt.wordsToBytes(md5(message, options));
    returnoptions && options.asBytes ? digestbytes : options && options.asString ? bin.bytesToString(digestbytes) : crypt.bytesToHex(digestbytes); }; }) ();Copy the code

use

Enter NPM install MD5 in the terminal. Specific documents can be viewed at www.npmjs.com/package/md5.

$ npm install md5
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node@1.0.0 No description
npm WARN node@1.0.0 No repository field.

+ md5@2.3.0
added 4 packages from 4 contributors and audited 4 packages in 2.457s
found 0 vulnerabilities
Copy the code

Use MD5 encryption in Node.

const md5 = require("md5");
console.log(md5("Chuan"));//3db9c89fbb99eca13513b823ac09ec5b
Copy the code

In fact, the crypto module encapsulation in Node provides many encryption functions, including the hash, HMAC, encryption, decryption, signature, and verification functions of OpenSSL. Use the crypto module to view the supported hash functions: crypto.gethashes ()

[ 'RSA-MD4'.'RSA-MD5'.'RSA-MDC2'.'RSA-RIPEMD160'.'RSA-SHA1'.'RSA-SHA1-2'.'RSA-SHA224'.'RSA-SHA256'.'RSA-SHA384'.'RSA-SHA512'.'blake2b512'.'blake2s256'.'md4'.'md4WithRSAEncryption'.'md5'.'md5-sha1'.'md5WithRSAEncryption'.'mdc2'.'mdc2WithRSA'.'ripemd'.'ripemd160'.'ripemd160WithRSA'.'rmd160'.'sha1'.'sha1WithRSAEncryption'.'sha224'.'sha224WithRSAEncryption'.'sha256'.'sha256WithRSAEncryption'.'sha384'.'sha384WithRSAEncryption'.'sha512'.'sha512WithRSAEncryption'.'ssl3-md5'.'ssl3-sha1'.'whirlpool' ]
Copy the code

Use crypto module for MD5 encryption.

const crypto = require("crypto");
const md5 = crypto.createHash("md5");

// Hash the plaintext password
const passToHash = password= >md5.update(password).digest("hex");

const password = "yichuan";
console.log(passToHash(password));
//9c1719293e8a445279f4bff5c954fda0
// 
Copy the code

The password can be obtained by reverse query at www.cmd5.com/, which is not secure enough.

Add salt to encrypt

We talked about the anti-collision property of MD5 in the past, but the strong has its own strong hand. As long as we know that your encryption method is the original MD5, we can query and crack through the rule. It is not safe, gie gie. To improve its security and uniqueness, we can add salt to the encryption, which is actually adding random values to the hash of the password to enhance the security of the data. Salt encryption can effectively protect against cryptographic attack media such as dictionary attack and rainbow table attack.

Custom salt value

const crypto = require("crypto");
const md5 = crypto.createHash("md5");
// Add normal salt (custom salt)
const salt = "YiChuanIsAHandsome";
const passToSaltHash = password= >md5.update(password+salt).digest("hex");
const password = "yichuan";

console.log(passToSaltHash(password));
// e56fb85a6fb79120b2db837a46a6aba3
Copy the code

Random salt value

const crypto = require("crypto");
const md5 = crypto.createHash("md5");
// Customize the salt value
const passToRandomSaltHash = (password) = >{
  // Generate random salt values of 32 bits length
  const salt = crypto.randomBytes(32);
  // Record a readable string version of the salt value
  console.log("salt: " + salt.toString("hex"));//a5bb712bf9de2b902be996c3317344185aed4bfbe78f68382429ef4c6aadac8d
  return md5.update(password+salt).digest("hex")}const password = "yichuan";
console.log(passToRandomSaltHash(password));//ff439334dec47045b9be413c84abfe82
Copy the code

4. To summarize

In short, md5 is called the fixed-length string algorithm. Given a string of any length, it can be used to generate a unique and irreversible string. However, such hashes still have some collision probability, that is, it is extremely unlikely that different strings will produce the same fixed length string, but the probability is very small. In the actual application development, the front-end page to get the password, in order to prevent him from entering a variety of symbols, can all be converted into ASCII code, and then, on the basis of all the specified numbers, to get a string of new strings. Finally, the corresponding decoding is good on the server side. Or, if it’s all letters, take the remainder of any number with the alphabet subscript and replace it with the corresponding letter below. We’ll talk about other encryption methods later.

The resources

[1] a Brief Discussion on seven Common Encryption Algorithms and Their Implementation

[2] “How to Encrypt Transfer and Store User Passwords”

[3] Graphic HTTP

[4] Full Parsing of MD5 Algorithm

[5] NPM Documentation

Write in the last

I would like to use the most understandable language to express my understanding of Vuex. Please point out any deviation in my understanding. Thank you. I wish you a happy May Day, with rivers and lakes.