Symmetric encryption and asymmetric encryption

Encryption is widely used in programming, especially in various network protocols. Symmetric / asymmetric encryption is often mentioned as two encryption methods.

Symmetric encryption

For example, when we encounter a symmetric password lock, most of our passwords are encrypted. For example, when we encounter a password lock, we use a symmetric password.

Symmetric encryption: encryption and decryption use the same password or the same set of logical encryption.

This password is also called symmetric secret key. In fact, this symmetry and asymmetry refer to whether the secret key used for encryption and decryption is the same.

When I was in college, I made a command-line version of the library management system as a C language course. When logging into the system, you need to enter the account password. Of course, verifying the password entered by the user is a kind of symmetric encryption. The password that the user must enter must be the same as the account password you set before.

At that time, I chose to store the account and password in the local file, but if the file was stolen and the password itself was not encrypted, the password would be leaked. So how to encrypt the password stored in the file? The method I adopted at that time (which can also be understood as an encryption algorithm) was to take the code value of each character of the account password set by the user, then add a fixed value, such as 6, and then store the calculated code value string when storing. Use js to simulate:

// Encrypt user password process
const sourcePassword = 'abcdef'; // User account password
// Encrypted account password stored in local file
const encryptedPassword = [...sourcePassword].map((char) => char.codePointAt(0) + 6).join();
console.log(`The encrypted account password is: ${encryptedPassword}`) // =>The encrypted account password is 103104105106107108

// Decryption process
const decryptedPassword = encryptedPassword.split(',').map((codePoint) => String.fromCodePoint(codePoint - 6)).join('');
console.log(`The decrypted account password is: ${decryptedPassword}`); // =>The decrypted account password is abcdef

Although the above process of encrypting the user account password does not obviously involve the password used for encryption, the encryption and decryption use the same set of logic: take the ascii code value of the character and add 6. In fact, this is also symmetric encryption. In fact, it can also be understood that the encryption password is the encryption algorithm itself. Knowing the encryption algorithm, you can decode the account password.

Some software supports data encryption, such as RAR. You need to enter the password when encrypting, and then we need to enter the set encryption password when decrypting. In fact, back to the simple encryption algorithm I mentioned above, the system can be designed so that users can set an encryption password for encrypting account passwords. This is simplified to a number. When the system stores the user account and password, instead of adding a fixed 6 to each user as before, it adds the number set by the user. Now your encryption logic can be disclosed like rar public compression algorithm. Even if the attacker knows the encryption algorithm and the encrypted account password, if he doesn't know the encryption password, he can't get the user account password. The encryption password and decryption password here use the same password, corresponding to the system above is 6, so it is also symmetric encryption.

Use nodejs for symmetric encryption

The crypto module of nodejs is a module specially used for various encryption. It can be used for hash, hmac, symmetric encryption, asymmetric encryption and so on. Symmetric encryption using crypto is very simple. The crypto module provides Cipher class for encrypting data and Decipher for decryption.

Common symmetric encryption algorithms are DES,3DES,AES,Blowfish,IDEA,RC5,RC6, Here is a demonstration of using AES algorithm for symmetric encryption.

const crypto = require('crypto');

/**
 * Symmetric encrypted string
 * @param {String} password Secret key for symmetric encryption
 * @param {String} string Encrypted data
 * @return {String} encryptedString Encrypted string
 */
const encrypt = (password, string) => {
  // The symmetric encryption algorithm used is aes-192-cbc
  const algorithm = 'aes-192-cbc';
  // Generate a symmetric encryption secret key. salt is used to generate the secret key. 24 specifies that the length of the secret key is 24 bits
  const key = crypto.scryptSync(password, 'salt', 24);
  console.log('key:', key); // => key: <Buffer f0 ca 6c ac 39 3c b3 f9 77 13 0d d9 bc cb dd 9d 86 f7 96 e0 75 53 7f 8a>
  console.log(`Key length: ${key.length}`); // =>Key len gt h: 24

  // Initialization vector
  const iv = Buffer.alloc(16, 0);
  // Get Cipher encryption class
  const cipher = crypto.createCipheriv(algorithm, key, iv);

  // utf-8 specifies the character encoding of the encrypted data, and hex specifies the character encoding of the output
  let encryptedString = cipher.update(string, 'utf8', 'hex');
  encryptedString += cipher.final('hex');

  return encryptedString;
};

const PASSWORD = 'lyreal666';
const encryptedString = encrypt(PASSWORD, 'Not talented enough to work hard');
console.log(`The encrypted data is: ${encryptedString}`); // =>The encrypted data is: 1546756bb4e530fc1fbae7fd2cf9aeac0368631b54581a39e5c53ee3172638de  

