Encryption method: symmetric and asymmetric encryption

Posted by Jene200 on Wed, 29 Dec 2021 02:49:31 +0100

catalogue

Symmetric encryption

Asymmetric encryption

Code example

Software applications inevitably need data interaction and storage, especially data transmission through the Internet. In some scenarios, data can be transmitted in clear text; In some scenarios, even if the data is plaintext, it is necessary to avoid data tampering during transmission, such as order information; In some scenarios, data cannot be transmitted and stored in clear text, such as login information. In these scenarios, the solution is signature or encryption, so it involves the choice of encryption method and algorithm. The text introduces symmetric and asymmetric encryption, as well as the use of java and js.

Symmetric encryption

Encryption and decryption use the same key, that is, both ends of the data interaction hold the same key.

encryption algorithm

AESSymmetric / block ciphers are generally divided into stream encryption (such as OFB, CFB, etc.) and block encryption (such as ECB, CBC, etc.). For stream encryption, the block cipher needs to be converted to stream mode. For block encryption (or packet encryption), if you want to encrypt data that exceeds the block size, you need to involve filling and chain encryption modes.

Usage scenario

Generate data signature to avoid data tampering:

Simultaneous interpreting the data set, the client will sort the data according to the data name, and use the key and order set to generate the signature. The signature will be transmitted to the server together with the data set.

After receiving the data set, the server generates a signature according to the same rules and compares the transmitted signatures to avoid data tampering.

 

Asymmetric encryption

Each user has two secret keys. The public secret key is called the public key, and the secret key he keeps is called the private key.

Usage scenario

A has the public key of B, and B has the public key of A.

A encrypts the information with B's public key and signs with the private key; B uses a's public key to verify the signature, and B uses the private key to decrypt the message.

effect

  • Communication security of insecure network
  • Information encryption and decryption
  • Verify the authenticity of the information source through the public key of the information sender
  • Digital signature ensures that the sender cannot deny that the message has been sent

shortcoming

Due to the complexity of the algorithm, the encryption and decryption speed is much slower (thousands of orders of magnitude) than the symmetric encryption algorithm.

encryption algorithm

RSAThe principle of RSA public key cryptosystem is: according to number theory, it is simple to find two large prime numbers, but it is extremely difficult to factorize their product. Therefore, the product can be used as an encryption key
Elgamal
Knapsack algorithm
Rabin

Code example

java uses symmetric encryption

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

import org.apache.commons.codec.binary.Base64;

/**
 * @author ChenHailong
 * @date 2020/10/10 17:14
 **/
public class AESCoder {
    /**
     * encryption
     * @param content Content to be encrypted
     * @param secretKeyStr AES key used for encryption, BASE64 encoded string
     * @param iv Initialization vector, 16 bytes in length, 16 * 8 = 128 bits
     * @return The encrypted ciphertext is returned after BASE64 processing
     */
    public static String encryptAES(byte[] content, String secretKeyStr, String iv)
            throws Exception {
        // Get a secret keyspec
        // SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(secretKeyStr), "AES");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyStr.getBytes(), "AES");
        // Get Cipher object of encryption algorithm instance
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //"Algorithm / mode / complement mode"
        // Get an IvParameterSpec
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());  // Using CBC mode requires a vector iv, which can increase the strength of the encryption algorithm
        // Initialization algorithm according to parameters
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        // Perform encryption and return the ciphertext after passing through the assistant at BASE64
        return new Base64().encodeToString(cipher.doFinal(content));
    }

    /**
     * decrypt
     * @param content: The content to be decrypted is a byte array encoded by BASE64
     * @param secretKeyStr: AES key used for decryption, BASE64 encoded string
     * @param iv: Initialization vector, length 16 bytes, 16 * 8 = 128 bits
     * @return The decrypted plaintext directly returns the plaintext converted by UTF-8 encoding
     */
    public static String decryptAES(byte[] content, String secretKeyStr, String iv) throws Exception {
        // The ciphertext is decrypted by BASE64
        byte[] contentDecByBase64 = new Base64().decode(content);
        // Get a secret keyspec
        // SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(secretKeyStr), "AES");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyStr.getBytes(), "AES");
        // Get Cipher object of encryption algorithm instance
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //"Algorithm / mode / complement mode"
        // Get an initialization IvParameterSpec
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        // Initialization algorithm according to parameters
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        // decrypt
        return new String(cipher.doFinal(contentDecByBase64), "utf8");
    }
}

