前端登陆进行加密后台解密

公司最近让在登录首页登录时,js加密,java解密。
首先必不可少的就是jar包,和js文件

后台引入的jar包:
jar 包 bcprov-jdk16-146.jar 和commons-codec-1.2.jar (maven项目的话引入相对应的依赖就好)

	<dependenccies>
		<dependency>
    		<groupId>commons-codec</groupId>
    		<artifactId>commons-codec</artifactId>
    		<version>1.10</version>
		</dependency>

		<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.60</version>
        </dependencies>
    <dependencys>

前端引入的脚本文件
jquery.min.js和security.js (security.js的源码可以在前一篇中找到)
java工具类 RSAUtils

import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;
import javax.crypto.Cipher;


public class RSAUtils {

    /**
     * 生成公钥和私钥 
     * @throwsNoSuchAlgorithmException 
     */
    public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        HashMap<String, Object> map = new HashMap<String, Object>();
        //为RSA算法创建一个KeyPairGenerator对象
        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公钥 
     *
     * @parammodulus 模 
     * @paramexponent 指数 
     * @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
     * @parammodulus 模
     * @paramexponent指数 
     * @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;
        }
    }

    /**
     * 公钥加密 
     * @return
     * @paramdata
     * @parampublicKey
     * @throwsException
     */
    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;
    }

    /**
     * 私钥解密 
     *
     * @paramdata 
     * @paramprivateKey 
     * @return 
     * @throwsException  
     */
    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 modulus = publicKey.getModulus().toString();
        System.out.println("pubkeymodulus=" + modulus);
        //公钥指数
        String public_exponent = publicKey.getPublicExponent().toString();
        System.out.println("pubkeyexponent=" + public_exponent);
        //私钥指数
        String private_exponent = privateKey.getPrivateExponent().toString();
        System.out.println("privateexponent=" + private_exponent);
        //明文
        String ming = "123456";
        //使用模和指数生成公钥和私钥
        RSAPublicKey pubKey = RSAUtils.getPublicKey(modulus, public_exponent);
        RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus, private_exponent);
        //加密后的密文
        String mi = RSAUtils.encryptByPublicKey(ming, pubKey);
        System.err.println("mi=" + mi);
        //解密后的明文
        String ming2 = RSAUtils.decryptByPrivateKey(mi, priKey);
        System.err.println("ming2=" + ming2);
    }
}

js 加密

账号:<input type="text" id="username" ><br><br>
密码:<input type="password" id="password"><br><br>
<input id="publicKeyExponent" value="" type="hidden"> //后台传过来的公钥
<input id="publicKeyModulus" value="" type="hidden">//后台传过来的模

<script>
	$(function(){
		//生成登陆用RSA公钥 密钥
		$.ajax({
			url:'${basePath}UserText/loginRSA.do',
			type:'post',
			dataType:'json',
			success:function(data){
				$("#publicKeyExponent").val(data[0]);
				$("#publicKeyModulus").val(data[1]);
			}
		})
	});

	//点击登录按钮,执行的方法
	function login1(){
		var username=$("#username").val();
		var password=$("#password").val();
		//RSA加密
        var publicKeyExponent=$("#publicKeyExponent").val();
        var publicKeyModulus=$("#publicKeyModulus").val();
        RSAUtils.setMaxDigits(200);
		var key = new RSAUtils.getKeyPair(publicKeyExponent, "", publicKeyModulus);
		var userNameEncrypt = RSAUtils.encryptedString(key,username.split("").reverse().join(""));
		var userPwdEncrypt = RSAUtils.encryptedString(key,password.split("").reverse().join(""));

		$.ajax({
			url:"${basePath}UserText/textLogin.do",
			data:'post',
			dataType:'json',
			data:{"username":userNameEncrypt,"password":userPwdEncrypt},
			success:function(data) {
				if(data == 'success') {
					alert("登录成功")
					window.location.href="${basePath}UserText/textList.do";
				} else if (data == 'usernameIsNull'){
					alert("账号错误")
				} else if (data == 'passwordIsNull'){
					alert("密码错误")
				} else {
					alert("登录失败")
				}
			}
		})
	}
</script>

java 后台接收,解密

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Description:Login
 * @Author:Anhk丶
 * @Date:2020/7/611:27
 * @Version:1.0
 */
public class LoginController {

    //生成登陆用RSA公钥密钥
    @RequestMapping(value = "/loginRSA")
    @ResponseBody
    public List<String> loginRSA(HttpServletRequest request) {
        //HttpServletRequestrequest=ServletActionContext.getRequest();
        String publicKeyExponent = "";
        String publicKeyModulus = "";

        try {
            HashMap<String, Object> map = RSAUtils.getKeys();
            //生成公钥和私钥
            RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
            RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
            //私钥保存在session中,用于解密
            request.getSession().setAttribute("privateKeyLogin", privateKey);
            //公钥信息保存在页面,用于加密公钥指数  .toString(16)表示转为16进制的字符串;
            publicKeyExponent = publicKey.getPublicExponent().toString(16);
            System.out.println("公钥指数:" + publicKeyExponent);
            //模 .toString(16)表示转为16进制的字符串;
            publicKeyModulus = publicKey.getModulus().toString(16);
            System.out.println("模指数:" + publicKeyModulus);

            //request.getSession().setAttribute("publicKeyExponent",publicKeyExponent);
            //request.getSession().setAttribute("publicKeyModulus",publicKeyModulus);
        } catch (Exception e) {
            log.error("RSA生成公钥错误", e);
        }
        List<String> list = new ArrayList<String>();
        list.add(publicKeyExponent);
        list.add(publicKeyModulus);
        return list;
    }

    //登录验证
    @RequestMapping(value = "/textLogin")
    @ResponseBody
    public String textLogin(String username, String password, HttpServletRequest request) {

        if (org.apache.commons.lang.StringUtils.isBlank(username)) {
            System.out.println("theusernameisnull");
            return "usernameIsNull";
        }
        if (org.apache.commons.lang.StringUtils.isBlank(password)) {
            System.out.println("thepasswordisnull");
            return "passwordIsNull";
        }
        RSAPrivateKey privateKey = (RSAPrivateKey) request.getSession().getAttribute("privateKeyLogin");
        try {
            username = RSAUtils.decryptByPrivateKey(username, privateKey);
            System.out.println("解密后的用户名:" + username);
            password = RSAUtils.decryptByPrivateKey(password, privateKey);
            System.out.println("解密后密码:" + password);
        } catch (Exception e) {
            log.error("RSA解密失败", e);
        }
        User user = userService.getUser(username);
        if (user != null) {
            if (password.equals(user.getPassword())) {
                System.out.println("登陆成功");
                return "success";
            }
        }
        System.out.println("登录失败");
        return "fail";
    }
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值