如何在项目中保证用户数据安全-前后端亲测有效

源码地址

步骤:

比如用户修改密码:

  1. server端 生成base64编码后的公私钥
  2. server端 send base64编码后的私钥
  3. web端保存私钥
  4. server端随机生成16位字符串->私钥加密字符串->加密字符串->base64编码加密字符串(base64编码) response web
  5. web端解码base64编码加密字符串->加密字符串->用私钥解密加密字符串->原生字符串
  6. web端拼接字符串加密码->AES原生字符串加密前者(字符串加密码) send server
  7. server端对用AES加密字符串(包含密码)AES解密->校验原生字符串是否正确–>获取原生密码->加密入库
    部分demo:

RSA非对称加密工具类:

package cloud.xulehuang.example.password_security.非对称加密;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

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

/**
 * <p>
 *  rsa 加密工具
 */
public class RsaUtil {

    /**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * <p>
     * 生成密钥对(公钥和私钥)
     * </p>
     *
     * @return
     * @throws Exception
     */
    public static Map<String, Object> genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    /**
     * <p>
     * 用私钥对信息生成数字签名
     * </p>
     *
     * @param data 已加密数据
     * @param privateKey 私钥(BASE64编码)
     *
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        byte[] keyBytes = decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return encode(signature.sign());
    }

    /**
     * <p>
     * 校验数字签名
     * </p>
     *
     * @param data 已加密数据
     * @param publicKey 公钥(BASE64编码)
     * @param sign 数字签名
     *
     * @return
     * @throws Exception
     *
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {
        byte[] keyBytes = decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);
        return signature.verify(decode(sign));
    }

    /**
     * <P>
     * 私钥解密
     * </p>
     *
     * @param encryptedData 已加密数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
            throws Exception {
        byte[] keyBytes = decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * <p>
     * 公钥解密
     * </p>
     *
     * @param encryptedData 已加密数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
            throws Exception {
        byte[] keyBytes = decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * <p>
     * 公钥加密
     * </p>
     *
     * @param data 源数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey)
            throws Exception {
        byte[] keyBytes = decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * <p>
     * 私钥加密
     * </p>
     *
     * @param data 源数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
            throws Exception {
        byte[] keyBytes =decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * <p>
     * 获取私钥
     * </p>
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return encode(key.getEncoded());
    }

    /**
     * <p>
     * 获取公钥
     * </p>
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        System.out.println("base64编码前" + key.getEncoded());
        return encode(key.getEncoded());
    }


    /**
     * base64 加密
     * @param bytes
     * @return
     * @throws Exception
     */
    public static String encode(byte[] bytes) throws Exception {
        return new String(Base64.encodeBase64(bytes));
    }
    /**
     * base64 解密
     * @param base64
     * @return
     * @throws Exception
     */
    public static byte[] decode(String base64) throws Exception {
        return Base64.decodeBase64(base64.getBytes());
    }

    /**
     * @Description: 解密
     * @Param: [data, privateKey]
     * @return: java.lang.String
     * @Author: anxingtao
     * @Date: 2019-3-13 11:06
     */
    public static String decrypt(String data, String privateKey) throws Exception {
        byte[] pubdata = decryptByPrivateKey(decode(data), privateKey);
        return new String(pubdata, "UTF-8");
    }

    /**
     * @Description: 加密
     * @Param: [data, publicKey]
     * @return: java.lang.String
     * @Author: anxingtao
     * @Date: 2019-3-13 11:10
     */
    public static String encrypt(String data, String publicKey) throws Exception {
        byte[] pubdata = encryptByPublicKey(data.getBytes("UTF-8"), publicKey);
        String outString = new String(encode(pubdata));
        return outString;
    }

    /**
     * @title encrypriva
     * @description 私钥加密
     * @author Administrator
     * @updateTime 2021/8/11 16:31
     */
    public static String encrypk(String data, String privateKey) throws Exception {
        byte[] resdata = encryptByPrivateKey(data.getBytes("UTF-8"), privateKey);
        String outString = new String(encode(resdata));
        return outString;
    }

