SpringBoot安全策略开发之集成数据传输加密
code2roc 人气:0前言
近期在对开发框架安全策略方面进行升级优化,提供一些通用场景的解决方案,本文针对前后端数据传输加密进行简单的分享,处理流程设计如下图所示,本加密方法对原有项目兼容性较好,只需要更换封装好的加密Ajax请求方法,后端统一拦截判断是否需要解密即可
生成DESKey
生成的DES加密密钥一定是8的整数倍的位数
function getRandomStr() { let str = "" let array = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", ]; for (let i = 0; i < 8; i++) { str += array[Math.round(Math.random() * (array.length - 1))]; } return str; }
生成RSA密钥对
RSA密钥对有很多种格式,因为需要和前端算法库互联互通,这里选择的是1024位,Padding方式为PKSC1
public static Map<String, String> createKeysPKSC1(int keySize) { // map装载公钥和私钥 Map<String, String> keyPairMap = new HashMap<String, String>(); try { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SecureRandom random = new SecureRandom(); KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC"); generator.initialize(keySize, random); KeyPair keyPair = generator.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded())); String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded())); keyPairMap.put("publicKey", publicKeyStr); keyPairMap.put("privateKey", privateKeyStr); } catch (Exception e) { e.printStackTrace(); } // 返回map return keyPairMap; }
前端DES加密
引入crypto.js第三方库
function encryptByDES(message, key) { var keyHex = CryptoJS.enc.Utf8.parse(key); var encrypted = CryptoJS.DES.encrypt(message, keyHex, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return encrypted.toString(); }
前端RSA加密
引入jsencrypt,js第三方库
function encryptByRSA(data, publicKey) { var encryptor = new JSEncrypt() encryptor.setPublicKey(publicKey) return encryptor.encrypt(data);; }
后端RSA解密
public static String decryptPKSC1(String data, String privateKeyStr) { try { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC"); RSAPrivateKey privateKey = getPrivateKeyPKSC1(privateKeyStr); cipher.init(Cipher.DECRYPT_MODE, privateKey); return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET); } catch (Exception e) { throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); } }
后端DES解密
public static String decrypt(String data, String key) throws IOException, Exception { if (data == null) return null; BASE64Decoder decoder = new BASE64Decoder(); byte[] buf = decoder.decodeBuffer(data); byte[] bt = decrypt(buf, key.getBytes("UTF-8")); return new String(bt, "UTF-8"); }
后端自定义拦截器
public class XSSFilter implements Filter, Ordered { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String contentType = request.getContentType(); if (StringUtils.isNotBlank(contentType) && contentType.contains("application/json")) { XSSBodyRequestWrapper xssBodyRequestWrapper = new XSSBodyRequestWrapper((HttpServletRequest) request); chain.doFilter(xssBodyRequestWrapper, response); } else { chain.doFilter(request, response); } } @Override public int getOrder() { return 9; } }
public class XSSBodyRequestWrapper extends HttpServletRequestWrapper { private String body; public XSSBodyRequestWrapper(HttpServletRequest request) { super(request); try{ body = XSSScriptUtil.handleString(CommonUtil.getBodyString(request)); String encrypt = request.getHeader("encrypt"); if (!StringUtil.isEmpty(encrypt)) { String privateKey = RSAEncryptUtil.getSystemDefaultRSAPrivateKey(); String desEncryptStr = RSAEncryptUtil.decryptPKSC1(encrypt, privateKey); JSONObject obj = JSONObject.parseObject(body); String encryptParam = obj.getString("encryptParam"); body = DESEncryptUtil.decrypt(encryptParam, desEncryptStr); } }catch (Exception e){ e.printStackTrace(); } } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(Charset.forName("UTF-8"))); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } }
加载全部内容