Introduction to encryption and decryption


Encryption and decryption is nothing more than ensuring data security. Three problems need to be solved to ensure data security:
Confidentiality, integrity, authentication (anti forgery and denial)

  • Confidentiality: the transmission content is not in clear text. Even if the data is intercepted by the outside world, it cannot be interpreted or cracked by others.

  • Integrity: the content cannot be tampered with during transmission. If the information is tampered or incomplete, the receiver can know.

  • Authentication (anti forgery and denial): the receiver can verify the actual sender of the data to ensure that the data is not forged by "impersonation".

After a general understanding of these three problems, let's solve them:

2, Confidentiality

2.1 basic concepts

Plaintext: data that everyone can understand.
Ciphertext: data that only a specific person can understand through a specific tool.
Algorithm: it is the process of converting plaintext and ciphertext, that is, encryption and decryption.

2.2 classification

Symmetric encryption
Asymmetric encryption

2.2. 1 symmetric encryption

Symmetric encryption refers to the encryption algorithm that uses the same key for encryption and decryption, also known as the traditional cryptographic algorithm. That is, the encryption secret key can be calculated from the decryption key, and the decryption key can also be calculated from the encryption key. In most symmetric algorithms, the encryption key and decryption key are the same

Disadvantages:

The security of symmetric algorithm depends on the key. Revealing the key may make anyone encrypt and decrypt the message

Common symmetric encryption algorithms

There are des, AES, 3DES, RC2, RC4 and RC5, etc.

2.2. 2 asymmetric encryption

Asymmetric encryption requires two keys: public key and private key. Public key and private key are a pair.

The public key encrypts the data, and only the corresponding private key can decrypt it;
The private key encrypts the data and can only be decrypted with the corresponding public key.
So this algorithm is called asymmetric encryption algorithm.

The basic process of asymmetric encryption algorithm to realize confidential information exchange is: Party A generates a pair of keys and discloses one of them to other parties as a public key; If Party B obtains the public key, use the key to encrypt the confidential information and then send it to Party A; Party A shall decrypt the encrypted information with another private key saved by itself.

Common asymmetric encryption algorithms:

RSA, DSA, ECC, etc.

The following is an example of RSA algorithm code

The process of RSA algorithm generating public-private key pair, public key encryption and private key decryption:

public class RSAEncrypt {

    final static Base64.Decoder decoder = Base64.getDecoder();
    final static Base64.Encoder encoder = Base64.getEncoder();

