Use of RSA encryption (front and back ends)

Public key (publicKey) encryption, private key (privateKey) decryption. Cannot be reversed, private key (privateKey) encryption, public key (publicKey) decryption. To put it bluntly, both the front and back ends need to use the public key (publicKey) for encryption and the private key (privateKey) for decryption.

Introducing the front-end JS library: jsencrypt.js

npm install jsencrypt

Use

The backend generates the RSAUtil tool class

public class RSAUtil {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
     * Randomly generate key pair
     *
     * @param filePath The path where the key pair is to be stored
     */
    public static void genKeyPair(String filePath) {
// The KeyPairGenerator class is used to generate public and private key pairs and generate objects based on the RSA algorithm.
KeyPairGenerator keyPairGen = null;
try {
keyPairGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Initialize the key pair generator, the key size is 96-1024 bits
keyPairGen.initialize(1024, new SecureRandom());
// Generate a key pair and save it in keyPair
KeyPair keyPair = keyPairGen.generateKeyPair();
// Get the private key
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// Get the public key
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
try {
// Get the public key string
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
// Get the private key string
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
//Write key pair to file
FileWriter pubfw = new FileWriter(filePath + "/publicKey.key");
FileWriter prifw = new FileWriter(filePath + "/privateKey.key");
BufferedWriter pubbw = new BufferedWriter(pubfw);
BufferedWriter pribw = new BufferedWriter(prifw);
pubbw.write(publicKeyString);
pribw.write(privateKeyString);
pubbw.flush();
pubbw.close();
pubfw.close();
pribw.flush();
pribw.close();
prifw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

    /**
     * Remove redundant information from the key
     *
     * @param key public key or private key string
     * @return Base64 key base 64 key
     */
    public static String getBase64Key(String key) {
key = key.replaceAll("-----BEGIN (.*)-----", "");
key = key.replaceAll("-----END (.*)----", "");
key = key.replaceAll("\r\
", "");
key = key.replaceAll("\
", "");
return key;
}
    /**
     * Load key from file
     *
     * @param fileName The file name of the public or private key
     * @return the key in string form, removing -----BEGIN (.*)----- and other redundant information
     */
    public static String loadKeyFromFile(String fileName) {
byte[] keyBytes = loadRawKeyFromFile(fileName);

// convert to format
return getBase64Key(new String(keyBytes));
}

    /**
     * Load key from file
     *
     * @param fileName The file name of the public or private key
     * @return key in string form byte []
     */
    public static byte[] loadRawKeyFromFile(String fileName) {
InputStream resourceAsStream = RSAUtil.class.getClassLoader().getResourceAsStream(fileName);
DataInputStream dis = new DataInputStream(resourceAsStream);
byte[] keyBytes = null;
try {
keyBytes = new byte[resourceAsStream.available()];
dis.readFully(keyBytes);
dis.close();
} catch (IOException e) {
throw new SystemException("Failed to load public key from file '" + fileName + "'", e);
}
return keyBytes;
}

    /**
     * Load private key by str rsa private key.
     * Load the secret key
     * @param privateKeyStr the private key str
     * @return the rsa private key
     */
    public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr) {
try {
byte[] buffer = Base64.getDecoder().decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); // KeyFactory.getInstance("RSA");
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new SystemException("No such algorithm", e);
} catch (InvalidKeySpecException e) {
throw new SystemException("Illegal private key", e);
} catch (NullPointerException e) {
throw new SystemException("Private key data is empty", e);
} catch (NoSuchProviderException e) {
throw new SystemException("no such provider: RSA, BC", e);
}
}

 /**
     * Public key encryption process
     *
     * @param publicKey public key
     * @param plainTextData plain text data
     * @return ciphertext byte [ ]
     */
    public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) {
if (publicKey == null) {
throw new SystemException("The encryption public key is empty");
}
Cipher cipher = null;
try {
// Use default RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new SystemException("No such encryption algorithm", e);
} catch (NoSuchPaddingException e) {
throw new SystemException("No such encryption algorithm", e);
} catch (InvalidKeyException e) {
throw new SystemException("The encryption public key is illegal, please check", e);
} catch (IllegalBlockSizeException e) {
throw new SystemException("Illegal plaintext length", e);
} catch (BadPaddingException e) {
throw new SystemException("Plain text data is damaged", e);
}
}