    /**
     * @title decrypk
     * @description 公钥解密
     * @author Administrator
     * @updateTime 2021/8/11 16:32
     */
   /* public static String decrypk(String data, String publicKey) throws Exception {
        byte[] resdata = decryptByPublicKey(decode(data), publicKey);
        return new String(resdata, "UTF-8");
    }*/


    public static void main(String[] args) throws Exception {
       /* String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALbGpPkikVf51rzHHr5rCmtIjpsq9Pked0W5xu5Khf4fQEl7utYahfC3dleFaCyLkD39Q1PpyOrQm7YQPSxkHR7Bn/w/CA93EYNKXG1cAZjDr/ZJAd6xUY2K4GkriWB9v4OeCTThkKwfharJJW270No5VT49ktKAHKkug/WnCUN7AgMBAAECgYEAlxPNK20qTFjj6biBLg5WV2VrEtFIGl7XYdf0meUZqnr0bYkLX4we6GENPby05hUaTlL4gvT8MTPrcWss1XOPKQYRrSjLBZmmCiYe+SDxx0ZPmNN1db86X0ahQsNzxAVkTyIKKVW1SxwyvIOSN5H71yyBzZj/yG0qymj8H0hBVFkCQQDijlLZ9E7pGT/2HLitxEyi02kIjlsgLtjmk8NP8if5eCspmKXaw3xH2j3BLOGDGZUjeQGZcyOOHdGnNkbUVSdtAkEAzoe6ugzr63r70CwbWAEBQLRUfX4i8fiLazlCybhVAMEKjbKTdcAUFLfKNmharPHE/dlHLja/dReaLMKB7l69hwJABcM/AkI/m5hD0zvJysm6dU3RVyFf2gK3C65ogmkTcToIRweV+GmOiLlZZseAePg2ne9fBgsytVO22Hz98jq0RQJAGOyOX0eR7RAhdYTtI9izMwDQNXjUdMke4ii946QoNfgV8vW7D/nHMpzffWNolfhzYoMnMO+QeWwIwiATGBY83wJBAN5aLGltsuW/6ILvMTgciwdQlO3dTjzFXhbXURsyKWYF6QJnaeqNMVqr9F0lWXKQyuIu+mj5JRkZszOvS0jczNA=\n";
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2xqT5IpFX+da8xx6+awprSI6bKvT5HndFucbuSoX+H0BJe7rWGoXwt3ZXhWgsi5A9/UNT6cjq0Ju2ED0sZB0ewZ/8PwgPdxGDSlxtXAGYw6/2SQHesVGNiuBpK4lgfb+Dngk04ZCsH4WqySVtu9DaOVU+PZLSgBypLoP1pwlDewIDAQAB";
        String msg = "{\"dev_id\":\"868989034328943\",\"user_id\":\"\",\"team_id\":\"\"}";
        //String msg = DateTimeUtil.getDate();
        String sm = RsaUtil.encrypt(msg,publicKey);
        System.out.println(sm);*/
        String str = "IGCJsmAEdYDle/WYAS4qd3hCp9TAZRz806Sm8p4KepJ2XuDaOnKh65homSgZJ88/pQs5rEm6Qmsg+8JqMgqjixD8jZhnToVriKzkhHe2UarS+sT8oUAvXrO98FwZv7GELgt4mCuitwxrREYq4QUtwI6Fc+SGdF0BjeKNUSWHifg=";
//
//
//
//        String s = RSAUtils.decrypt(sm,privateKey);
//        System.out.println(s);

        //生成密钥对(公钥和私钥)
        Map map = RsaUtil.genKeyPair();
        System.out.println("----------------公钥----------------");
        System.out.println(RsaUtil.getPublicKey(map));
        System.out.println("----------------私钥----------------");
        System.out.println(RsaUtil.getPrivateKey(map));

//        String str = RSAUtils.encrypk("我爱你中国",privateKey);
//        System.out.println(str);
//
//        String res = RSAUtils.decrypk(str,publicKey);
//        System.out.println(res);

//        String content = "F2cgqkTN1DehdikNnKtt5t0p+HrOr4hwWrbf9MGmksWUQFwWzFPbwt1at7uXYp8mt88KiIHrD/yKe8pkdzuq2VMTyvObryIbVannBHtzrhjBd2FoRQpaorMWtFuv7MZY3WmuqhzdhXMXAx1pB/hmEToncvW3ZpEWp7N5ItO89H8=";
//        String priKey = "MIICYQIBAAKBgQCijkoTGTel/S62WwUpXswc8m7Fdp+SY2ZMZKV8FeRD5QUi1mGYUHqmab7w/xN2vdNWI9sR9MPL4aO2IA57HD4HTGmidyCDmxl8QCRMSNwXroIP6mWpI5lHjajPth25n2gwsnYoAvrSfTnTkUAmoKUtQSg3/AZ9Rg8mf8NFY5AjGwIDAQABAoGBAJqS8W9NyHPn2DaBQNxBD5jrE1hj34NFT+6OuinPa1sAeSzSbMV4qdh6r53dADYmdcLwn41okZLbAmDaBBscUUZo/pIUPdGgU+P7RqpMtfwbq/RoleFpU2GWBErJ7/qKe6cfcEyuBhAMG8vLqtfA70P75vFAMoKhzWsUGtD5gQVZAkUAuRjD839QS/u17Xv6jWbcw0vxTD2UN/hyObyQORlX+LjxC5RCuYwkkWoXIGe94hzsyCoURc6RhakRM/LyqhCliTQ+PvcCPQDg0xUHm2qr8jfo1PTYf6Ks8Id9FZiqxD1VJh2OoRMSTCPo8O4PskbzictNu2siFLt0r3EKjCDP1jP0H/0CRFSsO5d8OiNINmU5PdjJoVvFtdCGqvMfuEEpPWChc1jYYYxGem+e6GuM+J9eVcLGMJswhK2aXX+jY7c8AD5D9zXYrFDpAj0Ap5OOXEIyy4FavRhmfCz+wyrxwoFjbv2gvaQQaeyTu5K3PXy/5UE783Ek8Yad/yQ26W2Ps43pMyF1TiS9AkQrfddTmrz7OZEfFtgaHuSj/8gbkGEdr7H8YIML/wZ1ozDkfxwsnzgclJXir/Qb2VjGOSzfUrlj2SaxgqIGfKI7DyEWeg==";
//        System.out.println(priKey);
//
//        String priKey2 = "MIICewIBADANBgkqhkiG9w0BAQEFAASCAmUwggJhAgEAAoGBAKKOShMZN6X9LrZbBSlezBzybsV2n5JjZkxkpXwV5EPlBSLWYZhQeqZpvvD/E3a901Yj2xH0w8vho7YgDnscPgdMaaJ3IIObGXxAJExI3Beugg/qZakjmUeNqM+2HbmfaDCydigC+tJ9OdORQCagpS1BKDf8Bn1GDyZ/w0VjkCMbAgMBAAECgYEAmpLxb03Ic+fYNoFA3EEPmOsTWGPfg0VP7o66Kc9rWwB5LNJsxXip2Hqvnd0ANiZ1wvCfjWiRktsCYNoEGxxRRmj+khQ90aBT4/tGqky1/Bur9GiV4WlTYZYESsnv+op7px9wTK4GEAwby8uq18DvQ/vm8UAygqHNaxQa0PmBBVkCRQC5GMPzf1BL+7Xte/qNZtzDS/FMPZQ3+HI5vJA5GVf4uPELlEK5jCSRahcgZ73iHOzIKhRFzpGFqREz8vKqEKWJND4+9wI9AODTFQebaqvyN+jU9Nh/oqzwh30VmKrEPVUmHY6hExJMI+jw7g+yRvOJy027ayIUu3SvcQqMIM/WM/Qf/QJEVKw7l3w6I0g2ZTk92MmhW8W10Iaq8x+4QSk9YKFzWNhhjEZ6b57oa4z4n15VwsYwmzCErZpdf6NjtzwAPkP3NdisUOkCPQCnk45cQjLLgVq9GGZ8LP7DKvHCgWNu/aC9pBBp7JO7krc9fL/lQTvzcSTxhp3/JDbpbY+zjekzIXVOJL0CRCt911OavPs5kR8W2Boe5KP/yBuQYR2vsfxggwv/BnWjMOR/HCyfOByUleKv9BvZWMY5LN9SuWPZJrGCogZ8ojsPIRZ6";
//
//        System.out.println(RSAUtils.decrypt(content,priKey2));
    }


}

