密码RSA加密传输-前端js加密-后端java解密

it2024-10-14  23

1、引入所需jar包 <dependency>   <groupId>org.bouncycastle</groupId>   <artifactId>bcprov-ext-jdk15on</artifactId>   <version>1.62</version> </dependency>

2、前端加载security.js文件

3、前端js代码 $.ajax({  //获取加密所需公钥指数和模     url:'${pageContext.request.contextPath}/system/key.html',     type:'get',     dataType:'json',     success:function(data){         if(data.type == 'success'){             //RSA加密             var publicKeyExponent=data.keys[0];             var publicKeyModulus=data.keys[1];             RSAUtils.setMaxDigits(200);             var key = new RSAUtils.getKeyPair(publicKeyExponent, "", publicKeyModulus);             var  userPwdEncrypt= RSAUtils.encryptedString(key,password.split("").reverse().join("")); //使用公钥加密

            $.ajax({  //登录请求                 url:'${pageContext.request.contextPath}/system/login.html',                 data:{userName:username, password:userPwdEncrypt, role:role, cpacha:cpacha},                 type:'post',                 dataType:'json',                 success:function(data){                     if(data.type == 'success'){                         登录成功                     }else{                         登录失败                     }                 }             });         }else{             获取公钥失败         }     } });

 

4、后端java代码    /**      * 获取公钥      * @return      */     @RequestMapping(value = "/key", method = RequestMethod.GET)     public String getKey(HttpServletRequest request, HttpServletResponse response){         JSONObject result = new JSONObject();         try {             //keys[0]为公钥,keys[1]为模             String[] keys = rsaService.getPublicAndModulus(request);             result.put("type", "success");             result.put("keys",keys);         } catch (NoSuchAlgorithmException e) {             e.printStackTrace();             result.put("type", "error");             result.put("msg", "数据加载失败,请刷新重试");         }         ResponseUtil.write(response, result);         return null;     }     

 

    /**      * /RSA工具类      * @return      */  public class RSAUtil {     /**      * 生成公钥和私钥      * @throws NoSuchAlgorithmException      *      */     public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException{         Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());         HashMap<String, Object> map = new HashMap<String, Object>();         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());         keyPairGen.initialize(1024);         KeyPair keyPair = keyPairGen.generateKeyPair();         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();         map.put("public", publicKey);         map.put("private", privateKey);         return map;     }     /**      * 使用模和指数生成RSA公钥      * @param modulus  模      * @param exponent  指数      * @return      */     public static RSAPublicKey getPublicKey(String modulus, String exponent) {         Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());         try {             BigInteger b1 = new BigInteger(modulus);             BigInteger b2 = new BigInteger(exponent);             KeyFactory keyFactory = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());             RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);             return (RSAPublicKey) keyFactory.generatePublic(keySpec);         } catch (Exception e) {             e.printStackTrace();             return null;         }     }

    /**      * 使用模和指数生成RSA私钥      * /None/NoPadding      * @param modulus     模      * @param exponent   指数      * @return      */     public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {         try {             Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());             BigInteger b1 = new BigInteger(modulus);             BigInteger b2 = new BigInteger(exponent);             KeyFactory keyFactory = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());             RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);             return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);         } catch (Exception e) {             e.printStackTrace();             return null;         }     }

    /**      * 公钥加密      *      * @param data      * @param publicKey      * @return      * @throws Exception      */     public static String encryptByPublicKey(String data, RSAPublicKey publicKey)             throws Exception {         Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());         Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());         cipher.init(Cipher.ENCRYPT_MODE, publicKey);         // 模长         int key_len = publicKey.getModulus().bitLength() / 8;         // 加密数据长度 <= 模长-11         String[] datas = splitString(data, key_len - 11);         String mi = "";         //如果明文长度大于模长-11则要分组加密         for (String s : datas) {             mi += bcd2Str(cipher.doFinal(s.getBytes()));         }         return mi;     }

    /**      * 私钥解密      *      * @param data      * @param privateKey      * @return      * @throws Exception      */     public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)             throws Exception {         Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());         Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());         cipher.init(Cipher.DECRYPT_MODE, privateKey);         //模长         int key_len = privateKey.getModulus().bitLength() / 8;         byte[] bytes = data.getBytes();         byte[] bcd = ASCII_To_BCD(bytes, bytes.length);         //System.err.println(bcd.length);         //如果密文长度大于模长则要分组解密         String ming = "";         byte[][] arrays = splitArray(bcd, key_len);         for(byte[] arr : arrays){             ming += new String(cipher.doFinal(arr));         }         return ming;     }     /**      * ASCII码转BCD码      *      */     public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {         byte[] bcd = new byte[asc_len / 2];         int j = 0;         for (int i = 0; i < (asc_len + 1) / 2; i++) {             bcd[i] = asc_to_bcd(ascii[j++]);             bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));         }         return bcd;     }     public static byte asc_to_bcd(byte asc) {         byte bcd;

        if ((asc >= '0') && (asc <= '9'))             bcd = (byte) (asc - '0');         else if ((asc >= 'A') && (asc <= 'F'))             bcd = (byte) (asc - 'A' + 10);         else if ((asc >= 'a') && (asc <= 'f'))             bcd = (byte) (asc - 'a' + 10);         else             bcd = (byte) (asc - 48);         return bcd;     }     /**      * BCD转字符串      */     public static String bcd2Str(byte[] bytes) {         char temp[] = new char[bytes.length * 2], val;

        for (int i = 0; i < bytes.length; i++) {             val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);             temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

            val = (char) (bytes[i] & 0x0f);             temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');         }         return new String(temp);     }     /**      * 拆分字符串      */     public static String[] splitString(String string, int len) {         int x = string.length() / len;         int y = string.length() % len;         int z = 0;         if (y != 0) {             z = 1;         }         String[] strings = new String[x + z];         String str = "";         for (int i=0; i<x+z; i++) {             if (i==x+z-1 && y!=0) {                 str = string.substring(i*len, i*len+y);             }else{                 str = string.substring(i*len, i*len+len);             }             strings[i] = str;         }         return strings;     }     /**      *拆分数组      */     public static byte[][] splitArray(byte[] data,int len){         int x = data.length / len;         int y = data.length % len;         int z = 0;         if(y!=0){             z = 1;         }         byte[][] arrays = new byte[x+z][];         byte[] arr;         for(int i=0; i<x+z; i++){             arr = new byte[len];             if(i==x+z-1 && y!=0){                 System.arraycopy(data, i*len, arr, 0, y);             }else{                 System.arraycopy(data, i*len, arr, 0, len);             }             arrays[i] = arr;         }         return arrays;     }     public static void main(String[] args) throws Exception{         /*HashMap<String, Object> map = getKeys();         //生成公钥和私钥         RSAPublicKey publicKey = (RSAPublicKey) map.get("public");         RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");

        //模         String modulusjs = publicKey.getModulus().toString(16);         System.out.println("pubkey_modulus_js="+modulusjs);         String modulus = publicKey.getModulus().toString();         //公钥指数         String public_exponentjs = publicKey.getPublicExponent().toString(16);         System.out.println("pubkey_exponent_js="+public_exponentjs);         String public_exponent = publicKey.getPublicExponent().toString();         //私钥指数         String private_exponent = privateKey.getPrivateExponent().toString();         System.out.println("private_exponent="+private_exponent);         //明文         String ming = "123456";         //使用模和指数生成公钥和私钥         RSAPublicKey pubKey = RSAUtil.getPublicKey(modulus, public_exponent);         RSAPrivateKey priKey = RSAUtil.getPrivateKey(modulus, private_exponent);         //加密后的密文         String mi = RSAUtil.encryptByPublicKey(ming, pubKey);         System.err.println("mi="+mi);         //解密后的明文         String ming2 = RSAUtil.decryptByPrivateKey(mi, priKey);         System.err.println("ming2="+ming2);*/                  //注意:传递给前端js的公钥指数和模需要转为16进制,java的私钥和模不需要转为16进制     } }

 

 

最新回复(0)