js uses symmetric encryption

var encrypt = function (_content) {
  var _key = getKey()
  var _iv = getIv(_key)
  // First, return any type with UTF-8 encoding and decoding parameters
  let content = CryptoJS.enc.Utf8.parse(_content);
  let aesKey = CryptoJS.enc.Utf8.parse(_key);
  let iv = CryptoJS.enc.Utf8.parse(_iv);

  // encryption
  let encrypted = CryptoJS.AES.encrypt(content, aesKey, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })

  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}

java uses asymmetric encryption

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import static com.chl.victory.core.util.Base64Util.decryptBASE64Bytes;
import static com.chl.victory.core.util.Base64Util.encryptBASE64Bytes;

/**
 * RSA Asymmetric encryption
 */
public class RSACoder {
     static final String KEY_ALGORITHM = "RSA";
     static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    /**
     * Generate a digital signature on the information with the private key
     *
     * @param data       Encrypted data
     * @param privateKey Private key
     * @return
     */
    public static String sign(byte[] data, String privateKey){
        try{
            // Decrypt the private key encoded by base64
            byte[] keyBytes = decryptBASE64Bytes(privateKey);
            // Construct PKCS8EncodedKeySpec object
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            // KEY_ALGORITHM specifies the encryption algorithm
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // Private key object
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // Generate a digital signature on the information with the private key
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(priKey);
            signature.update(data);
            return encryptBASE64Bytes(signature.sign());
        }catch (Exception e){
        }
        return null;
    }

    /**
     * Verify digital signature
     *
     * @param data      Encrypted data
     * @param publicKey Public key
     * @param sign      digital signature 
     * @return If the verification is successful, return true and if it fails, return false
     */
    public static boolean verify(byte[] data, String publicKey, String sign){
        try{
            // Decrypt the public key encoded by base64
            byte[] keyBytes = decryptBASE64Bytes(publicKey);
            // Construct X509EncodedKeySpec object
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            // KEY_ALGORITHM specifies the encryption algorithm
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // Public key object
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(pubKey);
            signature.update(data);
            // Verify whether the signature is normal
            return signature.verify(decryptBASE64Bytes(sign));
        }catch (Exception e){
        }
        return false;
    }

    /**
     * Decrypt with private key
     * @param data base64 byte []
     * @param privateKey Private key
     * @return byte [] of decrypted plaintext
     */
    static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception{
        // Decrypt key
        byte[] keyBytes = decryptBASE64Bytes(privateKey);
        // Get private key
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key _privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // Decrypt data
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, _privateKey);
        return cipher.doFinal(data);
    }

    /**
     * Decrypt with private key
     * @param data base64 Formal ciphertext
     * @param privateKey Private key
     * @return Decrypted plaintext
     */
    public static String decryptByPrivateKey(String data, String privateKey){
        try {
            return new String(decryptByPrivateKey(decryptBASE64Bytes(data),privateKey));
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * Encrypt with public key
     *
     * @param data Plaintext to be encrypted byte []
     * @param key Public key
     * @return Encrypted byte []
     * @throws Exception
     */
    static byte[] encryptByPublicKey(byte[] data, String key)
            throws Exception {
        // Decrypt public key
        byte[] keyBytes = decryptBASE64Bytes(key);
        // Get public key
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicKey = keyFactory.generatePublic(x509KeySpec);
        // Encrypt data
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * Encrypt with public key
     *
     * @param data Plaintext to be encrypted
     * @param key Public key
     * @return Encrypted base64 form
     */
    public static String encryptByPublicKey(String data, String key){
        try {
            return encryptBASE64Bytes(encryptByPublicKey(data.getBytes(), key));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Generate a new pair of keys
     *
     * @throws Exception
     */
    public static RSAStrKeyPair genNewKeyPair(){
        try{
            KeyPairGenerator keyPairGen = KeyPairGenerator
                    .getInstance(KEY_ALGORITHM);
            keyPairGen.initialize(1024);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            String publicK = encryptBASE64Bytes(keyPair.getPublic().getEncoded());
            String privateK = encryptBASE64Bytes(keyPair.getPrivate().getEncoded());
            return new RSAStrKeyPair(privateK, publicK);
        }catch (Exception e){
        }
        return null;
    }
}

js uses asymmetric encryption

// jsencrypt.min.js
var pubKey = xxxx
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
var encryptedPass = encrypt.encrypt(pass);

 

 

Topics: security