AES对称加密工具类:

package cloud.xulehuang.example.password_security.对称加密;

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

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

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

public class AESUtil {

    private static String iv = "0123456789ABCDEF";//偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
    private static String Algorithm = "AES";
    private static String AlgorithmProvider = "AES/ECB/PKCS5Padding"; // 算法/模式/补码方式

    //暂时不用这里的,使用随机生成的字符串
    public static byte[] generatorKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
        keyGenerator.init(256);//默认128,获得无政策权限后可为192或256
        SecretKey secretKey = keyGenerator.generateKey();
        return secretKey.getEncoded();
    }

    public static IvParameterSpec getIv() throws UnsupportedEncodingException {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
        System.out.println("偏移量:"+byteToHexString(ivParameterSpec.getIV()));
        return ivParameterSpec;
    }


    /**
    * 加密
    * */
    public static byte[] AES_CBC_Encrypt(byte[]content, byte[] keyBytes){

        try{
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv.getBytes()));
            byte[]result=cipher.doFinal(content);
            return result;
        }catch (Exception e) {
            System.out.println("exception:"+e.toString());
        }
        return null;
    }


    /**
    * 解密
    * */
    public static byte[] AES_CBC_Decrypt(byte[]content, byte[] keyBytes){

        try{
            SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher  =Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv.getBytes()));
            byte[]result=cipher.doFinal(content);
            return result;
        }catch (Exception e) {
            // TODO Auto-generated catchblock
            System.out.println("exception:"+e.toString());
        }
        return null;
    }

    /**
     * 将byte转换为16进制字符串
     * @param src
     * @return
     */
    public static String byteToHexString(byte[] src) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xff;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append("0");
            }
            sb.append(hv);
        }
        return sb.toString();
    }

    /**
     * 将16进制字符串装换为byte数组
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] b = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return b;
    }

    /**
     * 字符串装换成base64
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return Base64.decodeBase64(key.getBytes());
    }

    /**
     *二进制装换成base64
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[]key) throws Exception {
        return new String(Base64.encodeBase64(key));
    }

    /**将16进制字符串转换为二进制字节数组
     * @param hexStr
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length()/2];
        for (int i = 0;i< hexStr.length()/2; i++) {
            int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
            int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    /**将二进制字节数组转换为16进制字符串
     * @param
     * @return
     */
    public static String parseByte2HexStr(byte buf[]){
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < buf.length; i++){
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

}

