1 Common encryption modes

1.1 Symmetric Encryption

  • In the encryption method of single-key cryptosystem, the same key can be used to encrypt and decrypt information at the same time. This encryption method is called symmetric encryption, also called single-key encryption.

  • Common Encryption Algorithms

    • DES: Data Encryption Standard, also known as the Data Encryption Standard, is a block algorithm using Encryption keys. In 1977, it was confirmed by the National Bureau of Standards of the FEDERAL Government of the United States as the Federal Data Processing Standard (FIPS) and authorized to be used in unclassified government communications. Subsequently, the algorithm has been widely spread internationally.
    • AES: Advanced Encryption Standard. Also known as Rijndael in cryptography, it is a block encryption standard adopted by the US federal government. This standard to replace the original DES, has been widely analyzed and used around the world.
  • The characteristics of

    • Fast encryption speed, can encrypt large files
    • Ciphertext reversible, once the key file is leaked, data will be exposed
    • After encryption, the encoding table cannot find the corresponding character, resulting in garbled characters
    • It is used with Base64

1.2 Base64 algorithm

1.2.1 Introduction to the algorithm

Base64 is one of the most common readability encoding algorithms used to transmit 8Bit bytecode on the network. Readability encoding algorithm is not to protect the security of data, but to readability. Readability encoding does not change information content, but only the expression form of information content. Upper case A to Z, lower case A to Z, numbers 0 to 9, “+” and “/” Base58 is an encoding used in Bitcoin, mainly for the wallet address that produces Bitcoin. Base58 does not use the number “0”, the letter “O”, the letter “I”, And the lowercase “I”, and the “+” and “/” symbols

1.2.2 Base64 algorithm principle

Base64 is a set of three bytes, one byte is eight bits, a total of 24 bits, and then the three bytes are converted into four groups of six bits.

3 * 8 = 4 * 6 = 24, each group of 6 bits, missing 2 bits, will complement 0 in the high position, the advantage of this is that base is the last 6 bits, remove the high 2 bits, then the value of Base64 can be controlled in 0-63 bits, so it is called base64. 111 = 32 + 16 + 8 + 4 + 2 + 1

1.2.3 Base64 Composition principles

① Lowercase A-z = 26 letters

② Capital A-Z = 26 letters

③ Numbers 0-9 = 10 numbers

④ + / = 2 symbols

One problem you may notice is that our base64 has an = sign, but there is no = sign in the mapping table. This should be noted that the equal sign is very special, because base64 is a group of three bytes. If we run out of bits, we will use the equal sign to complement

1.3 DES Encryption and Decryption