/**
 * Decrypt string
 * @param {String} password Encryption password
 * @param {String} encryptedString Encrypted string
 * @return {String} decryptedString Decrypted string
 */
const decrypt = (password, encryptedString) => {
  const algorithm = 'aes-192-cbc';
  // The same algorithm is used to generate the same secret key
  const key = crypto.scryptSync(password, 'salt', 24);
  const iv = Buffer.alloc(16, 0);
  // Generate decrypter decryption class
  const decipher = crypto.createDecipheriv(algorithm, key, iv);

  let decryptedString = decipher.update(encryptedString, 'hex', 'utf8');
  decryptedString += decipher.final('utf8');

  return decryptedString;
};

const decryptedString = decrypt(PASSWORD, encryptedString);
console.log(`When decrypting data: ${decryptedString}`); // =>Decrypted data: talent is not enough to work hard

Asymmetric encryption

Asymmetric encryption uses a pair of secret keys, which are called public key and private key respectively, also known as asymmetric secret key. Asymmetric secret keys can be used for both encryption and authentication. Let's talk about encryption first.

One password is enough for encryption. Why do you need two passwords for the whole asymmetric encryption?
Black question mark jpg

I'm sure someone will have the same idea as me. In fact, as long as the length of the encrypted password is long enough, the encrypted data is generally safe when the password itself is not available. However, there is a problem that in practical applications, such as encrypting network data, because the same secret key is used for encryption and decryption, the server and client must exchange the secret key, and it is precisely because the asymmetric secret key may be stolen by an intermediary in the process of exchanging the secret key. Once the symmetric encryption secret key is stolen, And if the encryption algorithm is analyzed, the transmitted data is transparent to the middleman. Therefore, the fatal disadvantage of symmetric encryption is that it can not guarantee the security of the secret key.

Then can asymmetric encryption ensure the security of the secret key? Yes, the secret key can be boldly disclosed. The disclosed secret key is called the public key. The secret key of asymmetric encryption is calculated by the encryption algorithm and is in pairs. The secret key that can be disclosed is called the public key, and the private secret key that cannot be disclosed is called the private key.

When using github and other git warehouse hosting platforms, we usually configure ssh public keys to generate a pair of secret keys. We can use the following commands:

 

 

 

The above uses the SSH keygen program to specify the encryption algorithm as rsa and generate a pair of secret keys in the current directory pub. Key , is the private key, key Public is a public key, and the suffix public is clearly public. Let's take a look at the specific content generated:

 

This key Pub is a public key, which is designed to be freely public. By configuring this public key to the hosting platform, we can avoid having to enter a password every time we communicate with github.

This pair of public and private keys has a feature, and it is also the key to the security of asymmetric encryption. The key is to use one of the secret key pairs to encrypt, and the encrypted data can only be decrypted through another secret key. That is to say, if the public key in a pair of secret keys is used to encrypt the data, the data can only be decrypted through another private key. Or conversely, the data encrypted with the private key in a pair of secret keys can only be decrypted by another public key. It can be seen that from the perspective of encryption, the public key and the private key actually have the same function and can be used for encryption or decryption, but when we use the asymmetric secret key to encrypt data, we often use the public key for encryption.

In https encryption, symmetric encryption is used to encrypt the transmitted data itself, and asymmetric encryption is used to encrypt the symmetric secret key. The whole process is as follows: the server side forms a pair of asymmetric secret keys and sends the public key that can be disclosed to the client side. The client side also determines the symmetric encryption algorithm and symmetric secret key used in this data transmission, and then uses the public key given by the server side to encrypt and transmit the symmetric secret key. After the server receives the symmetric encryption algorithm and secret key sent by the client, the data transmission of the server and client uses this symmetric secret key and algorithm for symmetric encryption. In the whole process, even if the public key on the server side is known by the middleman, but there is no private key saved on the server side, you cannot decipher the symmetric secret key encrypted with the public key. The public key can be disclosed at will, and it is useless to get it. What is needed for decryption is the private key. The reason why asymmetric encryption or public key encryption can ensure the security of encryption is that the private key is confidential and not public, and the attacker cannot decipher without the private key.

Some people may wonder: why do we need to use asymmetric encryption to encrypt the symmetric secret key? That's because the symmetric secret key may be stolen by a third party when it is exchanged. If the symmetric secret key is stolen, the symmetric encryption is meaningless. And why not use asymmetric encryption directly to encrypt the transmitted content, but just encrypt the symmetric secret key? Isn't asymmetric encryption more secure than symmetric encryption? This is related to the characteristics of symmetric encryption and asymmetric encryption.