测试类:

package cloud.xulehuang.example.password_security;

import cloud.xulehuang.example.password_security.对称加密.AESUtil;
import cloud.xulehuang.example.password_security.非对称加密.RsaUtil;
import org.apache.commons.codec.binary.Base64;

import java.util.Map;
import java.util.UUID;

public class ExampleText {
    public static void main(String[] args) throws Exception {
        Map rsaMap = RsaUtil.genKeyPair();

        //获取公钥、私钥,私钥不断变化,应该将私钥实时更新到前端,或者把两者保存起来
        String rsaPublicKey = (String)RsaUtil.getPublicKey(rsaMap);
        System.out.println("base64编码的公钥:" + rsaPublicKey);
        String rsaPrivateKey =  (String)RsaUtil.getPrivateKey(rsaMap);
        System.out.println("base64编码的私钥:" +  rsaPrivateKey);

        //随机生成16位字符串
        String randomString = UUID.randomUUID().toString().substring(0, 16);
        System.out.println("随机生成的字符串:" + randomString);


        //公钥加密字符串
        String randomStringEncodeByDecodeRsaPublicKey = RsaUtil.encrypt(randomString, rsaPublicKey);
        System.out.println("公钥加密的随机生成的字符串:" + randomStringEncodeByDecodeRsaPublicKey);

        //编码加密字符串,送到客户端
        String randomStringEncodeByDecodeRsaPublicKeyWithBase64 = new String(Base64.encodeBase64(randomStringEncodeByDecodeRsaPublicKey.getBytes()), "UTF-8");
        System.out.println("base64编码的公钥加密的随机生成的字符串:" + randomStringEncodeByDecodeRsaPublicKeyWithBase64);

        //客户端解码,得到加密字符串
        String randomStringDecodeByDecodeRsaPublicKeyWithBase64 = new String(Base64.decodeBase64(randomStringEncodeByDecodeRsaPublicKeyWithBase64) , "UTF-8");
        System.out.println("base64解码的公钥加密的随机生成的字符串:" + randomStringDecodeByDecodeRsaPublicKeyWithBase64);

        //私钥解密加密字符串
        String originRandomString = RsaUtil.decrypt(randomStringDecodeByDecodeRsaPublicKeyWithBase64, rsaPrivateKey);
        System.out.println("私钥解密加密的字符串:" + originRandomString);;

        //AES解密字符串
        byte[] originRandomStringAndPassword = AESUtil.AES_CBC_Decrypt(Base64.decodeBase64("KlQGSJEJtnRaWyCRVVD+3fOo82Sp/vSqffae7+xNERQ=") ,"25a725ea-4782-44".getBytes());
        System.out.println("AES解密的包含随机字符串和密码的加密字符串" + new String(originRandomStringAndPassword , "UTF-8"));
    }
}