import cn.hutool.core.codec.Base64;
import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class EncryptTest {

    @Test
    public void DesTest(a) throws Exception {
        // The content to be encrypted
        String input = "Content";
        // DES encryption algorithm, the key size must be 8 bytes
        String key = "12345678";
        String transformation = "DES";
        // Specify the algorithm to obtain the key
        String algorithm = "DES";
        String encryptDES = encryptDesAes(input, key, transformation, algorithm);
        System.out.println("Encryption:" + encryptDES);/ / encryption: w4M6kCoVpZE =
        String s = decryptDesAes(encryptDES, key, transformation, algorithm);
        System.out.println("Decryption." + s);// Decrypt: contents
    }

    /** * DES AES data encryption **@paramInput@paramKey: indicates the key (DES). The length of the key must be 8 bytes. AES is 16 bytes) *@paramTransformation: Obtains the algorithm of the Cipher object *@paramAlgorithm: algorithm to obtain the key *@return {@link String}
	 * @throwsThe Exception Exception * /
    private static String encryptDesAes(String input, String key, String transformation, String algorithm) throws Exception {
        // Get the encrypted object
        Cipher cipher = Cipher.getInstance(transformation);
        // Create an encryption rule
        // The bytes of the first argument key
        // The second parameter indicates the encryption algorithm
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE: ENCRYPT_MODE
        // DECRYPT_MODE: decryption mode
        // Initialize the encryption mode and algorithm
        cipher.init(Cipher.ENCRYPT_MODE, sks);
        / / encryption
        byte[] bytes = cipher.doFinal(input.getBytes());
        // Return encrypted data
        return Base64.encode(bytes);
    }

    /** * DES AES decryption **@paramInput: ciphertext *@paramKey: key *@paramTransformation: Obtains the algorithm of the Cipher object *@paramAlgorithm: algorithm to obtain the key *@returnThe original *@throwsThe Exception Exception * /
    private static String decryptDesAes(String input, String key, String transformation, String algorithm) throws Exception {
        // 1 to obtain a Cipher object
        Cipher cipher = Cipher.getInstance(transformation);
        // Specify the key rule
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. Decrypt base64 encoding
        byte[] bytes = cipher.doFinal(Base64.decode(input));
        // It is plaintext, so it is returned directly
        return newString(bytes); }}Copy the code

1.4 AES Encryption and Decryption

@Test
public void AesTest(a) throws Exception {
    // The content to be encrypted
    String input = "Content";
    // AES encryption algorithm, the key size must be 16 bytes
    String key = "1234567812345678";
    String transformation = "AES";
    // Specify the algorithm to obtain the key
    String algorithm = "AES";
    String encryptDES = encryptDesAes(input, key, transformation, algorithm);
    System.out.println("Encryption:" + encryptDES);/ / encryption: uZFKEeJj50wA5bq8PzuPLw = =
    String s = decryptDesAes(encryptDES, key, transformation, algorithm);
    System.out.println("Decryption." + s);// Decrypt: contents
}
Copy the code

2 Encryption Mode

2.1 the ECB

ECB: Electronic codebook. The message to be encrypted is divided into several blocks according to the block size of the block password, and each block is encrypted independently

  • Advantages: Data can be processed in parallel
  • Disadvantages: The same source text generates the same ciphertext, which cannot protect data well
  • At the same time, the original text is the same, and the encrypted ciphertext is the same

2.2 CBC

CBC: cipher-block chaining, which links password blocks. Each plaintext block is xor with the previous ciphertext block before encryption. In this approach, each ciphertext block depends on all the plaintext blocks that precede it

  • Advantages: The ciphertext generated in the same original text is different
  • Disadvantages: Serial processing of data.

3 Filling Mode

When the data needs to be processed by block and the data length does not meet the requirements of block processing, fill the block length in a certain way according to the rule

3.1 NoPadding

  • Don’t fill.
  • Under the DES encryption algorithm, the length of the original text must be an integer multiple of 8 bytes
  • Under the AES encryption algorithm, the length of the text must be an integer multiple of 16 bytes

3.2 PKCS5Padding

The size of the data block is 8 bits

3.3 illustrates

  • By default, the encryption mode and fill mode are: ECB/PKCS5Padding
  • If the CBC mode is used, you need to add parameters when initializing a Cipher object. Initialize vector IV: IvParameterSpec IV = new IvParameterSpec(key.getBytes());

Encryption mode and fill mode

AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
Copy the code

3.4 case

DES/ECB/NoPadding encryption mode

@Test
public void test(a) throws Exception {
    // The content to be encrypted
    String input = Content of "12";
    // DES encryption algorithm, the key size must be 8 bytes
    String key = "12345678";
    // Specifies the algorithm to retrieve the Cipher. ECB/PKCS5Padding is the default if no encryption mode or padding mode is specified
    // NoPadding mode, the length of the text must be an integer multiple of 8 bytes, so the content must be changed to 12 to make up for 8 bits
    String transformation = "DES/ECB/NoPadding";
    // Specify the algorithm to obtain the key
    String algorithm = "DES";
    String encryptDES = encryptDesAes(input, key, transformation, algorithm);
    System.out.println("Encryption:" + encryptDES);/ / encryption: LpgdNawVOqY =
    String s = decryptDesAes(encryptDES, key, transformation, algorithm);
    System.out.println("Decryption." + s);// Decrypt: content 12
}
Copy the code

DES/CBC/PKCS5Padding Encryption mode

import cn.hutool.core.codec.Base64;
import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptTest {

    @Test
    public void test(a) throws Exception {
        // The content to be encrypted
        String input = "Content";
        // DES encryption algorithm, the key size must be 8 bytes
        String key = "12345678";
        // Specifies the algorithm to retrieve the Cipher. ECB/PKCS5Padding is the default if no encryption mode or padding mode is specified
        String transformation = "DES/CBC/PKCS5Padding";
        // Specify the algorithm to obtain the key
        String algorithm = "DES";
        String encryptDES = encryptDesAes(input, key, transformation, algorithm);
        System.out.println("Encryption:" + encryptDES);/ / encryption: aBDOoVb1td4 =
        String s = decryptDesAes(encryptDES, key, transformation, algorithm);
        System.out.println("Decryption." + s);// Decrypt: contents
    }

    private static String encryptDesAes(String input, String key, String transformation, String algorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(transformation);
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // The length of the initial vector must be 8 bits
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, sks, iv);
        byte[] bytes = cipher.doFinal(input.getBytes());
        return Base64.encode(bytes);
    }

    private static String decryptDesAes(String input, String key, String transformation, String algorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(transformation);
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, sks,iv);
        byte[] bytes = cipher.doFinal(Base64.decode(input));
        return newString(bytes); }}Copy the code

4 Message Summary

  • Message Digest (also known as Digital Digest)
  • It is a fixed-length value that uniquely corresponds to a message or text and is generated by a one-way Hash encryption function acting on the message
  • Values generated using a digital digest cannot be tampered with to ensure the security of the file or value

4.1 the characteristics of

No matter how long the input message is, the length of the calculated message digest is always fixed. For example, the message digest using MD5 algorithm has 128 bits, and the message digest using SHA-1 algorithm has 160 bits output

As long as the input message is different, the summary message generated after the digest must be different. But the same input must produce the same output

Message digests are one-way and irreversible

4.2 Common Algorithms

- MD5
- SHA1
- SHA256
- SHA512
Copy the code

4.3 Obtaining a String Message digest

public class EncryptTest {


    @Test
    public void test02(a) throws Exception {
        String input = "chen";
        // Get the digital digest object
        String md5 = getDigest(input, "MD5");
        System.out.println(md5);//a1a8887793acfc199182a649e905daab

        String sha1 = getDigest(input, "SHA-1");
        System.out.println(sha1);//8a89798cf0878e37bb6589ae1c36b9d8a036275b

        String sha256 = getDigest(input, "SHA-256");
        System.out.println(sha256);//3abd72ec6352d6085d85e34f0478dca7d14ef8048f3c1986e28106d654713946

        String sha512 = getDigest(input, "SHA-512");
        System.out.println(sha512);//e3b92710045fbae402523dbf08fdf0b07c7ba1969c0311c618a33f0cb82b76d3fa325bee6eb5a9ae5dd0bcf137e76d50587184493f1e70daa4a536 6dd7776af0
    }


    /** * hexadecimal byte array **@paramDigest Byte array *@return {@link String}
	 */
    private static String toHex(byte[] digest) {
        // Create objects for concatenation
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            // Convert to hexadecimal
            String s = Integer.toHexString(b & 0xff);
            if (s.length() == 1) {
                // If only one character is generated, it is preceded by 0
                s = "0" + s;
            }
            sb.append(s);
        }
        return sb.toString();
    }

    /** * message number summary **@paramThe input input *@param* algorithm algorithm@return {@link String}* @throwsThe Exception Exception * /
    private static String getDigest(String input, String algorithm) throws Exception {
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // Message digests
        byte[] digest = messageDigest.digest(input.getBytes());
        returntoHex(digest); }}Copy the code

4.4 Obtaining file Message Summaries

@Test
public void test03(a) throws Exception {
    String sha1 = getDigestFile("D:\\Data\\Pictures\\1.jpg"."SHA-1");
    System.out.println(sha1);//63be2a2ad212f3965962eaf0e302efca18fc7d2d

    String sha512 = getDigestFile("D:\\Data\\Pictures\\1.jpg"."SHA-512");
    System.out.println(sha512);//d98baf298686f862b714410b4605e93e1644ca528465ba7ff0567b6f8851674567248d53740b6a24ec3c88ec26bb7c163bfcca981a753cf8f50c43 8e08031082
}

private static String getDigestFile(String filePath, String algorithm) throws Exception {
    FileInputStream fis = new FileInputStream(filePath);
    int len;
    byte[] buffer = new byte[1024];
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    while((len = fis.read(buffer)) ! = -1) {
        baos.write(buffer, 0, len);
    }
    // Get the message digest object
    MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
    // Get the message digest
    byte[] digest = messageDigest.digest(baos.toByteArray());
    return toHex(digest);
}
Copy the code

4.5 summarize

  • MD5 algorithm: The summary result is 16 bytes, 32 bytes after converting to hexadecimal
  • SHA1 algorithm: summary result 20 bytes, 40 bytes after hexadecimal
  • SHA256 algorithm: The summary result is 32 bytes, 64 bytes after converting to hexadecimal
  • SHA512 algorithm: Summary result 64 bytes, 128 bytes after converting to hexadecimal

5 Asymmetric encryption

Introduction to the

Asymmetric encryption algorithm is also called modern encryption algorithm.

Asymmetric encryption is the cornerstone of computer communication security, ensuring that encrypted data can not be cracked.

Unlike symmetric encryption algorithms, asymmetric encryption algorithms require two keys: publickey and privatekey.

A public key and a private key are a pair

If the public key is used to encrypt data, only the corresponding private key can be used to decrypt the data.

If the private key is used to encrypt data, only the corresponding public key can be used to decrypt the data.

Because encryption and decryption use two different keys, the algorithm is called asymmetric encryption.

The sample

  • First, the key pair is generated. The public key is (5,14) and the private key is (11,14).
  • Now A wants to send text 2 to B
  • User A uses the public key to encrypt data. 2 ^ 5 mod 14 = 4 sends ciphertext 4 to user B
  • 4 ^ 11 mod14 = 2, get original text 2

The characteristics of

  • Encryption and decryption use different keys
  • If the private key is used for encryption, only the public key can be used for decryption
  • If public key encryption is used, only private key can be used for decryption
  • Data processing is slow because of high security

Common algorithms

  • RSA
  • ECC

5.1 Generating Public and Private Keys

@Test
public void test04(a) throws Exception {
    // Encryption algorithm
    String algorithm = "RSA";
    // Create a key pair generator object
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
    // Generate a key pair
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    // Generate private key
    PrivateKey privateKey = keyPair.getPrivate();
    // Generate a public key
    PublicKey publicKey = keyPair.getPublic();
    // Get the private key byte array
    byte[] privateKeyEncoded = privateKey.getEncoded();
    // Get the public key byte array
    byte[] publicKeyEncoded = publicKey.getEncoded();
    // Base64 encodes the public and private keys
    String privateKeyString = Base64.encode(privateKeyEncoded);
    String publicKeyString = Base64.encode(publicKeyEncoded);
    // Prints the private key
    System.out.println(privateKeyString);
    // Prints the public key
    System.out.println(publicKeyString);
}
Copy the code

To generate the sample

The private key

MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCCwVvY3aa69jqkbiLiKaqil0FNOF9husmKaQcl1R29iQetFFCNYvipJaKpvUdeUSzgo9Ln EsvCpY+nYiBAbIH8v/ddk9KlSwz+y6sU/JAGRCMjE799hHFeM/wWwjsro/ZimmTXDsx5WOT2+hTz/EbcIwk0JRBPvMnZ+8ZDjuyu8PUHFz48y9suf427B0jb /H2+Va9mAZTivR01ENFme+mflXwDYT3JPzUT8s/qTQW+lc2XZoQDU8T+iSHyqcjjRpyo1CARTJ9yJ1RUSzDNeM/QzNkOjb3HIL4A3fFkNkt4GUz6FhqJQIPo WFw4ktXOT8x44koHAExBTl9AlqAz5LQtAgMBAAECggEAI216klb0HwIqP3Ur9HVvq2AqLF8S0OsIQn1Ul3aX+UvQjZ/Md5KSZ1owKaeEV9TMwQ0CTuOz28h6 FNMsg+gijDYDMxKjZ2/fVIYgk64e4+PAVXe7Uan6AZk6O3xjBd8GGg9VNUPoORTR7O0zkiwPkwPXMY69Ta2MT4i9Xn6yOG/hUxOylz7K7LjbZzDApTgsr924 QoZ8AnHWrla7fmgeyn+lW5XMFQJMlM9nZJQ4z0cwzT1DpV2r1T9b3Zhm4Rg6MEJ+Alip0a4t62bChV1jbdR8iVwfpItaD3d8hBd2nBlDOgh8fyBbu6vNGq8y FmLl3rhRG5eQJZOhQaqyUePUAQKBgQDmpWFjDX/zyGJoHy8cjXVI27tcdNjk4k714z10OkEwMmMGYU3q94qCmirB/J3xg/GGXXP6JsGa37VDn1CU7ebdHkdH WhaDpqCVbjnIEBanBg7P6BRw+GfQeyG0M9l8CXOLNcNw68Wn8o32YWB3ao8nUS3OVL6K+LTYkF7j1M9FLQKBgQCRIPMW3w+q+G8BBKNlNeDAQJSVkrt1LpSw IgrQRl9pkAz9/66N9bpiIQgTo0UJmL2QcX6dQfIXZOQHMrC/6P0ILkITrtNSal8IdaK3ulfA25UZ3JP07Vu209aBu5Jqm2nkuTYugDc/CEPrsa4Ge1MEBgKY niodejJnoVNm5l6LAQKBgF4LHNRokr1x/T37SRhZTXMxtQmT00QwSoXT7CDSB/aA9QOK9VxTJrTt63VBbZ0mcXqZ7EoZN2PQx3YVJaQ0BKgwSlv7jaaMcHm9 ge3jMXlU7QE03fDaOGo3apyxb4I10Fj4yQHoAKXkLqJBPjYyyr/7R7QTtcWwdvy+kRJQmVrZAoGAK+4rZ1ryJTC6eTZsN3DNraRe1b/q2pfVDlPfrhf/PbcL F7/TmMkvOBEDnt4nQbZoe1a/mt6hZ490rvEbK5xdK6LFAaxD74ifZ7IkJTVU5t4RDhkE+Hj48CjDn9Wlhnuw3DlsOzs4fe4EkU3hfbjK8kbXdlc6LF4W7+OX mWhWagECgYA83s1t/Irl3drqnb36SKCVjdZPrx75HxKier3Ptn11Jb49GA06UOlxAkpcLQDlbQ4dghQnjiUsf3ATDOjrdaCF98Ysk15XWMNNeYGfpbHXm0fu 0gU/JAVOkPuPIxuL95e1227+8Sm8u4S19qn7GgjpiKx/+4B8zPjNtzzuTp+keg==Copy the code

The public key

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgsFb2N2muvY6pG4i4imqopdBTThfYbrJimkHJdUdvYkHrRRQjWL4qSWiqb1HXlEs4KPS5xLLwqWP p2IgQGyB/L/3XZPSpUsM/surFPyQBkQjIxO/fYRxXjP8FsI7K6P2Yppk1w7MeVjk9voU8/xG3CMJNCUQT7zJ2fvGQ47srvD1Bxc+PMvbLn+NuwdI2/x9vlWv ZgGU4r0dNRDRZnvpn5V8A2E9yT81E/LP6k0FvpXNl2aEA1PE/okh8qnI40acqNQgEUyfcidUVEswzXjP0MzZDo29xyC+AN3xZDZLeBlM+hYaiUCD6FhcOJLV zk/MeOJKBwBMQU5fQJagM+S0LQIDAQABCopy the code

5.2 Private Key Encryption Decryption of public Key

Public key encryption Private key decryption similar

@Test
public void test05(a) throws Exception {
    String input = "Content";
    String algorithm = "RSA";
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    // Create an encrypted object
    // The parameter represents the encryption algorithm
    Cipher cipher = Cipher.getInstance(algorithm);
    // Initialize encryption
    // First argument: encrypted mode
    // Second argument: encrypt with private key
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    // Private key encryption
    byte[] bytes = cipher.doFinal(input.getBytes());
    System.out.println(Base64.encode(bytes));
    // Public key for decryption
    cipher.init(Cipher.DECRYPT_MODE, publicKey);
    // To decrypt the ciphertext, you do not need to use Base64 because the original text is not garbled
    byte[] bytes1 = cipher.doFinal(bytes);
    System.out.println(new String(bytes1));
}
Copy the code

The output is as follows

k0W9BD/vBjVe4o2od1rStveoy2lMwsOpha6yBKTR15tX6aw/AlMcOju1AZrGKi7pgD/1Md/ki49tJR9/+YRTczVHOlIT63EDSd12H4KPfHAEH5jQMxKvEZ1x YlRQ52TicRNer254Df77uxKqiYoiUdcKx4+DGS+nPPhRIZtVP0oSnPnC956S26hKtrLqYdHusHG7sdq3+aOLtK1uUVoxlCiiBIU5oWomRCfLZgVjCya7ZvK/ VLWKk2W0B6/4 m5xrgae1fzjggsbpzks + Gt + 3 z + + HcEQ0GPK2lRo9glzvGZ Z4U9QK7QsAVVO7dix46F5DngMb3nr2uvwWM / 9 inlhguw = = contentCopy the code

5.3 Saving public and Private Keys

@Test
public void test06(a) throws Exception {
    String algorithm = "RSA";
    // Generate the key pair and save it in a local file
    generateKeyToFile(algorithm, "a.pub"."a.pri");
}

/** * Generate the key pair and save it in a local file **@paramThe algorithm is *@paramPubPath: save the public key *@paramPriPath: private key saving path *@throwsThe Exception Exception * /
private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
    // Get the key pair generator
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
    // Get the key pair
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    // Get the public key
    PublicKey publicKey = keyPair.getPublic();
    // Get the private key
    PrivateKey privateKey = keyPair.getPrivate();
    // Get the byte array
    byte[] publicKeyEncoded = publicKey.getEncoded();
    byte[] privateKeyEncoded = privateKey.getEncoded();
    // Base64 encoding
    String publicKeyString = Base64.encode(publicKeyEncoded);
    String privateKeyString = Base64.encode(privateKeyEncoded);
    // Save the file
    FileUtils.writeStringToFile(new File(pubPath), publicKeyString, StandardCharsets.UTF_8);
    FileUtils.writeStringToFile(new File(priPath), privateKeyString, StandardCharsets.UTF_8);

}
Copy the code

5.4 Using the Local Public And Private Keys for Encryption and Decryption

@Test
public void test07(a) throws Exception {
    String input = "Content";
    // Encryption algorithm
    String algorithm = "RSA";
    PrivateKey privateKey = getPrivateKey("a.pri", algorithm);
    PublicKey publicKey = getPublicKey("a.pub", algorithm);

    String encrypt = encryptRSA(algorithm, privateKey, input);
    String decrypt = decryptRSA(algorithm, publicKey, encrypt);
    System.out.println(encrypt);
    System.out.println(decrypt);
}

/** * Read public key **@paramPublicPath Public key path *@param* algorithm algorithm@return {@link PublicKey}* @throwsThe Exception Exception * /
public static PublicKey getPublicKey(String publicPath, String algorithm) throws Exception {
    // Convert the contents of the file to a string
    String publicKeyString = FileUtils.readFileToString(new File(publicPath), Charset.defaultCharset());
    // Get the key factory
    KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
    // Build the key specification for Base64 decoding
    X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
    // Generate a public key
    return keyFactory.generatePublic(spec);
}

/** * reads the private key **@paramPriPath Private key path *@param* algorithm algorithm@return {@link PrivateKey}* @throwsThe Exception Exception * /
public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception {
    // Convert the contents of the file to a string
    String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
    // Get the key factory
    KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
    // Build the key specification for Base64 decoding
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));
    // Generate private key
    return keyFactory.generatePrivate(spec);
}

/** * Encrypt data with key **@paramThe algorithm is *@paramInput@paramKey: key *@return {@link String}
 * @throwsThe Exception Exception * /
public static String encryptRSA(String algorithm, Key key, String input) throws Exception {
    // Create an encrypted object
    // The parameter represents the encryption algorithm
    Cipher cipher = Cipher.getInstance(algorithm);
    // Initialize encryption
    // First argument: encrypted mode
    // Second argument: encrypt with private key
    cipher.init(Cipher.ENCRYPT_MODE, key);
    // Private key encryption
    byte[] bytes = cipher.doFinal(input.getBytes());
    // Base64 encodes ciphertext
    return Base64.encode(bytes);
}

/** * decrypt data **@paramThe algorithm is *@paramEncrypted: ciphertext *@paramKey: key *@return {@link String}
 * @throwsThe Exception Exception * /
public static String decryptRSA(String algorithm, Key key, String encrypted) throws Exception {
    // Create an encrypted object
    // The parameter represents the encryption algorithm
    Cipher cipher = Cipher.getInstance(algorithm);
    // Decrypt the private key
    cipher.init(Cipher.DECRYPT_MODE, key);
    // Because the ciphertext is Base64 encoded, it needs to be decoded here
    byte[] decode = Base64.decode(encrypted);
    // To decrypt the ciphertext, you do not need to use Base64 because the original text is not garbled
    byte[] bytes1 = cipher.doFinal(decode);
    return new String(bytes1);

}
Copy the code

6 Digital Signature

Digital signature (also known as public key digital signature) is a digital string that can only be generated by the sender and cannot be forged by others. This digital string is also an effective proof of the authenticity of the message sent by the sender. It is a common physical signature similar to writing on paper, but implemented using techniques from the field of public key encryption, used to authenticate digital information. A set of digital signatures typically defines two complementary operations, one for signing and one for verification. Digital signature is the application of asymmetric key encryption technology and digital digest technology.

6.1 Introduction

I’m sure we’ve all written letters, and when we write letters, we always sign off with our name to show who the writer is. The words we sign are the signatures of life:

What about digital signatures? The idea is the same: when data is transferred over the network, a digital signature can be added to the data, indicating who sent it and proving that it hasn’t been tampered with.

OK, the main purpose of a digital signature is to ensure the validity of the data (verify who sent it) and integrity (verify that the information has not been tampered with). Let’s take a closer look at what the underlying implementation looks like.

6.2 Basic Principles

To make this clear, let’s go through the case step by step. Joe has two best friends, A and B. For work reasons, Both John and AB need to encrypt their emails for security. So Zhang SAN came up with digital signatures:

Here’s the whole idea:

The first step: encryption using asymmetric encryption, Zhang SAN has three keys, two public keys, to a friend. A private key for yourself.

Step 2: A or B sends an email to John: A encrypts the email with the public key, and John decrypts the email with the private key after receiving it.

Step 3: Zhang SAN writes an email to A or B:

(1) After zhang SAN writes the email, he first generates an abstract of the email with the hash function and attaches it to the article, which completes the digital signature. Then He uses the private key to encrypt the email. Then you can send it out.

(2) After receiving the email, A or B removes the digital signature and decrypts it using its own public key. At this time, if the digest in the digital signature is the same as that of John, it is considered to be sent by John. Then, the Hash function is used for the letter itself, and the result obtained is compared with the digest obtained in the previous step. If they agree, it means the letter hasn’t been redacted.

Let’s use a diagram to illustrate the above process:

First give the public key to friends A and B:

And the last one, which is A little tricky, is to send an email to A or B:

6.3 Digital Certificates

As mentioned above, we need public keys to verify signatures. If the public key is forged, then we cannot verify the digital signature, and it is impossible to determine the authenticity of the other party from the digital signature. That’s where the certificate comes in. We may all have the experience of testing various certificates, such as Putonghua certificate, cet-4 and CET-6 certificate and so on, but in the final analysis, to any occasion we can take out our certificate to prove that we have really passed the Test of Putonghua, cet-4 and CET-6. The same goes for certificates here.

If you do not understand the role of certificates, we can take an example, such as our graduation certificate, any company will recognize. Why did you admit it? Because it’s the state. Everybody trusts the state. So as long as it’s a national certification body, we trust it to be legitimate.

So how is this certificate generated? Let’s look at another picture:

Even if John’s friend A makes A mistake with the public key, John can still pass the certificate.

6.4 Web Encryption

Let’s look at an example of using the “digital certificate” protocol: HTTPS. This protocol is mainly used to encrypt web pages

First, the client sends an encryption request to the server.

The server encrypts the web page with its private key and sends it to the client, along with its digital certificate.

Certificate Manager of the client (browser) has a list of Trusted Root Certification Authorities. The client looks at the list to see if the public key to unlock the digital certificate is in the list.

If a digital certificate lists a web address different from the one you are currently viewing, the certificate may have been used fraudulently and the browser will issue a warning.

If the digital certificate is not issued by a trusted authority, the browser issues a different warning.

If the digital certificate is reliable, the client can use the server’s public key in the certificate to encrypt the information and then exchange the encrypted information with the server.

6.5 Code Implementation

@Test
public void test08(a) throws Exception {
    String a = "123";
    PublicKey publicKey = getPublicKey("a.pub"."RSA");
    PrivateKey privateKey = getPrivateKey("a.pri"."RSA");
    String signaturedData = getSignature(a, "sha256withrsa", privateKey);
    boolean b = verifySignature(a, "sha256withrsa", publicKey, signaturedData);
    System.out.println(b);//true
}

/** * Generate signature **@paramInput@paramThe algorithm is *@paramPrivateKey: privateKey *@return {@link String}
 * @throwsThe Exception Exception * /
private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception {
    // Get the signature object
    Signature signature = Signature.getInstance(algorithm);
    // Initializes the signature
    signature.initSign(privateKey);
    // Pass in the original text
    signature.update(input.getBytes());
    // Start signing
    byte[] sign = signature.sign();
    // Base64 encoding of signature data
    return Base64.encode(sign);
}

/** * Verify signature **@paramInput@paramThe algorithm is *@paramPublicKey: publicKey *@paramSignaturedData: indicates the signature *@return boolean
 * @throwsThe Exception Exception * /
private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception {
    // Get the signature object
    Signature signature = Signature.getInstance(algorithm);
    // Initializes the signature
    signature.initVerify(publicKey);
    // Pass in the original text
    signature.update(input.getBytes());
    // Verify data
    return signature.verify(Base64.decode(signaturedData));
}
Copy the code

7 Using keytool

Keytool Path: Java bin directory

Common commands

Generate keypair keytool -genkeypair keytool -genkeypair -alias lisi

Cer: keytool -list or keytool -list -v keytool -exportcert -alias lisi -file lisi.cer

Generate a printable certificate: keytool -exportcert -alias lisi -file lisi.cer -rfc

Cer command to display the certificate information in the digital certificate file: keytool -printcert -file Lisi. cer Double-click lisi.cer and run the Windows built-in program to open lisi.cer

Generate a private key public key

Generate a key certificate The following command generates a key certificate using the RSA algorithm. Each certificate contains public and private keys

Create a folder where you can run the following command:

keytool -genkeypair -alias chen -keyalg RSA -keypass chennn -keystore chen.jks -storepass chennn 
Copy the code

Keytool is a certificate management tool provided by Java

-alias: alias of the key -keyalg: hash algorithm used -keypass: access password of the key -keystore: file name of the keystore, xc.keystore stores the generated certificate -storepass: access password of the keystoreCopy the code

Querying certificate Information

keytool -list -keystore chen.jks
Copy the code

To delete an alias

keytool -delete -alias chen -keystore chen.jsk
Copy the code