一、需求概述:
为了满足360安全检测的要求,前端的密码不允许明文传输给后端进行密码验证,那么需要对密码进行前端加密,后端解密,目前流行的做法是采用RSA前端用公钥加密,后端用私钥解密的方案。
二、具体方案
(一)下载 支付宝生成公私钥的工具AlipayDevelopmentAssistant,分别生成公钥和私钥,如下图:
(二)vue前端配置内容:
1. 前端工程中安装jsencrypt,例如:npm install jsencrypt;
2. vue的main.js中声明为全局变量,实现全局签名的功能:
// 引入全局签名加密法
import JsEncrypt from 'jsencrypt'
/**
* 配置全局的加密方法
* @param obj 需要加密的字符串
*/
Vue.prototype.$encruption = function (obj) {
let encrypt = new JsEncrypt()
// 公钥
encrypt.setPublicKey(
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo8bNy2BkiGIQu4xW2A3ChLcFchM6rLZaK/FBCmtVZjxLzeLSDEDA2m3q6f8dHa2ujf1uyzQ5NybxGl577LJpSapFom1xR6BmwaJ1nvecBB4PpAQduA9w7GZ/MAlQyZzJetf6mEAtb24x6rKEBJevCflWeGc3UA4ehUAper1xV08XvZCquN2IRMwHYgVfwcWtMNrlbhNsoIxdkhWvdpDDYIUWj8fqQVuosnXnqZwvqX9xl4003clc2FnxAediLY5O0UjzA7AYt5D6mqX1xomcv432vW31UIVBrLNu+BLJ7EMtXb9CogudbtQKSDiOzGOlrtTCBZbgJlcqM2NE26z4pwIDAQAB'
)
return encrypt.encrypt(obj)
}
3. 改造登录界面,对密码进行签名加密:
如果还有锁屏功能,也要在锁屏界面输入密码后对其进行加密。
(三)spring boot配置内容:
1.编写RSA加密与解密工具类,例如:
package com.zjm.gwork.utils;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: RsaUtil
* @Description: RSA加解密工具类
* 1.
* 2.
* @Author: zhongzk 28582157@qq.com
* @Date: 2020/1/7 2:08 *
* @Copyright: 字节码团队www.bjsurong.com. All rights reserved. *
*/
public class RsaUtil {
private static final int DEFAULT_RSA_KEY_SIZE = 2048;
private static final String KEY_ALGORITHM = "RSA";
public static void main(String [] args){
Map<String,String> result = generateRsaKey(DEFAULT_RSA_KEY_SIZE);
System.out.println("公钥为:" + result.get("publicKey") );
System.out.println("私钥为:" + result.get("privateKey"));
}
/**
* 生成RSA 公私钥,可选长度为1025,2048位.
*/
public static Map<String,String> generateRsaKey(int keySize) {
Map<String,String> result = new HashMap<>(2);
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 初始化密钥对生成器,密钥大小为1024 2048位
keyPairGen.initialize(keySize, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到公钥字符串
result.put("publicKey", new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())));
// 得到私钥字符串
result.put("privateKey", new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return result;
}
/**
* RSA私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey) {
//64位解码加密后的字符串
byte[] inputByte;
String outStr = "";
try {
inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
outStr = new String(cipher.doFinal(inputByte));
} catch (UnsupportedEncodingException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return outStr;
}
}
2. application.yml中定义私钥:
# RSA 加解密
auth:
# 私钥的key
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjxs3LYGSIYhC7jFbYDcKEtwVyEzqstlor8UEKa1VmPEvN4tIMQMDaberp/x0dra6N/W7LNDk3JvEaXnvssmlJqkWibXFHoGbBonWe95wEHg+kBB24D3DsZn8wCVDJnMl61/qYQC1vbjHqsoQEl68J+VZ4ZzdQDh6FQCl6vXFXTxe9kKq43YhEzAdiBV/Bxa0w2uVuE2ygjF2SFa92kMNghRaPx+pBW6iydeepnC+pf3GXjTTdyVzYWfEB52Itjk7RSPMDsBi3kPqapfXGiZy/jfa9bfVQhUGss274EsnsQy1dv0KiC51u1ApIOI7MY6Wu1MIFluAmVyozY0TbrPinAgMBAAECggEBAJB8oa5dOhRAP/bWFv/BE+018m3znP4mWmMOEo14p/zsEQxwoVMCBaIu+uK5mRxH0AmgnpBTYG7Rwj+7P6VQuSauO4TS/O9uCXmnNBGs7U2Mn8vZfcaWiM9mlarxbP6RfgcMaB7N78ew9gTSvTm4AErSWIEcvmW4LyDrvCx22Xll9cXhgqcQbgDKgoujFuOGGGmLaijW0qjt23OpQuxvSoERZ8XB4hSNOkZLTFV5qrUbRF3NnysvBdhom2joHqS0lJQeVq44+QBBX2Mv4+a4odEBp9/VCWUYmSZZUsYQxFZL+f/DyzrAyQG/G4gTtvkwpmXE2veOmNSzC5beprsG9wECgYEA8MgpghPwgLuAuUeyyrmrds1iqLVlMxjIvGD6gB9EJte+dmsa2hR2Z3t5Zh7en96ZVDjPSG2eiUjkp5pLhz7MsiqtXvk3afHPOJ3/tkqpZ7C0IeR+d63UXJD8DrWbMOwih8JfPu9B+05IECv7GrwyBaMGBzJkeHFEJRMtCr7yYEECgYEAriCzNxf6niJdqkujyJpGEIZKLoQp8gPzHEidMmpIw5pEAUydg4zUL9Dr1B1peqbAWVD0QX/Sn1DyMU1zvgryRn5ovG2C7osfsDPth2ePKRZPOSVIUotv0xedOt/9FO+DcetUxcd5RZhQsYbDwhfCDJ64tAWxMdNTJjyHvhOQnucCgYEApSzKvL8s90KpdXDoCAYCyAbxLUby23CfFAt7DLVmLTdHIzkqPHxZFXgwuYtnsUgk6w/lsovwe8ETip5gPbEo/vgj4skX6IfHXdGVf9oMCGPBzpZO447N5YpYP0b55T+4GGWQrT24h8sVyHJDWf3MWu2QzxMUtUMOOljDR2HiJ4ECgYAYtv949GhYBZyxzSakFHGZatYgoBWsCi95dj0JqNhHGyBH5u38fAKp/sdaRgpwpDZs9vaUTWZBwqV9pfalpLwakVqgVBLfdNO8mMJAE8zYEhiQjeAkBzKKDbH9Z0lurUhE5RgVMmjeHe5mJDCo3eJnFCg3NQ+feNU2eiTyL6i5RQKBgGoHWaGtPt2uUZnny1iFngFGxO4RMQ7AEzzhwAjMr7na+T/iV0x6aXFCejkdXbbFTwJKu3XcSr7vrZgI0ynuP2G3DQf8UPixt+PsHpakSahzFOiBd99xQOscgc/pZ8r1E8hwUOrx9Z2b+caK2DGxWexyMZ/d3ed6uamC3Okt84+7
3. 改造登录的service,对前端传过来的密码利用私钥进行解密,例如:
总结,前后端利用RSA的实战就介绍到这里。
文章版权声明: 热水 2020.1.7 于北京,不得转载。