With the rise of the network era, more and more data are transmitted on the Internet, which is becoming more and more important. In order to avoid data being intercepted, encryption algorithms came into being. Today, we will use the Java platform to tell you about several common encryption algorithms.
1. Hash algorithm
(1) hash algorithm, also known as (digest algorithm)
The function of hash algorithm is to calculate any group of data and get a fixed length output summary.
The purpose of hash algorithm is to verify whether the data has been tampered with.
The characteristics of hash algorithm are: the same input must get the same output, and different input probabilities get different outputs.
(2) Several common hash algorithms
algorithm | Output length (bits) | Output bytes (bytes) |
MD5 | 128 bits | 16 bytes |
SHA-1 | 160 bits | 20 bytes |
RipMD-160 | 160 bits | 20 bytes |
SHA-256 | 256 bits | 32 bytes |
SHA-512 | 512 bits | 64 bytes |
(3) How to use hash algorithm to encrypt data
Next, we take encrypting a string (Hello world) as an example, using MD5 in hash algorithm as an example.
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class AAA { public static void main(String[] args) { String str = "Hello world"; //Using try catch block to deal with possible exceptions try { //Obtain the encryption tool object according to the current algorithm (summary) MessageDigest md5 = MessageDigest.getInstance("MD5"); //Update the original data and convert the string type into bytes md5.update(str.getBytes()); byte[] resultByteArray = md5.digest(); //The encrypted byte array needs to be converted into a string, and a Stringbuilder should be prepared in advance StringBuilder result = new StringBuilder(); for(byte bite : resultByteArray) { //Use the String.format method to set the encrypted string format result.append(String.format("%02x", bite)); } //Print out the encrypted string System.out.println(result); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } }
2. Symmetric encryption algorithm
(1) Symmetric encryption algorithm is the traditional use of a password for encryption and decryption. From a procedural point of view:
Encryption: a function that receives passwords and plaintext secert = encrypt (key, message);
Decryption: a function that receives passwords and ciphertexts, plain = decrypty (key, secert);
(2) In the process of software development, common symmetric encryption algorithms include:
algorithm | Key length | Working mode | Fill mode |
DES | 56/64 | ECB/CBC/PCBC/CTR.... | noPadding/PKCS5Pading/.... |
AES | 128/192/256 | ECB/CBC/PCBC/CTR..... | noPadding/PKCS5Pading/.... |
IDEA | 128 | ECB | PKCS5Pading/PKS7Paddong/... |
(3)AES encryption: AES algorithm is the most widely used encryption algorithm at present. The common working modes are ECB and CBC
We assume that the password plaintext is (Hello.world), and use ECB and CBC modes to simulate encryption and decryption.
ECB:
import java.security.*; import java.util.Base64; import javax.crypto.*; import javax.crypto.spec.*; public class Main { public static void main(String[] args) throws Exception { // Original text: String message = "Hello, world!"; System.out.println("Message(Original information): " + message); // 128 bit key = 16 bytes Key: byte[] key = "1234567890abcdef".getBytes(); // Encryption: byte[] data = message.getBytes(); byte[] encrypted = encrypt(key, data); System.out.println("Encrypted(Encrypted content): " + Base64.getEncoder().encodeToString(encrypted)); // decrypt: byte[] decrypted = decrypt(key, encrypted); System.out.println("Decrypted(Decrypt content): " + new String(decrypted)); } // Encryption: public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException { // To create a password object, you need to pass in the algorithm / working mode / filling mode Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // "Recover" the secret key object according to the byte content of the key SecretKey keySpec = new SecretKeySpec(key, "AES"); // Initialization key: set encryption mode ENCRYPT_MODE cipher.init(Cipher.ENCRYPT_MODE, keySpec); // Encrypt according to the original content (bytes) return cipher.doFinal(input); } // decrypt: public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException { // To create a password object, you need to pass in the algorithm / working mode / filling mode Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // "Recover" the secret key object according to the byte content of the key SecretKey keySpec = new SecretKeySpec(key, "AES"); // Initialize secret key: set the decryption mode DECRYPT_MODE cipher.init(Cipher.DECRYPT_MODE, keySpec); // Decrypt according to the original content (bytes) return cipher.doFinal(input); } }
CBC:
package com.apesource.demo04; import java.security.*; import java.util.Base64; import javax.crypto.*; import javax.crypto.spec.*; public class Main { public static void main(String[] args) throws Exception { // Original text: String message = "Hello, world!"; System.out.println("Message(Original information): " + message); // 256 bit key = 32 bytes Key: byte[] key = "1234567890abcdef1234567890abcdef".getBytes(); // Encryption: byte[] data = message.getBytes(); byte[] encrypted = encrypt(key, data); System.out.println("Encrypted(Encrypted content): " + Base64.getEncoder().encodeToString(encrypted)); // decrypt: byte[] decrypted = decrypt(key, encrypted); System.out.println("Decrypted(Decrypt content): " + new String(decrypted)); } // Encryption: public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException { // Set algorithm / working mode CBC/ filling Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Restore secret key object SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); // CBC mode needs to generate a 16 byte initialization vector: SecureRandom sr = SecureRandom.getInstanceStrong(); byte[] iv = sr.generateSeed(16); // Generate a random number of 16 bytes System.out.println(Arrays.toString(iv)); IvParameterSpec ivps = new IvParameterSpec(iv); // Random numbers are encapsulated into IvParameterSpec parameter objects // Initialization key: operation mode, key, IV parameters cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps); // encryption byte[] data = cipher.doFinal(input); // IV does not need to be confidential. Return the IV and the ciphertext together: return join(iv, data); } // decrypt: public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException { // Divide input into IV and ciphertext: byte[] iv = new byte[16]; byte[] data = new byte[input.length - 16]; System.arraycopy(input, 0, iv, 0, 16); // IV System.arraycopy(input, 16, data, 0, data.length); //ciphertext System.out.println(Arrays.toString(iv)); // decrypt: Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Password object SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); // Restore secret key IvParameterSpec ivps = new IvParameterSpec(iv); // Restore IV // Initialization key: operation mode, key, IV parameters cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps); // Decryption operation return cipher.doFinal(data); } // Merge array public static byte[] join(byte[] bs1, byte[] bs2) { byte[] r = new byte[bs1.length + bs2.length]; System.arraycopy(bs1, 0, r, 0, bs1.length); System.arraycopy(bs2, 0, r, bs1.length, bs2.length); return r; } }
3. Asymmetric encryption algorithm
(1) asymmetric encryption:
Encryption and decryption do not use the same key. Only the same public key private key can be encrypted and decrypted normally.
(2) Disadvantages of asymmetric encryption:
The operation speed is particularly slow, which is much slower than that of symmetric encryption.
(3) In practical applications, asymmetric encryption and symmetric encryption are used together. The process is as follows:
A generates a random AES password, encrypts the password with Xiaohong's public key through RSA, and sends it to B.
B decrypts the AES password with its RSA private key.
A and B use this shared AES password to encrypt communication with AES.
(4) Now let's write RSA encryption algorithm in JAVA:
import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.Cipher; // RSA public class Main { public static void main(String[] args) throws Exception { // Plaintext: byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8"); // Create a public / private key pair: Human alice = new Human("Alice"); // Encrypt with Alice's public key: // Get Alice's public key and output it byte[] pk = alice.getPublicKey(); System.out.println(String.format("public key(Public key): %x", new BigInteger(1, pk))); // Use public key encryption byte[] encrypted = alice.encrypt(plain); System.out.println(String.format("encrypted(encryption): %x", new BigInteger(1, encrypted))); // Decrypt with Alice's private key: // Get Alice's private key and output it byte[] sk = alice.getPrivateKey(); System.out.println(String.format("private key(Private key): %x", new BigInteger(1, sk))); // Decrypt with private key byte[] decrypted = alice.decrypt(encrypted); System.out.println("decrypted(decrypt): " + new String(decrypted, "UTF-8")); } } // User class class Human { // full name String name; // Private key: PrivateKey sk; // Public key: PublicKey pk; // Construction method public Human(String name) throws GeneralSecurityException { // Initialize name this.name = name; // Generate public / private key pair: KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA"); kpGen.initialize(1024); KeyPair kp = kpGen.generateKeyPair(); this.sk = kp.getPrivate(); this.pk = kp.getPublic(); } // Export private key as bytes public byte[] getPrivateKey() { return this.sk.getEncoded(); } // Export public key as bytes public byte[] getPublicKey() { return this.pk.getEncoded(); } // Encrypt with public key: public byte[] encrypt(byte[] message) throws GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, this.pk); // Initialize with public key return cipher.doFinal(message); } // Decrypt with private key: public byte[] decrypt(byte[] input) throws GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, this.sk); // Initialize with private key return cipher.doFinal(input); } }