Comparison between asymmetric encryption and symmetric encryption

  1. Symmetric encryption is a secret key, and asymmetric encryption is a pair of two secret keys
  2. Asymmetric encryption is more secure than symmetric encryption, because there is no problem of secret key disclosure, and even if the public key is known, it doesn't matter
  3. Because the use of asymmetric encryption is particularly complex in calculation, generally speaking, the encryption and decryption speed of symmetric encryption is much faster than that of asymmetric encryption
  4. Asymmetric keys can also be used for authentication

Due to the above article 3, asymmetric encryption will not be used when transmitting data in https. The data itself may be large when transmitting data. In that case, asymmetric encryption is more time-consuming, so asymmetric encryption will not be used when transmitting data.

Demonstrate asymmetric encryption using nodejs

Common asymmetric encryption include RSA, ECC (elliptic curve encryption algorithm), Diffie Hellman, El Gamal and DSA (for digital signature). Here is a demonstration of RSA encryption.

const crypto = require('crypto');

// Secret key encryption phrase
const passphrase = 'lyreal666';

// rsa specifies the asymmetric secret key algorithm as rsa
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 4096, // Specifies the length of the secret key
  publicKeyEncoding: {
    type: 'spki', // Public key encoding format
    format: 'pem',
  },
  privateKeyEncoding: {
    type: 'pkcs8', // Private key encoding format
    format: 'pem',
    cipher: 'aes-256-cbc',
    passphrase,
  },
});

/**
 * Use public key encryption
 * @param {String} publicKey Secret key for symmetric encryption
 * @param {String} string Encrypted data
 * @return {String} encryptedString Encrypted string
 */
const encrypt = (publicKey, string) => {
  // Use public key encryption
  return crypto.publicEncrypt({ key: publicKey, passphrase } , Buffer.from(string)).toString('hex');
};

/**
 * Decrypt string using private key
 * @param {String} privateKey Private key
 * @param {String} encryptedString Encrypted string
 * @return {String} decryptedString Decrypted string
 */
const decrypt = (privateKey, encryptedString) => {
    return crypto.privateDecrypt({ key: privateKey, passphrase } , Buffer.from(encryptedString, 'hex'));
}

const string = 'If you don't cry or love me, you'll pull me downヽ(`⌒´)ノ';
const encryptedString = encrypt(publicKey, string);
console.log(`Result after public key encryption: ${encryptedString}`); // =>The result of public key encryption: caf7535c46146f5
const decryptedString = decrypt(privateKey, encryptedString);
console.log(`Result after decryption of private key: ${decryptedString}`); // =>The result of decryption of the private key: if you don't cry, if you don't love me, I'll pull you down ('-')

Asymmetric key authentication

Asymmetric encryption is sometimes called public key encryption, and asymmetric secret key authentication is also called private key authentication. We say that using asymmetric secret key to authenticate data actually means to confirm whether a data has been tampered with. In addition to encrypting data, asymmetric secret keys are also widely used for authentication, such as the signature of mobile apk and the certificate in https.

The principle is very simple: for example, if I want to verify whether the code of an apk has been changed, first prepare a pair of asymmetric secret keys, usually from an authoritative organization. The official package of apk not only contains the application code, but also carries a signature. This signature is simply understood as the data encrypted by using the private key to the hash value of the application code. When installing apk, the android system will extract the signature in apk, decrypt the signature with the public key to get the hash of the original application code, and then compare it with the hash of the original application code. If the content is the same, the apk has not been tampered with. If the application code of apk is modified by a third party, the hash decrypted from the signature must be different from the hash of the application code. Therefore, it can ensure that the application code is not tampered with, that is, authentication.

In fact, the key to the existence of the application's hash signature is to ensure the existence of the original hash signature. How to ensure that the signature is not tampered with is beyond the scope of this article.

After reading the above process of apk authentication, some people may have such a question: using the private key to encrypt the content can achieve the purpose of authentication. Can you use public key encryption to authenticate?

The answer is definitely not. If you use the public key to encrypt the content, the middleman needs to tamper with your content. Forging a signature is very simple. You can directly use the public key to hash encrypt the forged content. Therefore, another key to the use of asymmetric secret keys for authentication is that the private key is not public. The middleman cannot obtain the private key and forge the signature.

Several questions

Is hash encryption?

I don't think so. hash is irreversible. Encryption should be restored according to the encrypted data.

Is base 64 encryption?

It is symmetric encryption, and the symmetric secret key is the base 64 character code table.

Is asymmetric encryption absolutely secure?

No encryption is absolutely secure. Asymmetric encryption has the problem that the public key is tampered when exchanging public keys.

Since I have not specially studied cryptography, the above contents are written by me by summarizing the knowledge I have learned in the past. It is inevitable to be biased, even with obvious personal views. Readers are welcome to point out the mistakes and discussions in the comments.

Keywords: Algorithm

Added by ozzythaman on Wed, 02 Feb 2022 07:25:56 +0200