    /**
     * Private key encryption process
     *
     * @param privateKey private key
     * @param plainTextData plain text data
     * @return ciphertext byte [ ]
     * @throws Exception Exception information during the encryption process
     */
    public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData) throws Exception {
if (privateKey == null) {
throw new SystemException("The encryption private key is empty");
}
Cipher cipher = null;
try {
// Use default RSA
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");// Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] output = cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new SystemException("No such encryption algorithm", e);
} catch (NoSuchPaddingException e) {
throw new SystemException("There is no such filling mechanism in the system", e);
} catch (InvalidKeyException e) {
throw new SystemException("The encryption private key is illegal, please check", e);
} catch (IllegalBlockSizeException e) {
throw new SystemException("Illegal plaintext length", e);
} catch (BadPaddingException e) {
throw new SystemException("Plain text data is damaged", e);
}
}

    /**
     * Private key decryption process
     *
     * @param privateKey private key
     * @param cipherData ciphertext data
     * @return plain text byte [ ]
     */
    public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) {
if (privateKey == null) {
throw new SystemException("The decryption private key is empty");
}
Cipher cipher = null;
try {
// Use default RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] output = cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new SystemException("No such decryption algorithm", e);
} catch (NoSuchPaddingException e) {
throw new SystemException("There is no such filling mechanism in the system", e);
} catch (InvalidKeyException e) {
throw new SystemException("The decryption private key is illegal", e);
} catch (IllegalBlockSizeException e) {
throw new SystemException("Illegal ciphertext length");
} catch (BadPaddingException e) {
throw new SystemException("The ciphertext data is damaged", e);
}
}

    /**
     * Public key decryption process
     *
     * @param publicKey public key
     * @param cipherData ciphertext data
     * @return plain text byte [ ]
     * @throws Exception Exception information during the decryption process
     */
    public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData) throws Exception {
if (publicKey == null) {
throw new SystemException("The decryption public key is empty");
}
Cipher cipher = null;
try {
// Use default RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new SystemException("No such decryption algorithm", e);
} catch (NoSuchPaddingException e) {
throw new SystemException("There is no such filling mechanism in the system", e);
} catch (InvalidKeyException e) {
throw new SystemException("The decryption public key is illegal", e);
} catch (IllegalBlockSizeException e) {
throw new SystemException("Illegal ciphertext length");
} catch (BadPaddingException e) {
throw new SystemException("The ciphertext data is damaged");
}
}

Front-end encryption

const JSEncrypt = window.JSEncrypt;

export function rsa(str) {
  const jse = new JSEncrypt();
  const { publicKey } = xxx;//Get publicKey from the backend interface
  jse.setPublicKey(publicKey);
  return jse.encrypt(str)
}


export default function(str) {
  return rsa(str)
}

export const decrypt = async str => {
  return new Promise((resolve, reject) => {
    Backend decryption interface (str)
      .then(res => {
        if (res.data.code === "success") {
          resolve(res.data.data);
        } else {
          reject(res);
        }
      })
      .catch(err => {
        reject(err)
      });
  })
}



Backend decryption interface

//eg: The backend obtains the publicKey interface
@GetMapping("getRsaPublicKey")
public ResultResp<String> getRsaPublicKey() {
    String key = RSAUtil.loadKeyFromFile("rsaPublicKey.key");
    return success(key);
}

//eg: backend decryption interface
@GetMapping("getDecryptRsaPwd")
public Result<Object> getDecryptRsaPwd(String rsaPwd) {
    //Process the incoming string and change the spaces to "+" signs
    String s = rsaPwd.replaceAll(" + ", " + ");
    String privateKeyStr = RSAUtil.loadKeyFromFile("rsaPrivateKey.key");
     // rsa decryption
     byte[] cipherData = Base64.getDecoder().decode(rsaPwd);
     byte[] xpwd = RSAUtil.decrypt(RSAUtil.loadPrivateKeyByStr(privateKey), cipherData);
     String decryptRsaPwd = new String(xpwd);
    return Result.success(decryptRsaPwd);
}

Use

import encrypt, { decrypt } from '@/utils/xxx;//Introduce the front-end front-end file written above
//encrypt password
data.password = encrypt(data.password);
//Decrypt
decrypt(this.password).then(clearText => {
  this.model.password = clearText
})