天天看點

RSA加密:web前端使用者名密碼加密以及java後端解密

RSA加密:web前端使用者名密碼加密以及java後端解密

編寫加解密公共方法類RSAUtils

package com.zhizhenkeji.administrative.common.utils;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPublicKey;

public class RSAUtil {
    private static final KeyPair keyPair = initKey();
    private static KeyPair initKey() {
        try {
            Provider provider =new BouncyCastleProvider();
            Security.addProvider(provider);
            SecureRandom random = new SecureRandom();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider);
            generator.initialize(1024,random);
            return generator.generateKeyPair();
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static String generateBase64PublicKey() {
        PublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
        return new String(Base64.encodeBase64(publicKey.getEncoded()));
    }
    public static String decryptBase64(String string) {
        return new String(decrypt(Base64.decodeBase64(string.getBytes())));
    }
    private static byte[] decrypt(byte[] byteArray) {
        try {
            Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
            Security.addProvider(provider);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
            PrivateKey privateKey = keyPair.getPrivate();
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] plainText = cipher.doFinal(byteArray);
            return plainText;
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
}

           

後端生成公鑰方法

@RequestMapping(value = "/xxx", method = RequestMethod.GET)
    public JsonResult RSAKey(){
        String publicKey = RSAUtil.generateBase64PublicKey();
        return JsonResult.getSuccessJsonResult("publicKey",publicKey);
    }
           

前端在向背景發起登入請求之前,先請求背景擷取公鑰的方法,然後經過加密之後再發起登入請求。

form.on('submit(signin)', function (data) {
        // 先擷取公鑰,然後送出使用者名和密碼給背景
        $.ajax({
          url: "擷取公鑰的請求路徑",
          type: "GET",
          dataType: "json",
          async: false,
          success: function (res) {
            var encrypt = new JSEncrypt();//建立加密執行個體
            if (res) {
              // console.log(res.data);
              var publicKey = null;
              publicKey = res.data;//後端傳回來的公鑰
              var username;
              var password;
              encrypt.setPublicKey(publicKey);// 初始化公鑰
              username = encrypt.encrypt(data.field.username.trim());// 加密使用者名資料
              password = encrypt.encrypt(data.field.password.trim());// 加密密碼資料
              // console.log(username);
              // console.log(password);
              // 送出加密後的使用者名和密碼給背景
              $.ajax({
                url: "登入請求路徑",
                data: {
                  "username": username,
                  "password": password
                },
                type: "GET",
                dataType: "json",
                success: function (result) {
                  if (result.rtnCode == "000000") {
                    layer.alert("登入成功!")
                    // window.top.location.href = './index.html';
                  } else {
                    layer.alert(result.data.rtnMsg);
                  }
                },
                error: function (e) {
                  layer.alert("登入失敗!");
                }
              });
            };
          }
        });
      });
           

前端代碼需引入jsencrypt.min.js檔案,這個js檔案網上一大堆,随便搜搜就有。

後端接收前端傳輸過來的密文進行解密

username = RSAUtil.decryptBase64(username.trim());
  password = RSAUtil.decryptBase64(password.trim());
           

後端代碼需要導入的依賴jar

需要導入的依賴jar
        <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk16 -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>
           

注意:

Http請求特殊符号變空格的問題:參數經過Base64編碼會有’+'加号,後端request.request.getParameter(name)擷取的值中+号變成了空格。

解決辦法:request.getParameter(nms).replaceAll(" ", “+”)