前端:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script th:src="@{/password_security/crypto-js-develop/src/rsa.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/crypto-js.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/core.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/evpkdf.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/cipher-core.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/enc-base64.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/enc-base64url.js}"></script>
    <script th:src="@{/password_security/crypto-js-develop/src/enc-utf16.js}"></script>
    <!--<script src="https://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script>-->
</head>
<body>

</body>
<script>
    var encrypt = new JSEncrypt();
    //获取私钥
    var private = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMWsnge1ll+ze0CuWLcRw58OY2GAUKAXC1GA15EvroIY4O+T6C3DL7ZtWs2NbOhFn4Ps6upDANvIjhMQfhKb9qdVGBS4elXTPAaV8mM5FHeUAsum6YCuwSSVA9boyvqeN8oeTCrhw4iLcabfoWpeZzV4wXlkWkhSMn6aTs7MPrevAgMBAAECgYBuOx486lQatfmrTg4GuI8/6UQeIPHU9ETJhHGxcsd7oOf+cZptuoSm1EBok88Bj6GubbVqQUb/SM2BcBb9xZ87H+MkGXtDZIlCgosWsLvjkVFMUzjg8hlhI2bnhmWGyMguK0CRAHXGzXpYN1VaD/b2ig2PphsRmi21vTgGzv8VwQJBAP8xXiCheAu3wdm/1VOLgac4n9DmSVA2QLqziOTR3WU/I8o6h2Stq27W3UtTRZRb7Gx6weI+DIDTWlOpa2Mm9pECQQDGTK0eQtRzRYL0K1ENtfxf//FwktfNULaDBMkm64fK4ECJn3xIPDaqzzpfvmTcTjv/bbjXbLGTM4QVAtxykGo/AkEA55aSuIQwoFmz53uLClV5ZRsjFf5XHB8QIR8bJaU7CU4Cmd0B0CE3idAeZeR9KYU+irfgygPLbwHfYDtJBGNwsQJBAKlmg1WgncFDlpVkE7/0wX55NRaIO1aoJuJSSky3VK/ZVwi6d/91gPX2RdXY3mzdYJ/aadeOgTxQ+/q/EPfFqx0CQHK3+ql2gEy/sCaXxkK6TnpP7MATmEYQl1sO4xbjhZ2lQ8mul1vTBEQVIohgMy2uoOoxuywGMZZBoHYq1Y4r6IE=\n"
    //var public = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrDysnndm5BjfWlc4jaBqkRyf7rtpBAga2u14Fv1XGlLqa7swTuqVPinUBMGPXufII0NNv8C/b99ZYsrhZMNIkYhUuWeCsPDvsSjcdUhwuwGSnjWw2l2Q4z40o7s8AgeUSlEH1xRNrcZKzVQiT+jhxtl8KMpZWiLAZojLzp0NDdQIDAQAB\n"
    //encrypt.setPublicKey(private)
    encrypt.setPrivateKey(private)

    //解码base64加密字符串
    var randomStringEncodeByDecodeRsaPublicKeyWithBase64 = "RWRFbWZJQURublNZT2dlMzVwQ0RJTldqNUIrRTN3V3ZGYmxsR1BiQmQyaDNLS2xoTFhnK1FPRG1zNm9VSWZsSzZ5cUVHeFhndnN1dVI4ZTkzU3Njbko3ZVAweGF4VXExZFIrMnM0K1BicXo0SmxEOUNKWVdoeGVzVWpMQ2lvbnVrWEFqbTZMalMxZVl1ZWQvRDFpYlJMdFVPWXlxVzZEUE1Ed0xBL0NsSHJvPQ==\n";
    var randomStringDecodeByDecodeRsaPublicKeyWithBase64 = window.atob(randomStringEncodeByDecodeRsaPublicKeyWithBase64).toString();

    console.log("解码base64加密字符串:" + randomStringDecodeByDecodeRsaPublicKeyWithBase64)

    //私钥解密字符串
    var originRandomString = encrypt.decrypt(randomStringDecodeByDecodeRsaPublicKeyWithBase64);
    console.log("原生字符串" + originRandomString)

    //密码加字符串,AES对称加密,以原生字符串作密钥

    //1.偏移值保持与后端相同
    var iv  = CryptoJS.enc.Utf8.parse("0123456789ABCDEF");

    //2.原生字符串+密码 为内容,原生字符串作密钥,AES加密
    var password = "123";
    var aesEncrypt = CryptoJS.AES.encrypt(originRandomString+password,   CryptoJS.enc.Utf8.parse(originRandomString),{
        iv:iv,
        mode:CryptoJS.mode.CBC,
        padding:CryptoJS.pad.Pkcs7
    });

    //直接给这个给后端,返回的是base64
    console.log("AES加密后aesEncrypt = %s"+aesEncrypt.toString())
    /*console.log(aesEncrypt.iv.toString(CryptoJS.enc.Base64))*/

    var aesDecrypt = CryptoJS.AES.decrypt(aesEncrypt, CryptoJS.enc.Utf8.parse(originRandomString) , {
        iv:iv,
        mode:CryptoJS.mode.CBC,
        padding:CryptoJS.pad.Pkcs7
    });
    console.log("AES解密后aesDecrypt = %s", aesDecrypt.toString(CryptoJS.enc.Utf8));

    //base64编码
    let decodeByBase64 = window.btoa(aesEncrypt);
    console.log("base64编码AES加密字符串:" + decodeByBase64)
   /* console.log(hex_to_bin(s))*/

   /* function hex_to_bin(str) {
        let hex_array = [{key:0,val:"0000"},{key:1,val:"0001"},{key:2,val:"0010"},{key:3,val:"0011"},{key:4,val:"0100"},{key:5,val:"0101"},{key:6,val:"0110"},{key:7,val:"0111"},
            {key:8,val:"1000"},{key:9,val:"1001"},{key:'a',val:"1010"},{key:'b',val:"1011"},{key:'c',val:"1100"},{key:'d',val:"1101"},{key:'e',val:"1110"},{key:'f',val:"1111"}]

        let value=""
        for(let i=0;i<str.length;i++){
            for(let j=0;j<hex_array.length;j++){
                if(str.charAt(i).toLowerCase()== hex_array[j].key){
                    value = value.concat(hex_array[j].val)
                    break
                }
            }
        }
        console.log(value)
        return value
    }*/
</script>
</html>