精华内容
下载资源
问答
  • 基于.Net的MVC模拟登录,RSA非对称加密,web前端加密,C#后端解密
  • rsa前端加密后端解密的使用

    千次阅读 2020-05-28 20:39:51
    然而把代码上传到服务器(Linux系统)后每次生成的公钥和私钥就不一样了,这样造成之前加密过后的数据,后面服务器重新启动后生成不一样的公钥和私钥就没法解密之前加密过的数据了。 需要引入bcprov-jdk15on-1.55....

    最近在项目中使用ras算法进行数据加密传输,加密后的数据需要存储到数据库。在使用过程中发现一个问题在windows上面每次生成的公钥和私钥是一致的,然而把代码上传到服务器(Linux系统)后每次生成的公钥和私钥就不一样了,这样造成之前加密过后的数据,后面服务器重新启动后生成不一样的公钥和私钥就没法解密之前加密过的数据了。

    需要引入bcprov-jdk15on-1.55.jar包和commons-codec-1.9.jar

            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.9</version>
            </dependency>
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcprov-jdk15on</artifactId>
                <version>1.60</version>
            </dependency>
    

    最初的代码

    public class RSAEncrypt {
    	/** 
    	 * 随机生成密钥对 
    	 * @throws NoSuchAlgorithmException 
    	 */  
    	public  static Map<String,String> genKeyPair() throws NoSuchAlgorithmException {
    		Map<String, String> keyMap = new HashMap<>();
    		// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
    		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
    		// 初始化密钥对生成器,密钥大小为96-1024位  
    		keyPairGen.initialize(1024,new SecureRandom());  
    		// 生成一个密钥对,保存在keyPair中  
    		KeyPair keyPair = keyPairGen.genKeyPair();
    		System.out.println(keyPair.getPublic().getEncoded());
    		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
    		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  
    		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
    		// 得到私钥字符串  
    		String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));  
    		// 将公钥和私钥保存到Map
    		keyMap.put("pub",publicKeyString);
    		keyMap.put("pri",privateKeyString);
    		return keyMap;
    	}  
    	/** 
    	 * RSA公钥加密 
    	 *  
    	 * @param str 
    	 *            加密字符串
    	 * @param publicKey 
    	 *            公钥 
    	 * @return 密文 
    	 * @throws Exception 
    	 *             加密过程中的异常信息 
    	 */  
    	public static String encrypt( String str, String publicKey ) throws Exception{
    		//base64编码的公钥
    		byte[] decoded = Base64.decodeBase64(publicKey);
    		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
    		//RSA加密
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    		String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
    		return outStr;
    	}
    
    	/** 
    	 * RSA私钥解密
    	 *  
    	 * @param str 
    	 *            加密字符串
    	 * @param privateKey 
    	 *            私钥 
    	 * @return 铭文
    	 * @throws Exception 
    	 *             解密过程中的异常信息 
    	 */  
    	public static String decrypt(String str, String privateKey) throws Exception{
    		//64位解码加密后的字符串
    		byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
    		//base64编码的私钥
    		byte[] decoded = Base64.decodeBase64(privateKey);  
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));  
    		//RSA解密
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.DECRYPT_MODE, priKey);
    		String outStr = new String(cipher.doFinal(inputByte));
    		return outStr;
    	}
    
    	public static void main(String[] args) throws Exception {
    		//生成公钥和私钥
    		Map<String, String> keyMap = genKeyPair();
    		//加密字符串
    		String message = "123456";
    		System.out.println("随机生成的公钥为:" + keyMap.get("pub"));
    		System.out.println("随机生成的私钥为:" + keyMap.get("pri"));
    		String messageEn = encrypt(message,keyMap.get("pub"));
    		System.out.println(message + "\t加密后的字符串为:" + messageEn);
    		String messageDe = decrypt(messageEn,keyMap.get("pri"));
    		System.out.println("还原后的字符串为:" + messageDe);
    	}
    }
    

    这种生成的密钥对的方式由于是随机数,所以每次都是不一样的,适合前端加密完就进行解密,不需要进行存储,只是做加密传输。

    keyPairGen.initialize(1024,new SecureRandom());
    

    每次生成的密钥一致,修改

            //如果使用SecureRandom random = new SecureRandom();//windows和linux默认不同,导致两个平台生成的公钥和私钥不同
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            //使用种子则生成相同的公钥和私钥
            secureRandom.setSeed("seed".getBytes());
            keyPairGenerator.initialize(1024, secureRandom);
    

    后端解密乱码的话可以这样配置

    //相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同
    		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",new BouncyCastleProvider());
    
    

    最终修改的代码,windows,linux都生成一致的密钥对

    import org.apache.commons.codec.binary.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    import javax.crypto.Cipher;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    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;
    
    public class RSAEncrypt {
    	/** 
    	 * 随机生成密钥对 
    	 * @throws NoSuchAlgorithmException 
    	 */  
    	public  static Map<String,String> genKeyPair(String seed) throws NoSuchAlgorithmException {
    		Map<String, String> keyMap = new HashMap<>();
    		// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
    		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    		SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
    		//使用种子则生成相同的公钥和私钥
    		secureRandom.setSeed(seed.getBytes());
    		// 初始化密钥对生成器,密钥大小为96-1024位  
    		keyPairGen.initialize(1024,secureRandom);
    		// 生成一个密钥对,保存在keyPair中  
    		KeyPair keyPair = keyPairGen.genKeyPair();
    		System.out.println(keyPair.getPublic().getEncoded());
    		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
    		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  
    		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
    		// 得到私钥字符串  
    		String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));  
    		// 将公钥和私钥保存到Map
    		keyMap.put("pub",publicKeyString);
    		keyMap.put("pri",privateKeyString);
    		return keyMap;
    	}  
    	/** 
    	 * RSA公钥加密 
    	 *  
    	 * @param str 
    	 *            加密字符串
    	 * @param publicKey 
    	 *            公钥 
    	 * @return 密文 
    	 * @throws Exception 
    	 *             加密过程中的异常信息 
    	 */  
    	public static String encrypt( String str, String publicKey ) throws Exception{
    		//base64编码的公钥
    		byte[] decoded = Base64.decodeBase64(publicKey);
    		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
    		//RSA加密
    		//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同
    		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",new BouncyCastleProvider());
    		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    		String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
    		return outStr;
    	}
    
    	/** 
    	 * RSA私钥解密
    	 *  
    	 * @param str 
    	 *            加密字符串
    	 * @param privateKey 
    	 *            私钥 
    	 * @return 铭文
    	 * @throws Exception 
    	 *             解密过程中的异常信息 
    	 */  
    	public static String decrypt(String str, String privateKey) throws Exception{
    		//64位解码加密后的字符串
    		byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
    		//base64编码的私钥
    		byte[] decoded = Base64.decodeBase64(privateKey);  
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));  
    		//RSA解密
    		//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同
    		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",new BouncyCastleProvider());
    		cipher.init(Cipher.DECRYPT_MODE, priKey);
    		String outStr = new String(cipher.doFinal(inputByte));
    		return outStr;
    	}
    
    	public static void main(String[] args) throws Exception {
    		//生成公钥和私钥
    		Map<String, String> keyMap = genKeyPair("seed");
    		//加密字符串
    		String message = "123456";
    		System.out.println("随机生成的公钥为:" + keyMap.get("pub"));
    		System.out.println("随机生成的私钥为:" + keyMap.get("pri"));
    		String messageEn = encrypt(message,keyMap.get("pub"));
    		System.out.println(message + "\t加密后的字符串为:" + messageEn);
    		String messageDe = decrypt(messageEn,keyMap.get("pri"));
    		System.out.println("还原后的字符串为:" + messageDe);
    	}
    }
    

    前端使用的是vue,可以npm安装至Vue项目

    npm install jsencrypt --dev
    

    页面引入jsencrypt

    import { JSEncrypt } from 'jsencrypt'
    

    公钥为后端提供,如前端需要解密数据,则也需要后端提供私钥。

    methods: {
        //  加密
        encryptedData(publicKey, data) {
          // 新建JSEncrypt对象
          let encryptor = new JSEncrypt();
          // 设置公钥
          encryptor.setPublicKey(publicKey);
          // 加密数据
          return encryptor.encrypt(data);
        },
        // 解密
        decryptData(privateKey,data){
          // 新建JSEncrypt对象
          let decrypt= new JSEncrypt();
          // 设置私钥
          decrypt.setPrivateKey(privateKey);
          // 解密数据
          return decrypt.decrypt(secretWord);
        }
      }
    
    展开全文
  • java+vue 实现前端sm2加密 后端解密

    千次阅读 2021-04-27 11:50:52
    1.pom文件 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.57</version> <...

    1.pom文件

            <dependency>
    			<groupId>org.bouncycastle</groupId>
    			<artifactId>bcprov-jdk15on</artifactId>
    			<version>1.57</version>
    		</dependency>

    2.java 关键类

    工具类util

    import java.math.BigInteger;
    
    public class Util {
        /**
         * 整形转换成网络传输的字节流(字节数组)型数据
         *
         * @param num 一个整型数据
         * @return 4个字节的自己数组
         */
        public static byte[] intToBytes(int num) {
            byte[] bytes = new byte[4];
            bytes[0] = (byte) (0xff & (num >> 0));
            bytes[1] = (byte) (0xff & (num >> 8));
            bytes[2] = (byte) (0xff & (num >> 16));
            bytes[3] = (byte) (0xff & (num >> 24));
            return bytes;
        }
    
        /**
         * 四个字节的字节数据转换成一个整形数据
         *
         * @param bytes 4个字节的字节数组
         * @return 一个整型数据
         */
        public static int byteToInt(byte[] bytes) {
            int num = 0;
            int temp;
            temp = (0x000000ff & (bytes[0])) << 0;
            num = num | temp;
            temp = (0x000000ff & (bytes[1])) << 8;
            num = num | temp;
            temp = (0x000000ff & (bytes[2])) << 16;
            num = num | temp;
            temp = (0x000000ff & (bytes[3])) << 24;
            num = num | temp;
            return num;
        }
    
        /**
         * 长整形转换成网络传输的字节流(字节数组)型数据
         *
         * @param num 一个长整型数据
         * @return 4个字节的自己数组
         */
        public static byte[] longToBytes(long num) {
            byte[] bytes = new byte[8];
            for (int i = 0; i < 8; i++) {
                bytes[i] = (byte) (0xff & (num >> (i * 8)));
            }
    
            return bytes;
        }
    
        /**
         * 大数字转换字节流(字节数组)型数据
         *
         * @param n
         * @return
         */
        public static byte[] byteConvert32Bytes(BigInteger n) {
            byte tmpd[] = (byte[]) null;
            if (n == null) {
                return null;
            }
    
            if (n.toByteArray().length == 33) {
                tmpd = new byte[32];
                System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);
            } else if (n.toByteArray().length == 32) {
                tmpd = n.toByteArray();
            } else {
                tmpd = new byte[32];
                for (int i = 0; i < 32 - n.toByteArray().length; i++) {
                    tmpd[i] = 0;
                }
                System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);
            }
            return tmpd;
        }
    
        /**
         * 换字节流(字节数组)型数据转大数字
         *
         * @param b
         * @return
         */
        public static BigInteger byteConvertInteger(byte[] b) {
            if (b[0] < 0) {
                byte[] temp = new byte[b.length + 1];
                temp[0] = 0;
                System.arraycopy(b, 0, temp, 1, b.length);
                return new BigInteger(temp);
            }
            return new BigInteger(b);
        }
    
        /**
         * 根据字节数组获得值(十六进制数字)
         *
         * @param bytes
         * @return
         */
        public static String getHexString(byte[] bytes) {
            return getHexString(bytes, true);
        }
    
        /**
         * 根据字节数组获得值(十六进制数字)
         *
         * @param bytes
         * @param upperCase
         * @return
         */
        public static String getHexString(byte[] bytes, boolean upperCase) {
            String ret = "";
            for (int i = 0; i < bytes.length; i++) {
                ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);
            }
            return upperCase ? ret.toUpperCase() : ret;
        }
    
        /**
         * 打印十六进制字符串
         *
         * @param bytes
         */
        public static void printHexString(byte[] bytes) {
            for (int i = 0; i < bytes.length; i++) {
                String hex = Integer.toHexString(bytes[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                System.out.print("0x" + hex.toUpperCase() + ",");
            }
            System.out.println("");
        }
    
        /**
         * Convert hex string to byte[]
         *
         * @param hexString the hex string
         * @return byte[]
         */
        public static byte[] hexStringToBytes(String hexString) {
            if (hexString == null || hexString.equals("")) {
                return null;
            }
    
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
            for (int i = 0; i < length; i++) {
                int pos = i * 2;
                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
            }
            return d;
        }
    
        /**
         * Convert char to byte
         *
         * @param c char
         * @return byte
         */
        public static byte charToByte(char c) {
            return (byte) "0123456789ABCDEF".indexOf(c);
        }
    
        /**
         * 用于建立十六进制字符的输出的小写字符数组
         */
        private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    
        /**
         * 用于建立十六进制字符的输出的大写字符数组
         */
        private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    
        /**
         * 将字节数组转换为十六进制字符数组
         *
         * @param data byte[]
         * @return 十六进制char[]
         */
        public static char[] encodeHex(byte[] data) {
            return encodeHex(data, true);
        }
    
        /**
         * 将字节数组转换为十六进制字符数组
         *
         * @param data        byte[]
         * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
         * @return 十六进制char[]
         */
        public static char[] encodeHex(byte[] data, boolean toLowerCase) {
            return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
        }
    
        /**
         * 将字节数组转换为十六进制字符数组
         *
         * @param data     byte[]
         * @param toDigits 用于控制输出的char[]
         * @return 十六进制char[]
         */
        protected static char[] encodeHex(byte[] data, char[] toDigits) {
            int l = data.length;
            char[] out = new char[l << 1];
            // two characters form the hex value.
            for (int i = 0, j = 0; i < l; i++) {
                out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
                out[j++] = toDigits[0x0F & data[i]];
            }
            return out;
        }
    
        /**
         * 将字节数组转换为十六进制字符串
         *
         * @param data byte[]
         * @return 十六进制String
         */
        public static String encodeHexString(byte[] data) {
            return encodeHexString(data, true);
        }
    
        /**
         * 将字节数组转换为十六进制字符串
         *
         * @param data        byte[]
         * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
         * @return 十六进制String
         */
        public static String encodeHexString(byte[] data, boolean toLowerCase) {
            return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
        }
    
        /**
         * 将字节数组转换为十六进制字符串
         *
         * @param data     byte[]
         * @param toDigits 用于控制输出的char[]
         * @return 十六进制String
         */
        protected static String encodeHexString(byte[] data, char[] toDigits) {
            return new String(encodeHex(data, toDigits));
        }
    
        /**
         * 将十六进制字符数组转换为字节数组
         *
         * @param data 十六进制char[]
         * @return byte[]
         * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
         */
        public static byte[] decodeHex(char[] data) {
            int len = data.length;
    
            if ((len & 0x01) != 0) {
                throw new RuntimeException("Odd number of characters.");
            }
    
            byte[] out = new byte[len >> 1];
    
            // two characters form the hex value.
            for (int i = 0, j = 0; j < len; i++) {
                int f = toDigit(data[j], j) << 4;
                j++;
                f = f | toDigit(data[j], j);
                j++;
                out[i] = (byte) (f & 0xFF);
            }
    
            return out;
        }
    
        /**
         * 将十六进制字符转换成一个整数
         *
         * @param ch    十六进制char
         * @param index 十六进制字符在字符数组中的位置
         * @return 一个整数
         * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
         */
        protected static int toDigit(char ch, int index) {
            int digit = Character.digit(ch, 16);
            if (digit == -1) {
                throw new RuntimeException("Illegal hexadecimal character " + ch
                        + " at index " + index);
            }
            return digit;
        }
    
        /**
         * 数字字符串转ASCII码字符串
         *
         * @param String 字符串
         * @return ASCII字符串
         */
        public static String StringToAsciiString(String content) {
            String result = "";
            int max = content.length();
            for (int i = 0; i < max; i++) {
                char c = content.charAt(i);
                String b = Integer.toHexString(c);
                result = result + b;
            }
            return result;
        }
    
        /**
         * 十六进制转字符串
         *
         * @param hexString  十六进制字符串
         * @param encodeType 编码类型4:Unicode,2:普通编码
         * @return 字符串
         */
        public static String hexStringToString(String hexString, int encodeType) {
            String result = "";
            int max = hexString.length() / encodeType;
            for (int i = 0; i < max; i++) {
                char c = (char) hexStringToAlgorism(hexString
                        .substring(i * encodeType, (i + 1) * encodeType));
                result += c;
            }
            return result;
        }
    
        /**
         * 十六进制字符串装十进制
         *
         * @param hex 十六进制字符串
         * @return 十进制数值
         */
        public static int hexStringToAlgorism(String hex) {
            hex = hex.toUpperCase();
            int max = hex.length();
            int result = 0;
            for (int i = max; i > 0; i--) {
                char c = hex.charAt(i - 1);
                int algorism = 0;
                if (c >= '0' && c <= '9') {
                    algorism = c - '0';
                } else {
                    algorism = c - 55;
                }
                result += Math.pow(16, max - i) * algorism;
            }
            return result;
        }
    
        /**
         * 十六转二进制
         *
         * @param hex 十六进制字符串
         * @return 二进制字符串
         */
        public static String hexStringToBinary(String hex) {
            hex = hex.toUpperCase();
            String result = "";
            int max = hex.length();
            for (int i = 0; i < max; i++) {
                char c = hex.charAt(i);
                switch (c) {
                    case '0':
                        result += "0000";
                        break;
                    case '1':
                        result += "0001";
                        break;
                    case '2':
                        result += "0010";
                        break;
                    case '3':
                        result += "0011";
                        break;
                    case '4':
                        result += "0100";
                        break;
                    case '5':
                        result += "0101";
                        break;
                    case '6':
                        result += "0110";
                        break;
                    case '7':
                        result += "0111";
                        break;
                    case '8':
                        result += "1000";
                        break;
                    case '9':
                        result += "1001";
                        break;
                    case 'A':
                        result += "1010";
                        break;
                    case 'B':
                        result += "1011";
                        break;
                    case 'C':
                        result += "1100";
                        break;
                    case 'D':
                        result += "1101";
                        break;
                    case 'E':
                        result += "1110";
                        break;
                    case 'F':
                        result += "1111";
                        break;
                }
            }
            return result;
        }
    
        /**
         * ASCII码字符串转数字字符串
         *
         * @param String ASCII字符串
         * @return 字符串
         */
        public static String AsciiStringToString(String content) {
            String result = "";
            int length = content.length() / 2;
            for (int i = 0; i < length; i++) {
                String c = content.substring(i * 2, i * 2 + 2);
                int a = hexStringToAlgorism(c);
                char b = (char) a;
                String d = String.valueOf(b);
                result += d;
            }
            return result;
        }
    
        /**
         * 将十进制转换为指定长度的十六进制字符串
         *
         * @param algorism  int 十进制数字
         * @param maxLength int 转换后的十六进制字符串长度
         * @return String 转换后的十六进制字符串
         */
        public static String algorismToHexString(int algorism, int maxLength) {
            String result = "";
            result = Integer.toHexString(algorism);
    
            if (result.length() % 2 == 1) {
                result = "0" + result;
            }
            return patchHexString(result.toUpperCase(), maxLength);
        }
    
        /**
         * 字节数组转为普通字符串(ASCII对应的字符)
         *
         * @param bytearray byte[]
         * @return String
         */
        public static String byteToString(byte[] bytearray) {
            String result = "";
            char temp;
    
            int length = bytearray.length;
            for (int i = 0; i < length; i++) {
                temp = (char) bytearray[i];
                result += temp;
            }
            return result;
        }
    
        /**
         * 二进制字符串转十进制
         *
         * @param binary 二进制字符串
         * @return 十进制数值
         */
        public static int binaryToAlgorism(String binary) {
            int max = binary.length();
            int result = 0;
            for (int i = max; i > 0; i--) {
                char c = binary.charAt(i - 1);
                int algorism = c - '0';
                result += Math.pow(2, max - i) * algorism;
            }
            return result;
        }
    
        /**
         * 十进制转换为十六进制字符串
         *
         * @param algorism int 十进制的数字
         * @return String 对应的十六进制字符串
         */
        public static String algorismToHEXString(int algorism) {
            String result = "";
            result = Integer.toHexString(algorism);
    
            if (result.length() % 2 == 1) {
                result = "0" + result;
    
            }
            result = result.toUpperCase();
    
            return result;
        }
    
        /**
         * HEX字符串前补0,主要用于长度位数不足。
         *
         * @param str       String 需要补充长度的十六进制字符串
         * @param maxLength int 补充后十六进制字符串的长度
         * @return 补充结果
         */
        static public String patchHexString(String str, int maxLength) {
            String temp = "";
            for (int i = 0; i < maxLength - str.length(); i++) {
                temp = "0" + temp;
            }
            str = (temp + str).substring(0, maxLength);
            return str;
        }
    
        /**
         * 将一个字符串转换为int
         *
         * @param s          String 要转换的字符串
         * @param defaultInt int 如果出现异常,默认返回的数字
         * @param radix      int 要转换的字符串是什么进制的,如16 8 10.
         * @return int 转换后的数字
         */
        public static int parseToInt(String s, int defaultInt, int radix) {
            int i = 0;
            try {
                i = Integer.parseInt(s, radix);
            } catch (NumberFormatException ex) {
                i = defaultInt;
            }
            return i;
        }
    
        /**
         * 将一个十进制形式的数字字符串转换为int
         *
         * @param s          String 要转换的字符串
         * @param defaultInt int 如果出现异常,默认返回的数字
         * @return int 转换后的数字
         */
        public static int parseToInt(String s, int defaultInt) {
            int i = 0;
            try {
                i = Integer.parseInt(s);
            } catch (NumberFormatException ex) {
                i = defaultInt;
            }
            return i;
        }
    
        /**
         * 十六进制串转化为byte数组
         *
         * @return the array of byte
         */
        public static byte[] hexToByte(String hex)
                throws IllegalArgumentException {
            if (hex.length() % 2 != 0) {
                throw new IllegalArgumentException();
            }
            char[] arr = hex.toCharArray();
            byte[] b = new byte[hex.length() / 2];
            for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
                String swap = "" + arr[i++] + arr[i];
                int byteint = Integer.parseInt(swap, 16) & 0xFF;
                b[j] = new Integer(byteint).byteValue();
            }
            return b;
        }
    
        /**
         * 字节数组转换为十六进制字符串
         *
         * @param b byte[] 需要转换的字节数组
         * @return String 十六进制字符串
         */
        public static String byteToHex(byte b[]) {
            if (b == null) {
                throw new IllegalArgumentException(
                        "Argument b ( byte array ) is null! ");
            }
            String hs = "";
            String stmp = "";
            for (int n = 0; n < b.length; n++) {
                stmp = Integer.toHexString(b[n] & 0xff);
                if (stmp.length() == 1) {
                    hs = hs + "0" + stmp;
                } else {
                    hs = hs + stmp;
                }
            }
            return hs.toLowerCase();
            //return hs.toUpperCase();
        }
    
        public static byte[] subByte(byte[] input, int startIndex, int length) {
            byte[] bt = new byte[length];
            for (int i = 0; i < length; i++) {
                bt[i] = input[i + startIndex];
            }
            return bt;
        }
    }
    

    参数类sm2

    import java.math.BigInteger;
    import java.security.SecureRandom;
    
    import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
    import org.bouncycastle.crypto.params.ECDomainParameters;
    import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
    import org.bouncycastle.math.ec.ECCurve;
    import org.bouncycastle.math.ec.ECFieldElement;
    import org.bouncycastle.math.ec.ECFieldElement.Fp;
    import org.bouncycastle.math.ec.ECPoint;
    
    public class SM2 {
    
        //国密参数
        public static String[] ecc_param = {
                "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
                "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
                "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
                "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
                "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
                "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"
        };
    
        public static SM2 Instance()
        {
            return new SM2();
        }
    
        public final BigInteger ecc_p;
        public final BigInteger ecc_a;
        public final BigInteger ecc_b;
        public final BigInteger ecc_n;
        public final BigInteger ecc_gx;
        public final BigInteger ecc_gy;
        public final ECCurve ecc_curve;
        public final ECPoint ecc_point_g;
        public final ECDomainParameters ecc_bc_spec;
        public final ECKeyPairGenerator ecc_key_pair_generator;
        public final ECFieldElement ecc_gx_fieldelement;
        public final ECFieldElement ecc_gy_fieldelement;
    
        public SM2()
        {
            this.ecc_p = new BigInteger(ecc_param[0], 16);
            this.ecc_a = new BigInteger(ecc_param[1], 16);
            this.ecc_b = new BigInteger(ecc_param[2], 16);
            this.ecc_n = new BigInteger(ecc_param[3], 16);
            this.ecc_gx = new BigInteger(ecc_param[4], 16);
            this.ecc_gy = new BigInteger(ecc_param[5], 16);
    
            this.ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx);
            this.ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy);
    
            this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);
            this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);
    
            this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);
    
            ECKeyGenerationParameters ecc_ecgenparam;
            ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());
    
            this.ecc_key_pair_generator = new ECKeyPairGenerator();
            this.ecc_key_pair_generator.init(ecc_ecgenparam);
        }
    }

    Cipher

    import java.math.BigInteger;
    
    import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    import org.bouncycastle.crypto.digests.SM3Digest;
    import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
    import org.bouncycastle.crypto.params.ECPublicKeyParameters;
    import org.bouncycastle.math.ec.ECPoint;
    
    public class Cipher {
        private int ct;
        private ECPoint p2;
        private SM3Digest sm3keybase;
        private SM3Digest sm3c3;
        private byte key[];
        private byte keyOff;
    
        public Cipher()
        {
            this.ct = 1;
            this.key = new byte[32];
            this.keyOff = 0;
        }
    
        private void Reset()
        {
            this.sm3keybase = new SM3Digest();
            this.sm3c3 = new SM3Digest();
    
            byte p[] = Util.byteConvert32Bytes(p2.getX().toBigInteger());
            this.sm3keybase.update(p, 0, p.length);
            this.sm3c3.update(p, 0, p.length);
    
            p = Util.byteConvert32Bytes(p2.getY().toBigInteger());
            this.sm3keybase.update(p, 0, p.length);
            this.ct = 1;
            NextKey();
        }
    
        private void NextKey()
        {
            SM3Digest sm3keycur = new SM3Digest(this.sm3keybase);
            sm3keycur.update((byte) (ct >> 24 & 0xff));
            sm3keycur.update((byte) (ct >> 16 & 0xff));
            sm3keycur.update((byte) (ct >> 8 & 0xff));
            sm3keycur.update((byte) (ct & 0xff));
            sm3keycur.doFinal(key, 0);
            this.keyOff = 0;
            this.ct++;
        }
    
        public ECPoint Init_enc(SM2 sm2, ECPoint userKey)
        {
            AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
            ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
            ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
            BigInteger k = ecpriv.getD();
            ECPoint c1 = ecpub.getQ();
            this.p2 = userKey.multiply(k);
            Reset();
            return c1;
        }
    
        public void Encrypt(byte data[])
        {
            this.sm3c3.update(data, 0, data.length);
            for (int i = 0; i < data.length; i++)
            {
                if (keyOff == key.length)
                {
                    NextKey();
                }
                data[i] ^= key[keyOff++];
            }
        }
    
        public void Init_dec(BigInteger userD, ECPoint c1)
        {
            this.p2 = c1.multiply(userD);
            Reset();
        }
    
        public void Decrypt(byte data[])
        {
            for (int i = 0; i < data.length; i++)
            {
                if (keyOff == key.length)
                {
                    NextKey();
                }
                data[i] ^= key[keyOff++];
            }
    
            this.sm3c3.update(data, 0, data.length);
        }
    
        public void Dofinal(byte c3[])
        {
            byte p[] = Util.byteConvert32Bytes(p2.getY().toBigInteger());
            this.sm3c3.update(p, 0, p.length);
            this.sm3c3.doFinal(c3, 0);
            Reset();
        }
    }
    

    功能类SM2EncDecUtils

    import java.io.IOException;
    import java.math.BigInteger;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
    import org.bouncycastle.crypto.params.ECPublicKeyParameters;
    import org.bouncycastle.math.ec.ECPoint;
    
    public class SM2EncDecUtils {
    	
    	public static final String key_pubk= "pub";
    	public static final String key_prik= "pri";
    	
    	// 生成随机秘钥对
    	public static Map<String,String> generateKeyPair() {
    		SM2 sm2 = SM2.Instance();
    		AsymmetricCipherKeyPair key = null;
    		while (true) {
    			key = sm2.ecc_key_pair_generator.generateKeyPair();
    			if (((ECPrivateKeyParameters) key.getPrivate()).getD().toByteArray().length == 32) {
    				break;
    			}
    		}
    		ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
    		ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
    		BigInteger privateKey = ecpriv.getD();
    		ECPoint publicKey = ecpub.getQ();
    		String pubk = Util.byteToHex(publicKey.getEncoded());
    		String prik = Util.byteToHex(privateKey.toByteArray());
    		System.out.println("公钥: " + pubk);
    		System.out.println("私钥: " + prik);
    		Map<String,String> result = new HashMap<>();
    		
    		result.put(key_pubk, pubk);
    		result.put(key_prik, prik);
    		
    		return result;
    	}
    
    	// 数据加密
    	public static String encrypt(byte[] publicKey, byte[] data) throws IOException {
    		if (publicKey == null || publicKey.length == 0) {
    			return null;
    		}
    
    		if (data == null || data.length == 0) {
    			return null;
    		}
    
    		byte[] source = new byte[data.length];
    		System.arraycopy(data, 0, source, 0, data.length);
    
    		Cipher cipher = new Cipher();
    		SM2 sm2 = SM2.Instance();
    		ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
    
    		ECPoint c1 = cipher.Init_enc(sm2, userKey);
    		cipher.Encrypt(source);
    		byte[] c3 = new byte[32];
    		cipher.Dofinal(c3);
    
    		return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(c3) + Util.byteToHex(source);
    	}
    
    	// 数据解密
    	public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException {
    		if (privateKey == null || privateKey.length == 0) {
    			return null;
    		}
    
    		if (encryptedData == null || encryptedData.length == 0) {
    			return null;
    		}
    		// 加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
    		String data = Util.byteToHex(encryptedData);
    		
    		byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
    		int c2Len = encryptedData.length - 97;
    		byte[] c3 = Util.hexToByte(data.substring(130, 130 + 64));
    		byte[] c2 = Util.hexToByte(data.substring(194, 194 + 2 * c2Len));
    
    		SM2 sm2 = SM2.Instance();
    		BigInteger userD = new BigInteger(1, privateKey);
    
    		// 通过C1实体字节来生成ECPoint
    		ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
    		Cipher cipher = new Cipher();
    		cipher.Init_dec(userD, c1);
    		cipher.Decrypt(c2);
    		cipher.Dofinal(c3);
    
    		// 返回解密结果
    		return c2;
    	}
    
    	public static void main(String[] args) throws Exception {
    		String plainText = "admin#@!7789";
    		byte[] sourceData = plainText.getBytes();
    
    		Map<String,String> keymap = generateKeyPair();
    		
    		// 生成密钥对
    		String pubk = keymap.get(key_pubk);
    		String prik =  keymap.get(key_prik);
    
    		System.out.println("加密: ");
    		String cipherText = SM2EncDecUtils.encrypt(Util.hexToByte(pubk), sourceData);
    		System.out.println(cipherText);
    
    		System.out.println("解密: ");
    		plainText = new String(SM2EncDecUtils.decrypt(Util.hexToByte(prik), Util.hexToByte(cipherText)));
    		System.out.println(plainText);
    	}
    
    }

    3.vue代码

    const sm2 = require('sm-crypto').sm2
    const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
    const publicKey = "040a27d03e0e71f4f285c6b05d570bdc434ec327f5fd25c55b7261f55183409682ceaf39fa4b36abed7520e31e1bdac8104905b28ffaf681b734915cd2e7fedf71"
    
    
    // 加密
    export function encrypt(txt) {
    
    	let encryptData = sm2.doEncrypt(txt, publicKey, 1) // 加密结果
    
    	return '04' + encryptData;
    }

    最关键的是vue加密完的密文要加‘04’,否则后端解密16禁止字符串转字节数组的时候会有问题

    展开全文
  • VUE 前端加密 PHP 后端解密 PHP 后端加密 VUE 前端解密 文章解析 AES AES 加密模式(CBC、ECB、CTR、OCF、CFB) ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一...


    VUE 前端加密 PHP 后端解密 PHP 后端加密 VUE 前端解密 教程



    文章解析


    AES

    AES 加密模式(ECB、CBC、CFB、CTR、CFB/OFB)

    在这里插入图片描述

    ECB:电码本模式(Electronic Codebook Book (ECB)
    这种模式是将整个明文分成若干段相同的小段,然后单独一个个加密,一个个输出组成密文。


    在这里插入图片描述

    CBC:密码分组链接模式(Cipher Block Chaining (CBC))
    这种模式是先将明文切分成若干小段,

    展开全文
  • RSA非对称JAVA后端解密前端加密前端加密JAVA后端解密数据解密生成签名验签检查密钥 限制请求频率Escape工具类RSAUtils工具类 前端加密 //需要导入的js <script type="text/javascript" src="./RSA.js"></...

    前端加密

    //需要导入的js

    <script type="text/javascript" src="./RSA.js"></script>
    <script type="text/javascript" src="./BigInt.js"></script>
    <script type="text/javascript" src="./Barrett.js"></script>
    
    setMaxDigits(131);
    const 公钥 = new RSAKeyPair("引入publicExponent", "", "引入publicModulus");
    const 加密后数据 = encryptedString(key, escape(加密前数据));
    const 加密后数据 = encryptedString(key, escape(加密前数据));
    

    切记 内层存在双引号情况下 若外层需要引号 务必用单引号 避免多余转义字符出现 否则解密会不通过

    JAVA后端解密

    数据解密

    private UserPayload decryptUserPayload(Long appId,String encrypts) throws InvalidKeySpecException, NoSuchAlgorithmException, BadRequestException {
            //处理加密数据排序问题
            if (encrypts.contains(" ")) {
                StringBuilder stringBuilder = new StringBuilder();
                String[] err = encrypts.split(" ");
                for (int length = err.length - 1; length >= 0; length--) {
                    stringBuilder.append(err[length]);
                }
                encrypts = stringBuilder.toString();
            }
            log.info("解密前数据:{}",encrypts);
            //获取密钥
            Company company = companyFeign.getCompanyById(appId);
            String privateKey = company.getPri();
            System.out.println("privateKey:::"+privateKey);
            Assert.notNull(privateKey,"兄弟,再乱来会报警的哦");
            PrivateKey PrivateKey = RSAUtils.getPrivateKey(privateKey);
            //解密
            byte[] en_result = HexToBytes.HexString2Bytes(encrypts);
            byte[] decrypt;
            try {
                decrypt = RSAUtils.decrypt(PrivateKey, en_result);
            } catch (Exception e) {
                throw new BadRequestException("解析失败:密钥或数据有误");
            }
            StringBuilder sb = new StringBuilder();
            sb.append(new String(decrypt));
            String str = sb.reverse().toString();
            String after = Escape.unescape(str);
            log.info("解密后数据:{}",after);
            //映射对应属性
            JSONObject jsonObject = JSON.parseObject(after);
            UserPayload userPayload = JSONObject.toJavaObject(jsonObject, UserPayload.class);
            userPayload.setPri(privateKey);
            return userPayload;
        }
    

    生成签名

    private JSONObject generateSign(SMSExtendRequest smsExtendRequest) throws Exception {
            Company companyById = companyFeign.getCompanyById(smsExtendRequest.getAppId());
    
            RSAPublicKey rsaPublicKey = RSAUtils.getPublicKey(companyById.getPub());
            String telephone = smsExtendRequest.getTelephone();
            String signBefore = telephone +smsExtendRequest.getTime();
            //生成签名
            String sign = RSAUtils.publicEncrypt(signBefore, rsaPublicKey);
            JSONObject jsonParam = new JSONObject();
            jsonParam.put("sign",sign);
    
            //缓存加密前签名
            redisTemplate.opsForValue().set(字符串KEY + telephone,signBefore,1 ,TimeUnit.HOURS);
            //缓存加密后签名
            redisTemplate.opsForValue().set(字符串KEY + telephone,sign,1 ,TimeUnit.HOURS);
    
            return jsonParam;
        }
    

    验签

     private void verifySign(String sign,String telephone,String privateKey) throws BadRequestException, InvalidKeySpecException, NoSuchAlgorithmException {
            //私钥解密
            RSAPrivateKey PrivateKey = (RSAPrivateKey)RSAUtils.getPrivateKey(privateKey);
            String decodedData = RSAUtils.privateDecrypt(sign, PrivateKey);
            String signBefore = redisTemplate.opsForValue().get(字符串KEY + telephone);
            //过滤重复提交请求  (每个签名只能验签一次)
            Assert.notNull(signBefore,"签名过期,请重新获取验证码再次重试");
            Assert.isTrue(decodedData.equals(signBefore),"验签失败");
        }
    

    检查密钥 限制请求频率

    private JSONObject prepareKey(SMSExtendRequest smsExtendRequest) throws Exception {
            JSONObject jsonObject;
            String telephone = smsExtendRequest.getTelephone();
            String requestRestrict = redisTemplate.opsForValue().get(字符串KEY + telephone);
            Assert.isNull(requestRestrict,"请求过于频繁,请稍后再试");
    
            //生成签名
            jsonObject = generateSign(smsExtendRequest);
    
    
            Assert.notNull(jsonObject,"签名系统异常,请联系客服");
            String sign = redisTemplate.opsForValue().get(字符串KEY + telephone);
    
            jsonObject.put("sign",sign);
            redisTemplate.opsForValue().set(字符串KEY + telephone,telephone,50,TimeUnit.SECONDS);
            return jsonObject;
        }
    

    Escape工具类

    public class Escape {
    
        private final static String[] hex = {
            "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
            "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
            "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
            "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
            "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
            "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
            "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
            "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
            "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
            "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
            "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
            "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
            "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
            "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
            "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
            "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
        };
    
        private final static byte[] val = {
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
            0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
        };
    
        public static String escape(String s) {
            StringBuilder sbuf = new StringBuilder();
            int len = s.length();
            for (int i = 0; i < len; i++) {
                int ch = s.charAt(i);
                if (ch == ' ') {                        // space : map to '+'
                    sbuf.append('+');
                } else if ('A' <= ch && ch <= 'Z') {    // 'A'..'Z' : as it was
                    sbuf.append((char) ch);
                } else if ('a' <= ch && ch <= 'z') {    // 'a'..'z' : as it was
                    sbuf.append((char) ch);
                } else if ('0' <= ch && ch <= '9') {    // '0'..'9' : as it was
                    sbuf.append((char) ch);
                } else if (ch == '-' || ch == '_' // unreserved : as it was
                        || ch == '.' || ch == '!'
                        || ch == '~' || ch == '*'
                        || ch == '\'' || ch == '('
                        || ch == ')') {
                    sbuf.append((char) ch);
                } else if (ch <= 0x007F) {              // other ASCII : map to %XX
                    sbuf.append('%');
                    sbuf.append(hex[ch]);
                } else {                                // unicode : map to %uXXXX
                    sbuf.append('%');
                    sbuf.append('u');
                    sbuf.append(hex[(ch >>> 8)]);
                    sbuf.append(hex[(0x00FF & ch)]);
                }
            }
            return sbuf.toString();
        }
    
        public static String unescape(String s) {
            StringBuilder sbuf = new StringBuilder();
            int i = 0;
            int len = s.length();
            while (i < len) {
                int ch = s.charAt(i);
                if (ch == '+') {                        // + : map to ' '
                    sbuf.append(' ');
                } else if ('A' <= ch && ch <= 'Z') {    // 'A'..'Z' : as it was
                    sbuf.append((char) ch);
                } else if ('a' <= ch && ch <= 'z') {    // 'a'..'z' : as it was
                    sbuf.append((char) ch);
                } else if ('0' <= ch && ch <= '9') {    // '0'..'9' : as it was
                    sbuf.append((char) ch);
                } else if (ch == '-' || ch == '_' // unreserved : as it was
                        || ch == '.' || ch == '!'
                        || ch == '~' || ch == '*'
                        || ch == '\'' || ch == '('
                        || ch == ')'
                ) {
                    sbuf.append((char) ch);
                } else if (ch == '%') {
                    int cint = 0;
                    if ('u' != s.charAt(i + 1)) {         // %XX : map to ascii(XX)
                        cint = (cint << 4) | val[s.charAt(i + 1)];
                        cint = (cint << 4) | val[s.charAt(i + 2)];
                        i += 2;
                    } else {                            // %uXXXX : map to unicode(XXXX)
                        cint = (cint << 4) | val[s.charAt(i + 2)];
                        cint = (cint << 4) | val[s.charAt(i + 3)];
                        cint = (cint << 4) | val[s.charAt(i + 4)];
                        cint = (cint << 4) | val[s.charAt(i + 5)];
                        i += 5;
                    }
                    sbuf.append((char) cint);
                }
                i++;
            }
            return sbuf.toString();
        }
    }
    
    

    RSAUtils工具类

    public class RSAUtils {
        public static final String CHARSET = "UTF-8";
        public static final String RSA_ALGORITHM = "RSA";
    
        public static RSAPrivateKey privateKeya;
        public static RSAPublicKey publicKeya;
    
        public static Map<String, String> createKeys(int keySize) {
            //为RSA算法创建一个KeyPairGenerator对象
            KeyPairGenerator kpg;
            try {
                kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
            } catch (NoSuchAlgorithmException e) {
                throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
            }
            //初始化KeyPairGenerator对象,密钥长度
            kpg.initialize(keySize);
            //生成密匙对
            KeyPair keyPair = kpg.generateKeyPair();
            //得到公钥
            Key publicKey = keyPair.getPublic();
            String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
            //得到私钥
            Key privateKey = keyPair.getPrivate();
            String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
            Map<String, String> keyPairMap = new HashMap<String, String>();
            keyPairMap.put("publicKey", publicKeyStr);
            keyPairMap.put("privateKey", privateKeyStr);
            //------------------------------------------------
            //得到私钥
            privateKeya = (RSAPrivateKey) keyPair.getPrivate();
            //得到公钥
            publicKeya = (RSAPublicKey) keyPair.getPublic();
            return keyPairMap;
        }
    
        /**
         * 得到公钥
         *
         * @param publicKey 密钥字符串(经过base64编码)
         * @throws Exception
         */
        public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
            //通过X509编码的Key指令获得公钥对象
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
            RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
            return key;
        }
    
        /**
         * 得到私钥
         *
         * @param privateKey 密钥字符串(经过base64编码)
         * @throws Exception
         */
        public static PrivateKey getPrivateKey(String privateKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
            //通过PKCS#8编码的Key指令获得私钥对象
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
            return keyFactory.generatePrivate(pkcs8KeySpec);
        }
    
        /**
         * 公钥加密
         *
         * @param data
         * @param publicKey
         * @return
         */
    
        public static String publicEncrypt(String data, RSAPublicKey publicKey) {
            try {
                Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                byte[] bs = rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
                    publicKey.getModulus().bitLength());
                return Base64.encodeBase64URLSafeString(bs);
            } catch (Exception e) {
                throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
            }
        }
    
        /**
         * 私钥解密
         *
         * @param data
         * @param privateKey
         * @return
         */
        public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
            try {
                Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] bs = Base64.decodeBase64(data);
                return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, bs, privateKey.getModulus().bitLength()),
                    CHARSET);
            } catch (Exception e) {
                throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
            }
        }
    
        public static String privateDecrypt(byte[] data, RSAPrivateKey privateKey) {
            try {
                Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, data, privateKey.getModulus().bitLength()),
                    CHARSET);
            } catch (Exception e) {
                throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
            }
        }
    
        /**
         * 私钥加密
         *
         * @param data
         * @param privateKey
         * @return
         */
        public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
            try {
                Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
                    privateKey.getModulus().bitLength()));
            } catch (Exception e) {
                throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
            }
        }
    
        /**
         * 公钥解密
         *
         * @param data
         * @param publicKey
         * @return
         */
        public static String publicDecrypt(String data, RSAPublicKey publicKey) {
            try {
                Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
                    publicKey.getModulus().bitLength()), CHARSET);
            } catch (Exception e) {
                throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
            }
    
        }
    
        private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
            int maxBlock = 0;
            if (opmode == Cipher.DECRYPT_MODE) {
                maxBlock = keySize / 8;
            } else {
                maxBlock = keySize / 8 - 11;
            }
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] buff;
            int i = 0;
            try {
                while (datas.length > offSet) {
                    if (datas.length - offSet > maxBlock) {
                        buff = cipher.doFinal(datas, offSet, maxBlock);
                    } else {
                        buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                    }
                    out.write(buff, 0, buff.length);
                    i++;
                    offSet = i * maxBlock;
                }
    
            } catch (Exception e) {
                throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
            }
            byte[] resultDatas = out.toByteArray();
            IOUtils.closeQuietly(out);
            return resultDatas;
        }
    
        public static byte[] hexStringToBytes(String hexString) {
            if (hexString == null || hexString.equals("")) {
                return null;
            }
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
            for (int i = 0; i < length; i++) {
                int pos = i * 2;
                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
            }
            return d;
        }
    
        private static byte charToByte(char c) {
            return (byte) "0123456789ABCDEF".indexOf(c);
        }
    
        /**
         * * 解密 *
         *
         * @param pk  解密的密钥 *
         * @param raw 已经加密的数据 *
         * @return 解密后的明文 *
         * @throws Exception
         */
        public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
            try {
                Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
                cipher.init(cipher.DECRYPT_MODE, pk);
                int blockSize = cipher.getBlockSize();
                ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
                int j = 0;
                while (raw.length - j * blockSize > 0) {
                    bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                    j++;
                }
                return bout.toByteArray();
            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
        }
     }
    
    展开全文
  • RSA前端加密后端解密避免出现明文密码传递 话不多说,直接开撸 前端JS 项目中先添加rsa.js文件 链接:https://pan.baidu.com/s/1r9930MkS4n8TR9IsOIXV-Q 提取码:hd52 添加完成之后在项目中引入rsa.js <script ...
  • 主要介绍了RSA实现JS前端加密与PHP后端解密功能,结合实例形式分析了rsa前端js加密与后端php解密相关操作技巧,需要的朋友可以参考下
  • python Django RSA 前台加密 后端解密,简单demo。
  • 前端vue加密 #安装依赖 npm install jsencrypt #公钥加密密码 import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMNRhRdV7BI4MN5buB2Dyj6+dSOEpa6...
  • private final static String password = "12334567812345678";//目前使用 private final static String IV =...//先用bAES64解密 return new String(cipher.doFinal(encrypted1)); }
  • 公司做的是一个某某平台的系统,包括前台和后台,作者刚毕业,刚开始试用,带我的师傅让我实现密码的加密解密,说实话,都有封装好的api,直接调用什么的,真的没啥难度,后来被其他小事情耽搁了,回过头来,前辈...
  • 文章目录1:vue实现加密过程2:java部分3:转载地址 1:vue实现加密过程 安装crypto-js npm install crypto-js --save-dev 在utils下新建secret.js 当然secret.js只是一个名字,叫什么高兴就好 import ...
  • Vue前端和Java后端 联调使用AES 前后端加密解密 最近在项目中需要针对重要数据进行加密传输,在网上找了一大推加密方式 最终采用AES 加密 Java端 package com.zk.web.util; /** * AES 128bit 加密解密...
  • 1.模块安装 npm install crypto-js 2.src–>util–>secret.js import CryptoJS from 'crypto-js' // 默认的 KEY 与 iv 如果没有给 const KEY = CryptoJS.enc.Utf8.parse(... * AES加密 :字符串 key iv 返.
  • 实现前端jsencrypt加密后端用java进行解密,然后用md5进行登录,非对称加密算法实现。包含代码示例代码详解

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,465
精华内容 586
关键字:

vue前端加密后端解密

vue 订阅