Common encryption algorithms in Java: hash algorithm encryption, symmetric encryption and asymmetric encryption

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

algorithmOutput length (bits)Output bytes (bytes)
MD5128 bits16 bytes
SHA-1160 bits

20 bytes

RipMD-160160 bits20 bytes
SHA-256256 bits32 bytes
SHA-512512 bits64 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:

algorithmKey lengthWorking modeFill mode
DES56/64ECB/CBC/PCBC/CTR....noPadding/PKCS5Pading/....
AES128/192/256ECB/CBC/PCBC/CTR.....noPadding/PKCS5Pading/....
IDEA128ECBPKCS5Pading/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);
	}
}

     

Tags: Java programming language Hash Algorithm

Posted by ihw13 on Fri, 22 Jul 2022 01:54:27 +0530