    /**
     * RSA Public key encryption
     * @param str Encrypted string
     * @param publicKey Public key
     * @return ciphertext
     * @throws Exception  Abnormal information during encryption
     */
    public static String encrypt( String str, String publicKey ) throws Exception{
        //base64 encoded public key
        byte[] decoded = decoder.decode(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
                .generatePublic(new X509EncodedKeySpec(decoded));
        //RSA encryption
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = encoder.encodeToString(cipher.doFinal(str
                .getBytes("UTF-8")));
        return outStr;
    }

    /**
     * RSA Private key decryption
     * @param str Encrypted string
     * @param privateKey Private key
     * @return Plaintext
     * @throws Exception Abnormal information during decryption
     */
    public static String decrypt(String str, String privateKey) throws Exception{
        //base64 decoded string
        byte[] inputByte =  decoder.decode(str.getBytes("UTF-8"));
        //base64 encoded private key
        byte[] decoded =  decoder.decode(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA decryption
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    //Generate key pair
    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        //It can be understood that the length of the encrypted ciphertext is smaller than that of the original text. The larger the length, the slower the encryption and decryption
        keyGen.initialize(512);
        KeyPair keyPair = keyGen.generateKeyPair();
        return keyPair;
    }

    public static Map<Integer, String>  genKeyPair() throws Exception {
        Map<Integer, String> keyMap = new HashMap<Integer, String>();
        //Generate public-private key pair
        KeyPair keyPair = getKeyPair();
        PublicKey publicKey =  keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String publicKeyString = encoder.encodeToString(publicKey.getEncoded());
        // Get private key string
        String privateKeyString = encoder.encodeToString(privateKey.getEncoded());
        // Save public and private keys to Map
        keyMap.put(0,publicKeyString);  //0 represents the public key
        keyMap.put(1,privateKeyString);  //1 indicates the private key
        return keyMap;
    }
}

 /**
 * Test RSA encryption and decryption
 */
@Test
public void test1() throws Exception {
    Map<Integer, String> keyMap = RSAEncrypt.genKeyPair();
    String content = "I'm the data to be encrypted";
    System.out.println("The randomly generated public key is:" + keyMap.get(0));
    System.out.println("The randomly generated private key is:" + keyMap.get(1));
    String messageEn = RSAEncrypt.encrypt(content,keyMap.get(0));
    System.out.println("The encrypted string is:" + messageEn);
    String messageDe = RSAEncrypt.decrypt(messageEn,keyMap.get(1));
    System.out.println("The decrypted string is:" + messageDe);

}

3, Integrity

Information integrity is mainly realized by extracting and comparing message summaries.

  • Message summary: it is to extract information from the original data according to certain operation rules.
  • The length of the message digest is always fixed,
  • It can uniquely identify a piece of data.

Common summary algorithms:

sha1, sha256, md5, crc32, etc.

Verification process:

The sender and receiver can agree to use the same digest algorithm to digest the original text.
If the message summaries obtained by both parties are consistent, it indicates that the data has not been tampered with.

The following example demonstrates the SHA256 digest algorithm:

public class SHA256 {

    /**
     * Implement SHA256 encryption
     * @param str Encrypted message
     * @return
     */
    public static String getSHA256(String str) {
        MessageDigest messageDigest;
        String encodestr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodestr = byte2Hex(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodestr;
    }

    private static String byte2Hex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }
}

/**
 * Test SHA256 digest algorithm
 */
@Test
public void test2() throws Exception {
    String content = "I am the text content";
    System.out.println(content + ": The string after the first summary is:" + SHA256.getSHA256(content));
    System.out.println(content + ": The string after the second summary is:" + SHA256.getSHA256(content));
}

4, Authentication

Previously, we have guaranteed the confidentiality and integrity of the data. There are still some problems:

  • To verify the integrity of the message, the receiver must obtain the summary generated by the sender. If the third party knows the summary algorithm, the summary can also be forged, so the summary itself needs to be encrypted.

  • How to determine the source of the message and how to determine that it is not forged by a third party?

The sender uses the digest algorithm to generate the digest of the original message, then encrypts the digest with the private key to generate a digital signature, and then transmits the content with the digital signature.

After receiving the message, the receiver decrypts the digital signature with the sender's public key (the authentication of the sender is completed if the decryption is successful), obtains summary A, and then uses the summary algorithm to generate summary B for the original text. Compare whether summaries A and B are the same. If they are the same, it means that the content has not been tampered with.

The following example demonstrates the signature and signature verification process using SHA1 as the summary algorithm and RSA as the signature encryption algorithm Add the following code to Java:

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

/**
 * RSA autograph
 * @param content Data to be signed
 * @param privateKey Private key
 * @param input_charset Coding format
 * @return Signature value
 */
public static String sign(String content, String privateKey, String input_charset) {
   try {
      PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decoder.decode(privateKey));
      KeyFactory keyf = KeyFactory.getInstance("RSA");
      PrivateKey priKey = keyf.generatePrivate(priPKCS8);
      Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
      signature.initSign(priKey);
      signature.update(content.getBytes(input_charset));
      byte[] signed = signature.sign();
      return encoder.encodeToString(signed);
   } catch (Exception e) {
      e.printStackTrace();
   }
   return null;
}

/**
 * RSA Signature check
 * @param content Data to be signed
 * @param sign Signature value
 * @param public_key Public key
 * @param input_charset Coding format
 * @return Boolean value
 */
public static boolean verify(String content, String sign, String public_key, String input_charset) {
   try {
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      byte[] encodedKey = decoder.decode(public_key);
      PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
      Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
      signature.initVerify(pubKey);
      signature.update(content.getBytes(input_charset));
      boolean bverify = signature.verify(decoder.decode(sign));
      return bverify;
   } catch (Exception e) {
      e.printStackTrace();
   }
   return false;
}

The test method is as follows:

/**
 * Test SHA1WithRSA signature and verify signature
 */
@Test
public void test3() throws Exception {

    Map<Integer, String> akeyMap = RSAEncrypt.genKeyPair();//Party a key pair
    System.out.println("Randomly generated a Party public key is:" + akeyMap.get(0));
    System.out.println("Randomly generated a Party private key is:" + akeyMap.get(1));

    String content = "I am the text content to be tested";

    System.out.println("------------a towards b Sending data, using a Generate a signature using your private key-----------");
    String signature = RSAEncrypt.sign(content, akeyMap.get(1), "utf-8");
    System.out.println("original text:'" +content+ "'Generate signature:" + signature);

    System.out.println("----------b Received a Data sent, using a Public key verification signature-----------");
    if (RSAEncrypt.verify(content, signature, akeyMap.get(0), "utf-8")) {
        System.out.println("Signature verification succeeded:" + signature);
    } else {
        System.out.println("Failed to verify signature!");
    }
}

5, Summary

Through the encryption algorithm to encrypt and decrypt the original data, we can ensure the confidentiality in the process of data transmission.

Through the digital signature mechanism, we can not only ensure the data integrity, but also authenticate the data source.

Keywords: network security Encryption

Added by genie on Sat, 25 Dec 2021 23:12:54 +0200