Rsa非对称性算法-springboot实现

Rsa非对称性算法-springboot实现

使用这个算法增强表单提交的安全性。

原理相当简单如下:

假设后端a和前端b是两个人,a有两把钥匙(俗称:公钥和秘钥,他们是一对的缺一不可),a把私钥留给自己,公钥给了b,b可以使用公钥对账号密码加密。但是b无法解密因为私钥在a的手上,b把加密后的东西给a。a用私钥解密。这就完成了Rsa的实现原理。

1、引入maven依赖替换Base64

<!-- 替换sun.misc.BASE64Encoder  Rsa非对称性算法-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

2、工具类RsaUtils

package com.su.main.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加解密工具类,实现公钥加密私钥解密和私钥解密公钥解密
 */
public class RSAUtils {

    private static final String src = "123abc";


    public static void main(String[] args) throws Exception {
        System.out.println("\n");
        RSAKeyPair keyPair = generateKeyPair();
        System.out.println("公钥:" + keyPair.getPublicKey());
        System.out.println("私钥:" + keyPair.getPrivateKey());
        System.out.println("\n");
        test1(keyPair, src);
        System.out.println("\n");
        test2(keyPair, src);
        System.out.println("\n");
    }

    /**
     * 公钥加密私钥解密
     */
    private static void test1(RSAKeyPair keyPair, String source) throws Exception {
        System.out.println("***************** 公钥加密私钥解密开始 *****************");
        String text1 = encryptByPublicKey(keyPair.getPublicKey(), source);
        String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
        System.out.println("加密前:" + source);
        System.out.println("加密后:" + text1);
        System.out.println("解密后:" + text2);
        if (source.equals(text2)) {
            System.out.println("解密字符串和原始字符串一致,解密成功");
        } else {
            System.out.println("解密字符串和原始字符串不一致,解密失败");
        }
        System.out.println("***************** 公钥加密私钥解密结束 *****************");
    }

    /**
     * 私钥加密公钥解密
     *
     * @throws Exception
     */
    private static void test2(RSAKeyPair keyPair, String source) throws Exception {
        System.out.println("***************** 私钥加密公钥解密开始 *****************");
        String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), source);
        String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
        System.out.println("加密前:" + source);
        System.out.println("加密后:" + text1);
        System.out.println("解密后:" + text2);
        if (source.equals(text2)) {
            System.out.println("解密字符串和原始字符串一致,解密成功");
        } else {
            System.out.println("解密字符串和原始字符串不一致,解密失败");
        }
        System.out.println("***************** 私钥加密公钥解密结束 *****************");
    }

    /**
     * 公钥解密
     *
     * @param publicKeyText
     * @param text
     * @return
     * @throws Exception
     */
    public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param privateKeyText
     * @param text
     * @return
     * @throws Exception
     */
    public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 私钥解密
     *
     * @param privateKeyText
     * @param text
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyText
     * @param text
     * @return
     */
    public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 构建RSA密钥对
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static RSAKeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        RSAKeyPair rsaKeyPair = new RSAKeyPair(publicKeyString, privateKeyString);
        return rsaKeyPair;
    }


    /**
     * RSA密钥对对象
     */
    public static class RSAKeyPair {

        private String publicKey;
        private String privateKey;

        public RSAKeyPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }

    }

}


3、controller 的调用

package com.su.main.controller;

import com.su.main.utils.RSAUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.security.NoSuchAlgorithmException;

import static com.su.main.utils.RSAUtils.generateKeyPair;

/**
 * TODO
 *
 * @author Administrator
 * @version 1.0
 * @date 2020/10/28 17:44
 */
@Controller
public class RsaTest {


    @RequestMapping("/rsa")
    public String toRsaTest(){
        return "rsaTest";
    }

    @RequestMapping("/getPublicKey")
    @ResponseBody
    public String buildKeyPair(HttpSession session) throws NoSuchAlgorithmException {
        RSAUtils.RSAKeyPair rsaKeyPair = generateKeyPair();
        //如果这个session存在,先删除后添加
        if(session.getAttribute("privateKeySu")!=null){
            session.removeAttribute("privateKeySu");
            session.setAttribute("privateKeySu",rsaKeyPair.getPrivateKey());
            System.out.println("privateKeySu:"+rsaKeyPair.getPrivateKey());
        }else {
            session.setAttribute("privateKeySu",rsaKeyPair.getPrivateKey());
            System.out.println("privateKeySu:"+rsaKeyPair.getPrivateKey());
        }

        String publicKey = rsaKeyPair.getPublicKey();

        System.out.println("publicKey:"+publicKey);
        //返回公钥
        return rsaKeyPair.getPublicKey();
    }


    @RequestMapping("/aaa")
    @ResponseBody
    public String Login(String name, HttpSession session) throws Exception {
        String comeBackMsg;
        //获得秘钥对
        if(session.getAttribute("privateKeySu")!=null){
            String privateKey = (String) session.getAttribute("privateKeySu");
            System.out.println("privateKey:"+privateKey);
            //获取私钥解密方法
            RSAUtils rsaUtils = new RSAUtils();

            String changeName = rsaUtils.decryptByPrivateKey(privateKey, name);

            comeBackMsg = "私钥解开了!解开为:"+changeName;
        }else{
            comeBackMsg = "抱歉你没有权限";
        }


        return comeBackMsg;
    }



}

4、前端页面设计和js的导入

前端页面设计:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        账号:<input type="text" id="name1" name="name1" oninput="getPublicKey(this)" >
    </div>
    <div>
        密码:<input type="password" id="pwd1" name="pwd1">
    </div>
    <div>
        <button type="button" name="aaa" onclick="clickA(this)">aaa</button>
    </div>

    <form action="">

        <input type="hidden" id="name2" name="name2">
        <input type="hidden" id="pwd2" name="pwd2">
        <input type="hidden" id="publicKey" name="publicKey">
        <input type="submit" value="提交">
    </form>


<script type="text/javascript"  src="/Rsa/js/jquery.min-2.1.4.js"></script>
    <!--Rsa非对称性算法前端js-->
<script type="text/javascript"  src="/Rsa/js/jsencrypt.min.js"></script>
<script>


    //oninput 当表单的value值改变是触发,但js改变value的值不会触发
    function getPublicKey(e) {
        // 3-Url参数加密类
        //公钥加密
        var encrypt = new JSEncrypt();

        //获取公钥
        $.post(
            "/getPublicKey",
            function (r) {

                //获取公钥
                console.log(r);
                let pkey = r;
                console.log(pkey);
                $("#publicKey").val(pkey);
                //公匙加密
                encrypt.setPublicKey(pkey);
                let name1 = $("#name1").val();
                console.log("name1加密前:"+name1);
                let name2;
                name2 = encrypt.encrypt(JSON.stringify(name1));
                console.log("name2加密后:"+name2);
                $("#name2").val(name2);

            }
        );


    }

    function clickA() {
        //获取加密后的密码上交解密
        if($("#name2").val()!=null){
            let name2 = $("#name2").val();
            console.log(name2);
            $.post(
                "/aaa",
                {
                    name : name2
                },
                function (r) {
                    alert(r);

                }
            );
        }else {
            alert("请输入你的账号在试试点击我!");
        }


    }

</script>

</body>
</html>

js的引入(需要jQuery和jsencrypt.min.js(前端Rsa的库))

这两个js自行去网站下载即可啦,jQuery要求不高,其他版本也可以,jsencrypt.min.js,百度一下在别人项目里面拿也可以
粟德桡 QQ:648713624

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值