JavaWeb RSA密码加密登录

思路:每次登录前,向后端发送请求,由RSA生成一对公钥和私钥,用redis或者数据库保存用户名对应的私钥,获取公钥中的modulus和publicExponent,分别调用String#toString(int)方法,然后传到前端,前端使用security.js加密密码,然后进行登录,在后端使用私钥解密,再验证密码的正确性。

注意:
- 每次登录都需要获取公钥和私钥
- 保证每次登录时,生成的公钥和私钥与用户名是对应的。


  • 1.在maven项目的pom.xml中添加下面的依赖,为了引入import org.bouncycastle.jce.provider.BouncyCastleProvider;作为安全服务提供者
        <dependency>
            <groupId>org.bouncycastlegroupId>
            <artifactId>bcprov-jdk16artifactId>
            <version>1.46version>
        dependency>
  • 2.RSAUtils工具类
    RSAUtils源码:https://pan.baidu.com/s/1mkd2WWg
  • 3.Controller接口,为了验证加密和解密的操作是否可行。(此接口要绕过拦截器)
    /**
     * 
     * @Title: generateRSAKey 
     * @Description: 生成公钥和私钥
     * @param username
     * @return  
     * @date 2018年2月5日 下午4:25:05
     * @author p7
     */
    @GetMapping(value = "/rsaKey/{username}")
    public ResultBean generateRSAKey(@PathVariable String username) {

        try {
            // 获取公钥和私钥
            HashMap keys = RSAUtils.getKeys();
            RSAPublicKey publicKey = (RSAPublicKey) keys.get("public");
            RSAPrivateKey privateKey = (RSAPrivateKey) keys.get("private");
            // 保存私钥到 redis,也可以保存到数据库
            boolean res = redisService.set(username, privateKey);
            if (!res) {
                throw new BusinessLogicException("redis 保存失败");
            }
            // 将公钥传到前端
            Map map = new HashMap();
            // 注意返回modulus和exponent以16为基数的BigInteger的字符串表示形式
            map.put("modulus", publicKey.getModulus().toString(16));
            map.put("exponent", publicKey.getPublicExponent().toString(16));

            return new ResultBean(map);
        } catch (NoSuchAlgorithmException e) {
            return new ResultBean(ResultBean.ERROR, e.getMessage());
        } catch (BusinessLogicException e) {
            return new ResultBean(ResultBean.ERROR, e.getMessage());
        }
    }

    /**
     * 
     * @Title: checkRSAKey 
     * @Description: 验证密码
     * @param username
     * @param password
     * @return  
     * @date 2018年2月5日 下午4:25:43
     * @author p7
     */
    @GetMapping(value = "/rsaKey/{username}/{password}")
    public ResultBean checkRSAKey(@PathVariable String username, @PathVariable String password) {
        Object object = redisService.get(username);
        try {
            // 解密
            String decryptByPrivateKey = RSAUtils.decryptByPrivateKey(password, (RSAPrivateKey) object);
            return new ResultBean(decryptByPrivateKey);
        } catch (Exception e) {
            return new ResultBean(ResultBean.ERROR, "解密失败");
        }
    }
  • 4.在登录页面引入security.js
    security.js:https://pan.baidu.com/s/1nxnArBN
  • 5.在登录的js中对接接口。
$(document).ready(function() {
    $(".loginBtn").click(function() {
        var uName = $(".userName").val(); //获取用户名
        var pWord = $(".passWord").val(); //获取账号
        // 获取
        $.ajax({
            type:"get",
            url:userBasePath+"rsaKey/"+uName,
            success:function(data){
                console.log(data);
                var pwdKey = new RSAUtils.getKeyPair(data.data.exponent,"",data.data.modulus);
                var reversedPwd = pWord.split("").reverse().join("");
                var encrypedPwd = RSAUtils.encryptedString(pwdKey,reversedPwd);
                console.log(encrypedPwd);
                $.ajax({
                    type:"get",
                    url:userBasePath+"rsaKey/"+uName+"/"+encrypedPwd,
                    success:function(data){
                        console.log(data);
                    },
                    error: function(result, status, xhr) {
                    }
                });
            },
            error: function(result, status, xhr) {
            }
        });
    }   
}   

你可能感兴趣的:(java,javascript)