Encryption is widely used in programming, especially in various network protocols. Symmetric/asymmetric encryption is often mentioned as two encryption methods.
Symmetric encryption
The vast majority of encryption that we encounter at ordinary times is symmetrical encryption, for example: fingerprint unlock, PIN code lock, safe combination lock, account password is used symmetrical encryption.
Symmetric encryption: encryption and decryption using the same password or the same logical encryption method.
This is also known as a symmetric key, but symmetry and asymmetry refer to whether the encryption and decryption keys are the same.
When I was in college, I made a command line version of the library management system as a C language course. When you log in to the system, you need to input your account password. Of course, verifying the password entered by the user is a kind of symmetric encryption. The password must be the same as the account password you set before.
I chose to store the password in a local file, but if the file is stolen and the password itself is not encrypted, the password is compromised. So how do you encrypt passwords stored in files? The way 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 and add a fixed value, such as 6, and then store the calculated code value string when storing. Use JS to simulate:
// Process of encrypting user passwords
const sourcePassword = 'abcdef'; // User account password
// Encrypted password of the account stored in the local file
const encryptedPassword = [...sourcePassword].map((char) = > char.codePointAt(0) + 6).join();
console.log('The encrypted account password is:${encryptedPassword}`) // => the encrypted password is 103,104,105,106,107,108
// Decryption process
const decryptedPassword = encryptedPassword.split(', ').map((codePoint) = > String.fromCodePoint(codePoint - 6)).join(' ');
console.log('Decrypted account password is:${decryptedPassword}`); // => The password of the decrypted account is abcdef
Copy the code
The above procedure for encrypting user account passwords does not obviously involve the password used for encryption, but the encryption and decryption use the same logic: take the ASCII value of the character plus 6, in fact, this is symmetric encryption. In fact, it can also be understood that the encryption password is the encryption algorithm itself, and the encryption algorithm can decode the account password.
Some software supports data encryption, such as RAR, which requires you to input the password when encrypting data, and then requires us to input the set encryption password when decrypting data. Actually going back to the very simple encryption algorithm I mentioned above, the system can be designed so that the user can set an encrypted password to encrypt the account password. This is reduced to a single number, and instead of adding a fixed 6 to each user’s password, the system will add the number set by the user. Now your encryption logic can be disclosed as rar compression algorithm, even if the attacked know the encryption algorithm and the encrypted account password, if they do not know the encryption password, they still cannot get the user account password. Here the encryption password and decryption password are the same password, corresponding to the above system is 6, so also symmetric encryption.
Use NodeJS for symmetric encryption
Nodejs’s crypto module is a dedicated module for all kinds of encryption, can be used to extract (hash), salt digest (HMAC), symmetric encryption, asymmetric encryption, etc. Symmetric encryption with Crypto is simple, with the Crypto module providing Cipher classes for encrypting data and Decipher for decryption.
Common symmetric encryption algorithms include DES, 3DES, AES, Blowfish, IDEA, RC5, and RC6. The AES algorithm is used in this section.
const crypto = require('crypto');
/** * symmetric encryption String * @param {String} password Secret key used for symmetric encryption * @param {String} String Encrypted data * @return {String} encryptedString The encrypted character string */
const encrypt = (password, string) = > {
// The symmetric encryption algorithm is AES-192-Cbc
const algorithm = 'aes-192-cbc';
// Generate symmetric encryption key, salt is used to generate the key, 24 specifies that the key length 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('Secret key length:${key.length}`); // => Length of key: 24
// Initialize the vector
const iv = Buffer.alloc(16.0);
// Get the Cipher Cipher class
const cipher = crypto.createCipheriv(algorithm, key, iv);
// UTF-8 specifies the character encoding of the data to be encrypted, 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, 'Talent doesn't work hard enough.');
console.log('The encrypted data is:${encryptedString}`); / / = > the encrypted data is: 1546756 bb4e530fc1fbae7fd2cf9aeac0368631b54581a39e5c53ee3172638de
/** * decryptedString * @param {String} password encryption password * @param {String} encryptedString encryptedString * @return {String} decryptedString Decrypted string */
const decrypt = (password, encryptedString) = > {
const algorithm = 'aes-192-cbc';
// Use the same algorithm to generate the same secret key
const key = crypto.scryptSync(password, 'salt'.24);
const iv = Buffer.alloc(16.0);
// Generate Decipher 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('Decrypted data:${decryptedString}`); // => Decrypted data: talent is not hard enough to gather together
Copy the code
Asymmetric encryption
Asymmetric encryption uses a pair of secret keys, called a public key and a private key, also known as an asymmetric secret key. Asymmetric keys can be used for both encryption and authentication. Let’s talk about encryption first.
One password is enough for encryption, why two passwords for asymmetric encryption?
Black question mark. JPG
I’m sure there are people out there who have had that thought. In fact, symmetric encryption as long as the length of the encrypted password is long enough, the encrypted data is generally secure without access to the password itself. But there is a problem in the practical application of network data such as encryption, because use the same secret key encryption and decryption, so the server and the client is necessarily to the exchange of the secret key, and it is because of the asymmetric secret key with a secret key exchange this process may be an intermediary to steal the secret key, once the symmetrical secret key stolen, and by analyzing the encryption algorithm, The transmitted data is then transparent to the middleman. So the fatal drawback of symmetric encryption is that it cannot guarantee the security of the secret key.
So does asymmetric encryption guarantee the security of a secret key? Yes, the secret key can be made public, and the secret key that is made public is called a public key. Asymmetrically encrypted secret keys are calculated by encryption algorithms and come in pairs. The public key is called a public key, and the private key that cannot be made public is called a private key.
When using github and other Git repository hosting platforms, we usually configure SSH public key, generate a pair of secret keys we can use the following command:
The above uses the ssh-keygen program to specify the encryption algorithm as RSA, and generates a pair of key, key.pub in the current directory. Pub = public key = public key = public key Take a look at the generated content:
The key.pub is a public key, and public keys are designed to be public at will. By configuring this public key to the hosting platform, we can eliminate the need to enter a password every time we communicate with Github.
The key to the security of asymmetric encryption is to use one secret key in a private key pair, and the encrypted data can only be decrypted through the other secret key. This means that data is encrypted using the public key of a pair of secret keys and can only be decrypted using the other private key. Or conversely, data encrypted using the private key in a pair of secret keys can only be decrypted using the other public key. Thus, from the point of view of encryption, public key and private key are the same function, can be used for encryption or decryption, but when we use asymmetric secret key for encryption data is often used for encryption with public key.
In HTTPS encryption, symmetric encryption is used to encrypt the transmitted data itself, and asymmetric encryption is used to encrypt symmetric secret keys. The whole process is as follows: The server creates a pair of asymmetric secret keys and sends the public key to the client. The client also determines the symmetric encryption algorithm and the symmetric secret key used for data transmission, and then encrypts the symmetric secret key using the public key given by the server. After receiving the symmetric encryption algorithm and key from the client, the server and client use the symmetric encryption algorithm and key for data transmission. Without the private key stored on the server side, you cannot decipher the symmetric secret key encrypted with the public key, even if the contents of the public key on the server side are known to the middleman. A public key is a public key that can be accessed at will, and decryption requires a private key. Asymmetric encryption or public key encryption can ensure encryption security because the private key is not public, attackers can not crack without the private key.
One might wonder: why use asymmetric encryption to encrypt symmetric keys? That’s because the exchange of symmetric keys can be stolen by a third party, and if symmetric keys are stolen then symmetric encryption makes no sense. And why not just use asymmetric encryption to encrypt the transmission instead of just the symmetric key? Asymmetric encryption isn’t symmetric encryption more secure? This is related to the characteristics of symmetric encryption and asymmetric encryption.
Contrast asymmetric encryption with symmetric encryption
- Symmetric encryption is one secret key, asymmetric encryption is a pair of two secret keys
- Asymmetric encryption is more secure than symmetric encryption because there is no leakage of the secret key and the public key is known
- Because asymmetric encryption is computationally complex, symmetric encryption and decryption are generally much faster than asymmetric encryption
- Asymmetric keys can also be used for authentication
Asymmetric encryption is not used for data transmission in HTTPS because the data itself may be large. In this case, asymmetric encryption takes more time. Therefore, asymmetric encryption is not used for data transmission.
Use NodeJS to demonstrate asymmetric encryption
Common asymmetric encryption has RSA, ECC (elliptic curve encryption algorithm), Diffie-Hellman, El Gamal, DSA (digital signature), here demonstrates RSA encryption.
const crypto = require('crypto');
// Key phrase
const passphrase = 'lyreal666';
// rsa Indicates that the asymmetric key algorithm is RSA
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 4096.// Specify the length of the key
publicKeyEncoding: {
type: 'spki'.// Public key encoding format
format: 'pem',},privateKeyEncoding: {
type: 'pkcs8'.// Private key encoding
format: 'pem'.cipher: 'aes-256-cbc',
passphrase,
},
});
/** * encrypting with publicKey * @param {String} publicKey the secret key used for symmetric encryption * @param {String} String the encrypted data * @return {String} encryptedString The encrypted character string */
const encrypt = (publicKey, string) = > {
// Use public key encryption
return crypto.publicEncrypt({ key: publicKey, passphrase } , Buffer.from(string)).toString('hex');
};
/** * encryptedString with privateKey * @param {String} privateKey privateKey * @param {String} encryptedString DecryptedString indicates the decryptedString */
const decrypt = (privateKey, encryptedString) = > {
return crypto.privateDecrypt({ key: privateKey, passphrase } , Buffer.from(encryptedString, 'hex'));
}
const string = 'Say don't cry, don't love me, cry (' ⌒´) Blue';
const encryptedString = encrypt(publicKey, string);
console.log('Result of public key encryption:${encryptedString}`); // => Result of public key encryption: caf7535C46146f5...
const decryptedString = decrypt(privateKey, encryptedString);
console.log('Decrypted private key result:${decryptedString}`); // => Private key decrypt result: say, don't cry, don't love me, cry (' ⌒´) Blue
Copy the code
Asymmetric key authentication
Asymmetric encryption is sometimes called public key encryption, and asymmetric secret key authentication is also called private key authentication. When we say we use asymmetric keys to authenticate data, what we mean is to verify that data has not been tampered with. Asymmetric keys are widely used for authentication in addition to encrypting data, such as mobile apK signatures and certificates in HTTPS.
The principle is simple: for example, if I want to verify that an APK code has been modified, I first prepare a pair of asymmetric secret keys, usually from an authority. The official apK package includes not only the application code, but also a signature, which is simply interpreted as the encrypted data using the hash value of the application code using the private key. When the APK is installed, the Android system extracts the signature in the APK, decrypts the signature using the public key to obtain the hash of the original application code, and compares the hash with the hash of the original application code. If the content is the same, the APK has not been tampered with. If apK’s application code has been modified by a third party, the hash decrypted from the signature must be different from the hash of the application code. So you can make sure that the application code is not tampered with, which is authentication.
The key to authentication is the presence of the signature, which must be guaranteed to hash the original APK application code. How to ensure that signatures are not tampered with is beyond the scope of this article.
Some people may look at the apK authentication process will have such a question: using the private key to encrypt the content can achieve the purpose of authentication, that can use the public key encryption to authenticate?
The answer is definitely no. If you use a public key to encrypt your content, the middleman will have to tamper with your content. Forging a signature is as simple as using the public key to hash the forged content. So another key to using asymmetric keys for authentication is that the private key is not public, so middlemen can’t get access to the private key and therefore can’t forge the signature.
A few questions
Is hash encryption?
I don’t think so. Hash is irreversible and the encryption should be able to be restored based on the encrypted data.
Is Base 64 encryption?
Symmetric encryption, symmetric key is the base 64 character code table.
Is asymmetric encryption absolutely safe?
No encryption is absolutely secure, and asymmetric encryption has the problem of public keys being tampered with when they are exchanged.
Because I have not studied cryptography, the above content is written by me through summarizing the knowledge I have learned in the past, it is inevitable that there will be some bias, even said with a very obvious personal point of view. Readers are welcome to point out errors and discussions in the comments section.
Thank you for reading. If it is helpful to you, please pay attention and click a “like” to support it.
This article is original content, first published in personal blog, reproduced please indicate the source.