RSA加密工具类

RSA加密工具类

原文链接:https://blog.csdn.net/sly1311220942/article/details/86583004

 
1.为什么要加密
由于部分数据是需要保密的比如用户名密码之类,为了防止被人抓包后数据泄露,因此需要对数据进行一定的加密,通常比较常用的就是rsa加密了.

2.工具类实现
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
 
/**
 * rsa加密工具类
 * @author sly
 * @time 2018年12月12日
 */
public class RsaUtils {
    public static final String KEY_ALGORITHM = "RSA";
    /** 貌似默认是RSA/NONE/PKCS1Padding,未验证 */
    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
    public static final String PUBLIC_KEY = "B38A579FFE8711E88737000C29048FA8";
    public static final String PRIVATE_KEY = "BCB81751FE8711E88737000C29048FA8";
 
    /** RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024 */
    public static final int KEY_SIZE = 2048;
 
    /**
     * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥
     * 
     * @return
     */
    public static Map<String, byte[]> generateKeyBytes() {
 
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
 
            Map<String, byte[]> keyMap = new HashMap<String, byte[]>(16);
            keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
            keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范
     * 
     * @param keyBytes
     * @return
     */
    public static PublicKey restorePublicKey(byte[] keyBytes) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
 
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范
     * 
     * @param keyBytes
     * @return
     */
    public static PrivateKey restorePrivateKey(byte[] keyBytes) {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);
            return privateKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 加密,三步走。
     * 
     * @param key
     * @param plainText
     * @return
     */
    public static byte[] rsaEncode(PublicKey key, byte[] plainText) {
 
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(plainText);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
                | BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
 
    }
 
    /**
     * 解密,三步走。
     * 
     * @param key
     * @param encodedText
     * @return
     */
    public static String rsaDecode(PrivateKey key, byte[] encodedText) {
 
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            return new String(cipher.doFinal(encodedText));
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
                | BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
 
    }
}
3.使用
以登录作为演示场景:

首先需要再跳转至登录页面时将公钥传入页面,私钥传入session

    /**
     * 
     * @param request
     * @param response
     * @return
     * @author sly
     * @time 2018年11月25日
     */
    @RequestMapping("/login/toLogin")
    public String toLogin(HttpServletRequest request,HttpServletResponse response) {
        Map<String, byte[]> keyMap = RsaUtils.generateKeyBytes();
        
        PublicKey publicKey = RsaUtils.restorePublicKey(keyMap.get(RsaUtils.PUBLIC_KEY));
        PrivateKey privateKey = RsaUtils.restorePrivateKey(keyMap.get(RsaUtils.PRIVATE_KEY));
        request.setAttribute(RsaConstant.PUBLICK_KEY, Base64.encodeBase64String(publicKey.getEncoded()));
        request.getSession().setAttribute(RsaConstant.PRIVATE_KEY,privateKey);
        return "/system/login/login.jsp";
    }
在页面上使用js获取公钥进行加密(该js上网搜就有)

function login() {
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey($("#publicKey").val());
    // 加密后的字符串
    var username = $.trim($("#username").val());
    var password = $.trim($("#password").val());
    var validate = $.trim($("#validate").val());
    var _997D08B3 = encrypt.encrypt(username);
    var _3DCBF670 = encrypt.encrypt(password);
    var _1EE97457 = encrypt.encrypt(validate);
 
    if (!username) {
        layer.alert("请输入用户名!");
        return;
    }
    if (!password) {
        layer.alert("请输入密码!");
        return;
    }
    if (!validate) {
        layer.alert("请输入验证码!");
        return;
    }
 
    $.ajax({
        type : "post",
        url : webRoot + "/system/login/login",
        dataType : 'json',
        data : {
            a997d08b3 : _997D08B3,
            a3dcbf670 : _3DCBF670,
            a1ee97457 : _1EE97457,
            isAjax : 1
        },
        success : function(data) {
            if (data.status == 200) {
                top.location = webRoot + "/index/home";
            } else if (data.status == 300) {
                eval(data.evalCode);
            } else {
                $("#publicKey").val(data.dataMap.publicKey);
                layer.alert(data.message, { icon: 2 });
            }
        }
    });
}
后台解密

    /**
     * 登录
     * @param request
     * @param response
     * @param a997d08b3 用户名
     * @param a3dcbf670 密码
     * @param a1ee97457 验证码
     * @return
     * @author sly
     * @time 2018年12月12日
     */
    @ResponseBody
    @RequestMapping("/login/login")
    public BaseResult login(HttpServletRequest request,HttpServletResponse response,String a997d08b3,String a3dcbf670,String a1ee97457) {
        try {
            
        
            //获取私钥用于解密
            PrivateKey privateKey = (PrivateKey) request.getSession().getAttribute(RsaConstant.PRIVATE_KEY);
            
            //验证验证码
            String validateCode = RsaUtils.rsaDecode(privateKey, Base64.decodeBase64(a1ee97457));
            String verifyCode = (String) request.getSession().getAttribute(CommonConstant.LOGIN_VALIDATECODE_KEY);
            if(verifyCode == null || !verifyCode.equals(validateCode)) {
                return new BaseResult(ResultStatus.FAILED, Message.VERIFY_ERROR);
            }
            
            String username = RsaUtils.rsaDecode(privateKey, Base64.decodeBase64(a997d08b3));
            String password = RsaUtils.rsaDecode(privateKey, Base64.decodeBase64(a3dcbf670));
            BaseResult result = loginService.login(username,password);
            //登录成功
            if(result.getStatus() == ResultStatus.SUCCESS) {
                //防止sessionId  劫持  登录成功后清除sessionId
                request.getSession().invalidate();
                //保存用户数据到session
                request.getSession().setAttribute(CommonConstant.SESSION_USER, result.getValue(CommonConstant.SESSION_USER));
                //保存登录id同步到redis用于单用户登录
                String loginId = (String) result.getValue(CommonConstant.LOGIN_ID);
                User existUser = FeignBeanUtils.getBaseResultObject("existUser", User.class, result);
                request.getSession().setAttribute(CommonConstant.LOGIN_ID, loginId);
                request.getSession().setAttribute(CommonConstant.SESSION_USER,existUser);
                webRedisHelper.putValue(existUser.getUserId(),CommonConstant.LOGIN_ID);
            }else {
                //重新生成公钥和私钥
                Map<String, byte[]> keyMap = RsaUtils.generateKeyBytes();
                PublicKey publicKey2 = RsaUtils.restorePublicKey(keyMap.get(RsaUtils.PUBLIC_KEY));
                PrivateKey privateKey2 = RsaUtils.restorePrivateKey(keyMap.get(RsaUtils.PRIVATE_KEY));
                request.getSession().setAttribute(RsaConstant.PRIVATE_KEY,privateKey2);
                //将公钥返回页面
                result.setValue("publicKey", Base64.encodeBase64String(publicKey2.getEncoded()));
            }
            
            return result;
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            return new BaseResult(ResultStatus.FAILED, LoginReturnCode.LOGIN_FAILE);
        }
    }
大功告成!
 
原文链接:https://blog.csdn.net/sly1311220942/article/details/86583004

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值