亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java如何實(shí)現(xiàn)http接口參數(shù)和返回值加密

 更新時(shí)間:2022年11月17日 12:02:17   作者:站在墻頭上  
這篇文章主要介紹了Java如何實(shí)現(xiàn)http接口參數(shù)和返回值加密問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

參數(shù)和返回值得加密目的

為了保證接口不被人攔截下來(lái)惡意請(qǐng)求,保證程序的穩(wěn)定性,我們可以使用接口加密的方法來(lái)保證參數(shù)和返回值的保密性。

具體實(shí)現(xiàn)方式

因?yàn)楸救耸菍?xiě)Java 的,所以這里就直接以Java代碼為例。思想都是一樣的,只是不同的語(yǔ)言都不同的實(shí)現(xiàn)方式。

大致思路

  • 我們的參數(shù)和返回值只需要定義兩個(gè)參數(shù):ak,ct,ak存放堆成加密的秘鑰,ct存放加密之后的請(qǐng)求內(nèi)容。
  • 加密方式用到AES對(duì)稱(chēng)加密和RSA非對(duì)稱(chēng)加密,將請(qǐng)求參數(shù)使用AES加密,HTTP的POST請(qǐng)求和GET請(qǐng)求都可以將實(shí)際請(qǐng)求參數(shù)的格式定義成同一種格式(比如:JSON格式),便于后臺(tái)處理。AES加密使用的秘鑰用RSA加密。這樣我們就不需要操心參數(shù)加密的秘鑰是什么了,雙方都可以隨時(shí)更換。
  • 使用過(guò)濾器獲取到請(qǐng)求的加密內(nèi)容后,通過(guò)RSA解密將參數(shù)加密的秘鑰解析出來(lái),然后再通過(guò)解析出來(lái)的秘鑰通過(guò)AES解密去獲取實(shí)際的請(qǐng)求內(nèi)容。

注意:不同的請(qǐng)求方式獲取參數(shù)的方式不同,需要根據(jù)不同的請(qǐng)求方式去做不同的解析

代碼實(shí)現(xiàn)

1. 首先需要一個(gè)過(guò)濾器,因?yàn)槲覀円獢r截請(qǐng)求參數(shù),和加密返回的數(shù)據(jù)。

因?yàn)椴⒉皇撬械慕涌诙夹枰用?,過(guò)濾器不能想Spring攔截器那樣直接配置攔截和不攔截的類(lèi),所以定義了一個(gè)ALLOWED_PATHS 集合,用于過(guò)濾不需要加解密的請(qǐng)求。然后根據(jù)不同的請(qǐng)求方式去解析不同的請(qǐng)求內(nèi)容,我這里只處理了get請(qǐng)求和post請(qǐng)求這兩種常用的請(qǐng)求方式。

package com.pay.filter;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
?* 請(qǐng)求信息加解密
?*/
@Log4j2
@Component
@WebFilter(filterName = "EncryptionFilter", urlPatterns = {"/*"})
public class EncryptionFilter implements Filter {

? ? private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
? ? ? ? ? ? Arrays.asList("/pay/notify")));
? ? @Override
? ? public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
? ? ? ? if(request instanceof HttpServletRequest) {
? ? ? ? ? ? HttpServletRequest hRequest = (HttpServletRequest) request;
? ? ? ? ? ? String servletPath = hRequest.getServletPath();
? ? ? ? ? ? log.info("request_path:path="+servletPath);
? ? ? ? ? ? boolean allow = false;
? ? ? ? ? ? for (String allowedPath : ALLOWED_PATHS) {
? ? ? ? ? ? ? ? if(servletPath.contains(allowedPath)) {
? ? ? ? ? ? ? ? ? ? allow = true;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if(allow) {
? ? ? ? ? ? ? chain.doFilter(request, response);
? ? ? ? ? ? ? log.info("no Encryption");
? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? MyHttpServletResponseWrapper responseWrapper = new MyHttpServletResponseWrapper((HttpServletResponse) response);
? ? ? ? ? ? if(hRequest.getMethod().equalsIgnoreCase("post")) {
? ? ? ? ? ? ? ? MyHttpServletRequestWrapper requestWrapper = null;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? requestWrapper = new MyHttpServletRequestWrapper(hRequest);
? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? request.getRequestDispatcher("404.html").forward(request,response);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? chain.doFilter(requestWrapper, responseWrapper);
? ? ? ? ? ? }else if(!hRequest.getMethod().equalsIgnoreCase("options")){
? ? ? ? ? ? ? ? log.info("收到 potions請(qǐng)求");
? ? ? ? ? ? } else { //其余默認(rèn)get請(qǐng)求
? ? ? ? ? ? ? ? ParameterRequestWrapper requestWrapper = null;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? requestWrapper = new ParameterRequestWrapper(hRequest);
? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? request.getRequestDispatcher("404.html").forward(request,response);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? chain.doFilter(requestWrapper, responseWrapper);
? ? ? ? ? ? }
? ? ? ? ? ? String resp = responseWrapper.getTextContent(); //獲取接口返回內(nèi)容
? ? ? ? ? ? //加密處理返回
? ? ? ? ? ? response.getOutputStream().write(HttpEncryptUtil.serverEncrypt(resp).getBytes(StandardCharsets.UTF_8));
? ? ? ? }
? ? }
}

2. 對(duì)于POST請(qǐng)求,定義一個(gè)解析request中參數(shù)的類(lèi) MyHttpServletRequestWrapper繼承HttpServletRequestWrapper ,去解析請(qǐng)求參數(shù)。

具體實(shí)現(xiàn)方式如下:

readBody:實(shí)際解析請(qǐng)求參數(shù)

package com.pay.filter;

import com.alipay.api.internal.util.file.IOUtils;
import com.pay.util.HttpEncryptUtil;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {

? ? private String requestBody = null;

? ? public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
? ? ? ? super(request);
? ? ? ? requestBody = readBody(request);
? ? }

? ? @Override
? ? public BufferedReader getReader() {
? ? ? ? return new BufferedReader(new InputStreamReader(getInputStream()));
? ? }

? ? @Override
? ? public ServletInputStream getInputStream() {
? ? ? ? final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
? ? ? ? return new ServletInputStream() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean isFinished() {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }

? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean isReady() {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }

? ? ? ? ? ? @Override
? ? ? ? ? ? public void setReadListener(ReadListener readListener) {

? ? ? ? ? ? }

? ? ? ? ? ? @Override
? ? ? ? ? ? public int read() throws IOException {
? ? ? ? ? ? ? ? return bais.read();
? ? ? ? ? ? }
? ? ? ? };
? ? }

? ? private static String readBody(ServletRequest request) throws IOException {

? ? ? ? String param = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
? ? ? ? if(StringUtils.isNotBlank(param)) {
? ? ? ? ? ? //解密請(qǐng)求參數(shù)
? ? ? ? ? ? return HttpEncryptUtil.serverDecrypt(param);
? ? ? ? }
? ? ? ? return param;
? ? }
}

3. 對(duì)于get請(qǐng)求,定義一個(gè)參數(shù)類(lèi)ParameterRequestWrapper,繼承HttpServletRequestWrapper 去解析URL上的參數(shù)

具體方式如下:

重載構(gòu)造方法獲取加密之后的參數(shù),去解析出來(lái)

ParameterRequestWrapper(HttpServletRequest request)

重寫(xiě)getParameter和setParameter等獲取參數(shù)和設(shè)置參數(shù)的方法

package com.pay.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.pay.util.HttpEncryptUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;

public class ParameterRequestWrapper extends HttpServletRequestWrapper {
? ? private Map<String , String[]> params = new HashMap<String, String[]>();


? ? @SuppressWarnings("unchecked")
? ? public ParameterRequestWrapper(HttpServletRequest request) {
? ? ? ? // 將request交給父類(lèi),以便于調(diào)用對(duì)應(yīng)方法的時(shí)候,將其輸出,其實(shí)父親類(lèi)的實(shí)現(xiàn)方式和第一種new的方式類(lèi)似
? ? ? ? super(request);
? ? ? ? //將參數(shù)表,賦予給當(dāng)前的Map以便于持有request中的參數(shù)
? ? ? ? //解析
? ? ? ? String ak = request.getParameter("ak");
? ? ? ? String ct = request.getParameter("ct");
? ? ? ? JSONObject jsonObject = new JSONObject();
? ? ? ? jsonObject.put("ak",ak);
? ? ? ? jsonObject.put("ct",ct);
? ? ? ? String s = HttpEncryptUtil.serverDecrypt(jsonObject.toJSONString());
? ? ? ? addAllParameters(JSON.parseObject(s));
? ? }
? ? //重載一個(gè)構(gòu)造方法
? ? public ParameterRequestWrapper(HttpServletRequest request , Map<String , Object> extendParams) {
? ? ? ? this(request);
? ? ? ? addAllParameters(extendParams);//這里將擴(kuò)展參數(shù)寫(xiě)入?yún)?shù)表
? ? }

? ? @Override
? ? public String getParameter(String name) {//重寫(xiě)getParameter,代表參數(shù)從當(dāng)前類(lèi)中的map獲取
? ? ? ? String[]values = params.get(name);
? ? ? ? if(values == null || values.length == 0) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? return values[0];
? ? }

? ? public String[] getParameterValues(String name) {//同上
? ? ? ? return params.get(name);
? ? }

? ? public void addAllParameters(Map<String , Object>otherParams) {//增加多個(gè)參數(shù)
? ? ? ? for(Map.Entry<String , Object>entry : otherParams.entrySet()) {
? ? ? ? ? ? addParameter(entry.getKey() , entry.getValue());
? ? ? ? }
? ? }


? ? public void addParameter(String name , Object value) {//增加參數(shù)
? ? ? ? if(value != null) {
? ? ? ? ? ? if(value instanceof String[]) {
? ? ? ? ? ? ? ? params.put(name , (String[])value);
? ? ? ? ? ? }else if(value instanceof String) {
? ? ? ? ? ? ? ? params.put(name , new String[] {(String)value});
? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? params.put(name , new String[] {String.valueOf(value)});
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

注意:為了便于區(qū)分我才把獲取post請(qǐng)求內(nèi)容和get請(qǐng)求內(nèi)容的類(lèi)寫(xiě)成了兩個(gè),其實(shí)可以嘗試著去將兩個(gè)解析類(lèi)合成一個(gè)

4. 加解密工具類(lèi) HttpEncryptUtil ,和兩個(gè)網(wǎng)上百度的AESUtil,RSAUtil

package com.pay.util;

import com.alibaba.fastjson.JSONObject;
import com.pay.common.Constant;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;

public class HttpEncryptUtil {

? ? //解密請(qǐng)求內(nèi)容
? ? public static String serverDecrypt(String content) {
? ? ? ? JSONObject result = JSONObject.parseObject(content);
? ? ? ? String encryptAesKeyStr = result.getString("ak");
? ? ? ? String encryptContent = result.getString("ct");
? ? ? ? //使用私鑰解密 獲取解密內(nèi)容的AES密鑰
// ? ? ? ?encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解碼

? ? ? ? PrivateKey privateKey = RSAUtil.getPrivateKey(HTTP_PRIVATE_KEY);
? ? ? ? String aesKey = RSAUtil.decryptByPrivate(decodeBase64String(encryptAesKeyStr), privateKey);
? ? ? ? //使用解密出來(lái)的key解密content:使用AES
? ? ? ? return AESUtil.decryptAES(decodeBase64String(encryptContent), aesKey);
? ? }

? ? public static String serverDecryptByPublic(String content) {
? ? ? ? JSONObject result = JSONObject.parseObject(content);
? ? ? ? String encryptAesKeyStr = result.getString("ak");
? ? ? ? String encryptContent = result.getString("ct");
? ? ? ? //使用私鑰解密 獲取解密內(nèi)容的AES密鑰
// ? ? ? ?encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解碼
? ? ? ? RSAPublicKey publicKey = RSAUtil.getPublicKey(HTTP_PUBLIC_KEY);
? ? ? ? String aesKey = RSAUtil.decryptByPublic(decodeBase64String(encryptAesKeyStr), publicKey);
? ? ? ? //使用解密出來(lái)的key解密content:使用AES
? ? ? ? return AESUtil.decryptAES(decodeBase64String(encryptContent), aesKey);
? ? }

? ? //加密返回內(nèi)容
? ? public static String serverEncrypt(String content) {
? ? ? ? String aesKey = HTTP_CONTENT_KEY;
? ? ? ? //使用私鑰加密AES的key
? ? ? ? PrivateKey privateKey = RSAUtil.getPrivateKey(HTTP_PRIVATE_KEY);
? ? ? ? String ak = RSAUtil.encryptByPrivate(aesKey.getBytes(StandardCharsets.UTF_8), privateKey);
? ? ? ? String ct = AESUtil.encryptAES(content, aesKey);
? ? ? ? JSONObject result = new JSONObject();
? ? ? ? result.put("ak",encodeBase64String(ak));
? ? ? ? result.put("ct",encodeBase64String(ct));
? ? ? ? return result.toJSONString();
? ? }

? ? public static String serverEncryptByPublic(String content) {
? ? ? ? String aesKey = HTTP_CONTENT_KEY;
? ? ? ? //使用公鑰鑰加密AES的key
? ? ? ? RSAPublicKey publicKey = RSAUtil.getPublicKey(HTTP_PUBLIC_KEY);
? ? ? ? String ak = RSAUtil.encryptByPublic(aesKey.getBytes(StandardCharsets.UTF_8), publicKey);
? ? ? ? String ct = AESUtil.encryptAES(content, aesKey);
? ? ? ? JSONObject result = new JSONObject();
? ? ? ? result.put("ak",encodeBase64String(ak));
? ? ? ? result.put("ct",encodeBase64String(ct));
? ? ? ? return result.toJSONString();
? ? }


? ? public static String encodeBase64String(String content) {
? ? ? ? if(StringUtils.isBlank(content)) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? return Base64.encodeBase64String(content.getBytes(StandardCharsets.UTF_8));
? ? }

? ? public static String decodeBase64String(String content) {
? ? ? ? if(StringUtils.isBlank(content)) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? return new String(Base64.decodeBase64(content), StandardCharsets.UTF_8);
? ? }
}
package com.pay.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AESUtil {

? ? public static final Charset CHARSET = StandardCharsets.UTF_8;
? ? public static final String ALGORITHMS_MD5 = "MD5";
? ? public static final String SHA = "SHA1PRNG";

? ? public static final String ALGORITHM = "AES";

? ? /**
? ? ?* 加密
? ? ?*
? ? ?* @param content ?需要加密的內(nèi)容
? ? ?* @param password 加密密碼
? ? ?* @return
? ? ?*/
? ? public static byte[] encrypt(String content, String password) {
? ? ? ? try {
? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance(SHA);
? ? ? ? ? ? random.setSeed(password.getBytes());
? ? ? ? ? ? kgen.init(128, random);
? ? ? ? ? ? SecretKey secretKey = kgen.generateKey();
? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded();
? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM);
? ? ? ? ? ? Cipher cipher = Cipher.getInstance(ALGORITHM);// 創(chuàng)建密碼器
? ? ? ? ? ? byte[] byteContent = content.getBytes(CHARSET);
? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
? ? ? ? ? ? return cipher.doFinal(byteContent); // 加密
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* 解密
? ? ?*
? ? ?* @param content ?待解密內(nèi)容
? ? ?* @param password 解密密鑰
? ? ?* @return
? ? ?*/
? ? public static byte[] decrypt(byte[] content, String password) {
? ? ? ? try {
? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance(SHA);
? ? ? ? ? ? random.setSeed(password.getBytes());
? ? ? ? ? ? kgen.init(128, random);
? ? ? ? ? ? SecretKey secretKey = kgen.generateKey();
? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded();
? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM);
? ? ? ? ? ? Cipher cipher = Cipher.getInstance(ALGORITHM);// 創(chuàng)建密碼器
? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
? ? ? ? ? ? return cipher.doFinal(content); // 加密
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* 將二進(jìn)制轉(zhuǎn)換成16進(jìn)制
? ? ?*
? ? ?* @param buf
? ? ?* @return
? ? ?*/
? ? public static String parseByte2HexStr(byte buf[]) {
? ? ? ? StringBuffer sb = new StringBuffer();
? ? ? ? for (int i = 0; i < buf.length; i++) {
? ? ? ? ? ? String hex = Integer.toHexString(buf[i] & 0xFF);
? ? ? ? ? ? if (hex.length() == 1) {
? ? ? ? ? ? ? ? hex = '0' + hex;
? ? ? ? ? ? }
? ? ? ? ? ? sb.append(hex.toUpperCase());
? ? ? ? }
? ? ? ? return sb.toString();
? ? }

? ? /**
? ? ?* 將16進(jìn)制轉(zhuǎn)換為二進(jìn)制
? ? ?*
? ? ?* @param hexStr
? ? ?* @return
? ? ?*/
? ? public static byte[] parseHexStr2Byte(String hexStr) {
? ? ? ? if (hexStr.length() < 1)
? ? ? ? ? ? return null;
? ? ? ? byte[] result = new byte[hexStr.length() / 2];
? ? ? ? for (int i = 0; i < hexStr.length() / 2; i++) {
? ? ? ? ? ? int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
? ? ? ? ? ? int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
? ? ? ? ? ? result[i] = (byte) (high * 16 + low);
? ? ? ? }
? ? ? ? return result;
? ? }

? ? private static byte[] doSign(String algorithms, String inputStr) throws NoSuchAlgorithmException {
? ? ? ? MessageDigest messageDigest = MessageDigest.getInstance(algorithms);
? ? ? ? messageDigest.update(inputStr.getBytes(CHARSET));
? ? ? ? return messageDigest.digest();
? ? }

? ? private static String signToHexStr(String algorithms, String inputStr) {
? ? ? ? try {
? ? ? ? ? ? return parseByte2HexStr(doSign(algorithms, inputStr));
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return null;
? ? ? ? }
? ? }

? ? public static String sign(String key, String sourceStr) {
? ? ? ? String md5Str1 = signToHexStr(ALGORITHMS_MD5, sourceStr);
? ? ? ? String sourceStr2 = md5Str1 + key;
? ? ? ? return signToHexStr(ALGORITHMS_MD5, sourceStr2);
? ? }

? ? public static String toDecryptParam(String sourceStr, String password){
? ? ? ? try {
? ? ? ? ? ? byte[] sourceByte = parseHexStr2Byte(sourceStr);
? ? ? ? ? ? byte[] bytes = decrypt(sourceByte, password);
? ? ? ? ? ? return new String(bytes,CHARSET);
? ? ? ? }catch (Exception e){
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return "";
? ? }

? ? public static String toEncryptResult(Object sourceStr, String password){
? ? ? ? String parameterJson = JSONObject.toJSONString(sourceStr);
? ? ? ? byte[] encode = encrypt(parameterJson, password);
? ? ? ? return parseByte2HexStr(encode);
? ? }

? ? public static String encryptAES(String content, String password) {
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
? ? ? ? ? ? byte[] byteContent = content.getBytes("utf-8");
? ? ? ? ? ? cipher.init(1, getSecretKey(password));
? ? ? ? ? ? byte[] result = cipher.doFinal(byteContent);
? ? ? ? ? ? return Base64.encodeBase64String(result);
? ? ? ? } catch (Exception var5) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }

? ? public static String decryptAES(String content, String password) {
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
? ? ? ? ? ? cipher.init(2, getSecretKey(password));
? ? ? ? ? ? byte[] result = cipher.doFinal(Base64.decodeBase64(content));
? ? ? ? ? ? return new String(result, "utf-8");
? ? ? ? } catch (Exception var4) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? private static SecretKeySpec getSecretKey(String password) {
? ? ? ? KeyGenerator kg = null;

? ? ? ? try {
? ? ? ? ? ? kg = KeyGenerator.getInstance("AES");
? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
? ? ? ? ? ? random.setSeed(password.getBytes());
? ? ? ? ? ? kg.init(128, random);
? ? ? ? ? ? SecretKey secretKey = kg.generateKey();
? ? ? ? ? ? return new SecretKeySpec(secretKey.getEncoded(), "AES");
? ? ? ? } catch (NoSuchAlgorithmException var4) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
package com.pay.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.security.*;
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.*;

/**
?* RSA算法加密/解密工具類(lèi)
?*/
@Slf4j
public class RSAUtil {
? ? /** 算法名稱(chēng) */
? ? private static final String ALGORITHM = ?"RSA";
? ? /** 默認(rèn)密鑰大小 */
? ? private static final int KEY_SIZE = 1024;
? ? /** 用來(lái)指定保存密鑰對(duì)的文件名和存儲(chǔ)的名稱(chēng) */
? ? private static final String PUBLIC_KEY_NAME = "publicKey";
? ? private static final String PRIVATE_KEY_NAME = "privateKey";
? ? private static final String PUBLIC_FILENAME = "publicKey.properties";
? ? private static final String PRIVATE_FILENAME = "privateKey.properties";
? ? /** 密鑰對(duì)生成器 */
? ? private static?
? ? KeyPairGenerator keyPairGenerator = null;

? ? private static KeyFactory keyFactory = null;
? ? /** 緩存的密鑰對(duì) */
? ? private static KeyPair keyPair = null;
? ? /** Base64 編碼/解碼器 JDK1.8 */
? ? private static Base64.Decoder decoder = Base64.getDecoder();
? ? private static Base64.Encoder encoder = Base64.getEncoder();
? ? /** 初始化密鑰工廠 */
? ? static{
? ? ? ? try {
? ? ? ? ? ? keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
? ? ? ? ? ? keyFactory = KeyFactory.getInstance(ALGORITHM);
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? log.error("RSAUtil[ERROR]:e={}",e);
? ? ? ? }
? ? }
? ? /** 私有構(gòu)造器 */
? ? private RSAUtil(){}

? ? /**
? ? ?* 生成密鑰對(duì)
? ? ?* 將密鑰分別用Base64編碼保存到#publicKey.properties#和#privateKey.properties#文件中
? ? ?* 保存的默認(rèn)名稱(chēng)分別為publicKey和privateKey
? ? ?*/
? ? public static synchronized Map<String, Object> generateKeyPair(){
? ? ? ? try {
? ? ? ? ? ? keyPairGenerator.initialize(KEY_SIZE,new SecureRandom(UUID.randomUUID().toString().replaceAll("-","").getBytes()));
? ? ? ? ? ? keyPair = keyPairGenerator.generateKeyPair();
? ? ? ? } catch (InvalidParameterException e){
? ? ? ? ? ? log.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".",e);
? ? ? ? } catch (NullPointerException e){
? ? ? ? ? ? log.error("RSAUtil#key_pair_gen is null,can not generate KeyPairGenerator instance.",e);
? ? ? ? }
? ? ? ? RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
? ? ? ? RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
? ? ? ? String publicKeyString = encoder.encodeToString(rsaPublicKey.getEncoded());
? ? ? ? String privateKeyString = encoder.encodeToString(rsaPrivateKey.getEncoded());
? ? ? ? storeKey(publicKeyString,PUBLIC_KEY_NAME,PUBLIC_FILENAME);
? ? ? ? storeKey(privateKeyString,PRIVATE_KEY_NAME,PRIVATE_FILENAME);
? ? ? ? Map<String, Object> keyPair = new HashMap<>();
? ? ? ? keyPair.put("public", publicKeyString);
? ? ? ? keyPair.put("private", privateKeyString);
? ? ? ? return keyPair;
? ? }

? ? /**
? ? ?* 將指定的密鑰字符串保存到文件中,如果找不到文件,就創(chuàng)建
? ? ?* @param keyString 密鑰的Base64編碼字符串(值)
? ? ?* @param keyName ?保存在文件中的名稱(chēng)(鍵)
? ? ?* @param fileName 目標(biāo)文件名
? ? ?*/
? ? private static void storeKey(String keyString,String keyName,String fileName){
? ? ? ? Properties properties = new Properties();
? ? ? ? //存放密鑰的絕對(duì)地址
? ? ? ? String path = null;
? ? ? ? try{
? ? ? ? ? ? path = RSAUtil.class.getClassLoader().getResource(fileName).toString();
? ? ? ? ? ? path = path.substring(path.indexOf(":") + 1);
? ? ? ? }catch (NullPointerException e){
? ? ? ? ? ? //如果不存#fileName#就創(chuàng)建
? ? ? ? ? ? log.warn("storeKey()# " + fileName + " is not exist.Begin to create this file.");
? ? ? ? ? ? String classPath = RSAUtil.class.getClassLoader().getResource("").toString();
? ? ? ? ? ? String prefix = classPath.substring(classPath.indexOf(":") + 1);
? ? ? ? ? ? String suffix = fileName;
? ? ? ? ? ? File file = new File(prefix + suffix);
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? file.createNewFile();
? ? ? ? ? ? ? ? path = file.getAbsolutePath();
? ? ? ? ? ? } catch (IOException e1) {
? ? ? ? ? ? ? ? log.error(fileName +" create fail.",e1);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? try(OutputStream out = new FileOutputStream(path)){
? ? ? ? ? ? properties.setProperty(keyName,keyString);
? ? ? ? ? ? properties.store(out,"There is " + keyName);
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? log.error("ModulusAndExponent.properties is not found.",e);
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? log.error("OutputStream output failed.",e);
? ? ? ? }
? ? }

? ? /**
? ? ?* 獲取密鑰字符串
? ? ?* @param keyName 需要獲取的密鑰名
? ? ?* @param fileName 密鑰所在文件
? ? ?* @return Base64編碼的密鑰字符串
? ? ?*/
? ? private static String getKeyString(String keyName,String fileName){
? ? ? ? if (RSAUtil.class.getClassLoader().getResource(fileName) == null){
? ? ? ? ? ? log.warn("getKeyString()# " + fileName + " is not exist.Will run #generateKeyPair()# firstly.");
? ? ? ? ? ? generateKeyPair();
? ? ? ? }
? ? ? ? try(InputStream in = RSAUtil.class.getClassLoader().getResource(fileName).openStream()){
? ? ? ? ? ? Properties properties = new Properties();
? ? ? ? ? ? properties.load(in);
? ? ? ? ? ? return properties.getProperty(keyName);
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? log.error("getKeyString()#" + e.getMessage(),e);
? ? ? ? }
? ? ? ? return ?null;
? ? }

? ? /**
? ? ?* 從文件獲取RSA公鑰
? ? ?* @return RSA公鑰
? ? ?* @throws InvalidKeySpecException
? ? ?*/
? ? public static RSAPublicKey getPublicKey(){
? ? ? ? try {
? ? ? ? ? ? byte[] keyBytes = decoder.decode(getKeyString(PUBLIC_KEY_NAME,PUBLIC_FILENAME));
? ? ? ? ? ? X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
? ? ? ? ? ? return (RSAPublicKey)keyFactory.generatePublic(x509EncodedKeySpec);
? ? ? ? }catch (InvalidKeySpecException e) {
? ? ? ? ? ? log.error("getPublicKey()#" + e.getMessage(),e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? public static RSAPublicKey getPublicKey(String publicKeyString) {
? ? ? ? if(StringUtils.isBlank(publicKeyString)) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? byte[] keyBytes = decoder.decode(publicKeyString);
? ? ? ? ? ? X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
? ? ? ? ? ? return (RSAPublicKey)keyFactory.generatePublic(x509EncodedKeySpec);
? ? ? ? }catch (InvalidKeySpecException e) {
? ? ? ? ? ? log.error("getPublicKey()#" + e.getMessage(),e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* 從文件獲取RSA私鑰
? ? ?* @return RSA私鑰
? ? ?* @throws InvalidKeySpecException
? ? ?*/
? ? public static RSAPrivateKey getPrivateKey(){
? ? ? ? try {
? ? ? ? ? ? byte[] keyBytes = decoder.decode(getKeyString(PRIVATE_KEY_NAME,PRIVATE_FILENAME));
? ? ? ? ? ? PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
? ? ? ? ? ? return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec);
? ? ? ? } catch (InvalidKeySpecException e) {
? ? ? ? ? ? log.error("getPrivateKey()#" + e.getMessage(),e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? public static RSAPrivateKey getPrivateKey(String privateKeyString) {
? ? ? ? if(StringUtils.isBlank(privateKeyString)) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? byte[] keyBytes = decoder.decode(privateKeyString);
? ? ? ? ? ? PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
? ? ? ? ? ? return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec);
? ? ? ? } catch (InvalidKeySpecException e) {
? ? ? ? ? ? log.error("getPrivateKey()#" + e.getMessage(),e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* RSA公鑰加密
? ? ?* @param content 等待加密的數(shù)據(jù)
? ? ?* @param publicKey RSA 公鑰 if null then getPublicKey()
? ? ?* @return 加密后的密文(16進(jìn)制的字符串)
? ? ?*/
? ? public static String encryptByPublic(byte[] content,PublicKey publicKey){
? ? ? ? if (publicKey == null){
? ? ? ? ? ? publicKey = getPublicKey();
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA");
? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE,publicKey);
? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長(zhǎng)度
? ? ? ? ? ? int splitLength = ((RSAPublicKey)publicKey).getModulus().bitLength() / 8 -11;
? ? ? ? ? ? byte[][] arrays = splitBytes(content,splitLength);
? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer();
? ? ? ? ? ? for (byte[] array : arrays){
? ? ? ? ? ? ? ? stringBuffer.append(bytesToHexString(cipher.doFinal(array)));
? ? ? ? ? ? }
? ? ? ? ? ? return stringBuffer.toString();
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e);
? ? ? ? } catch (NoSuchPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e);
? ? ? ? } catch (InvalidKeyException e) {
? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e);
? ? ? ? } catch (BadPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e);
? ? ? ? } catch (IllegalBlockSizeException e) {
? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* RSA私鑰加密
? ? ?* @param content 等待加密的數(shù)據(jù)
? ? ?* @param privateKey RSA 私鑰 if null then getPrivateKey()
? ? ?* @return 加密后的密文(16進(jìn)制的字符串)
? ? ?*/
? ? public static String encryptByPrivate(byte[] content,PrivateKey privateKey){
? ? ? ? if (privateKey == null){
? ? ? ? ? ? privateKey = getPrivateKey();
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA");
? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE,privateKey);
? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長(zhǎng)度
? ? ? ? ? ? int splitLength = ((RSAPrivateKey)privateKey).getModulus().bitLength() / 8 -11;
? ? ? ? ? ? byte[][] arrays = splitBytes(content,splitLength);
? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer();
? ? ? ? ? ? for(byte[] array : arrays){
? ? ? ? ? ? ? ? stringBuffer.append(bytesToHexString(cipher.doFinal(array)));
? ? ? ? ? ? }
? ? ? ? ? ? return stringBuffer.toString();
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e);
? ? ? ? } catch (NoSuchPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e);
? ? ? ? } catch (InvalidKeyException e) {
? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e);
? ? ? ? } catch (BadPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e);
? ? ? ? } catch (IllegalBlockSizeException e) {
? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* RSA私鑰解密
? ? ?* @param content 等待解密的數(shù)據(jù)
? ? ?* @param privateKey RSA 私鑰 if null then getPrivateKey()
? ? ?* @return 解密后的明文
? ? ?*/
? ? public static String decryptByPrivate(String content,PrivateKey privateKey){
? ? ? ? if (privateKey == null){
? ? ? ? ? ? privateKey = getPrivateKey();
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA");
? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE,privateKey);
? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長(zhǎng)度
? ? ? ? ? ? int splitLength = ((RSAPrivateKey)privateKey).getModulus().bitLength() / 8;
? ? ? ? ? ? byte[] contentBytes = hexStringToBytes(content);
? ? ? ? ? ? byte[][] arrays = splitBytes(contentBytes,splitLength);
? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer();
? ? ? ? ? ? String sTemp = null;
? ? ? ? ? ? for (byte[] array : arrays){
? ? ? ? ? ? ? ? stringBuffer.append(new String(cipher.doFinal(array)));
? ? ? ? ? ? }
? ? ? ? ? ? return stringBuffer.toString();
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e);
? ? ? ? } catch (NoSuchPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e);
? ? ? ? } catch (InvalidKeyException e) {
? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e);
? ? ? ? } catch (BadPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e);
? ? ? ? } catch (IllegalBlockSizeException e) {
? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* RSA公鑰解密
? ? ?* @param content 等待解密的數(shù)據(jù)
? ? ?* @param publicKey RSA 公鑰 if null then getPublicKey()
? ? ?* @return 解密后的明文
? ? ?*/
? ? public static String decryptByPublic(String content,PublicKey publicKey){
? ? ? ? if (publicKey == null){
? ? ? ? ? ? publicKey = getPublicKey();
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA");
? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE,publicKey);
? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長(zhǎng)度
? ? ? ? ? ? int splitLength = ((RSAPublicKey)publicKey).getModulus().bitLength() / 8;
? ? ? ? ? ? byte[] contentBytes = hexStringToBytes(content);
? ? ? ? ? ? byte[][] arrays = splitBytes(contentBytes,splitLength);
? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer();
? ? ? ? ? ? String sTemp = null;
? ? ? ? ? ? for (byte[] array : arrays){
? ? ? ? ? ? ? ? stringBuffer.append(new String(cipher.doFinal(array)));
? ? ? ? ? ? }
? ? ? ? ? ? return stringBuffer.toString();
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e);
? ? ? ? } catch (NoSuchPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e);
? ? ? ? } catch (InvalidKeyException e) {
? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e);
? ? ? ? } catch (BadPaddingException e) {
? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e);
? ? ? ? } catch (IllegalBlockSizeException e) {
? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e);
? ? ? ? }
? ? ? ? return null;
? ? }

? ? /**
? ? ?* 根據(jù)限定的每組字節(jié)長(zhǎng)度,將字節(jié)數(shù)組分組
? ? ?* @param bytes 等待分組的字節(jié)組
? ? ?* @param splitLength 每組長(zhǎng)度
? ? ?* @return 分組后的字節(jié)組
? ? ?*/
? ? public static byte[][] splitBytes(byte[] bytes,int splitLength){
? ? ? ? //bytes與splitLength的余數(shù)
? ? ? ? int remainder = bytes.length % splitLength;
? ? ? ? //數(shù)據(jù)拆分后的組數(shù),余數(shù)不為0時(shí)加1
? ? ? ? int quotient = remainder != 0 ? bytes.length / splitLength + 1:bytes.length / splitLength;
? ? ? ? byte[][] arrays = new byte[quotient][];
? ? ? ? byte[] array = null;
? ? ? ? for (int i =0;i<quotient;i++){
? ? ? ? ? ? //如果是最后一組(quotient-1),同時(shí)余數(shù)不等于0,就將最后一組設(shè)置為remainder的長(zhǎng)度
? ? ? ? ? ? if (i == quotient -1 && remainder != 0){
? ? ? ? ? ? ? ? array = new byte[remainder];
? ? ? ? ? ? ? ? System.arraycopy(bytes,i * splitLength,array,0,remainder);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? array = new byte[splitLength];
? ? ? ? ? ? ? ? System.arraycopy(bytes,i*splitLength,array,0,splitLength);
? ? ? ? ? ? }
? ? ? ? ? ? arrays[i] = array;
? ? ? ? }
? ? ? ? return arrays;
? ? }

? ? /**
? ? ?* 將字節(jié)數(shù)組轉(zhuǎn)換成16進(jìn)制字符串
? ? ?* @param bytes 即將轉(zhuǎn)換的數(shù)據(jù)
? ? ?* @return 16進(jìn)制字符串
? ? ?*/
? ? public static String bytesToHexString(byte[] bytes){
? ? ? ? StringBuffer sb = new StringBuffer(bytes.length);
? ? ? ? String temp = null;
? ? ? ? for (int i = 0;i< bytes.length;i++){
? ? ? ? ? ? temp = Integer.toHexString(0xFF & bytes[i]);
? ? ? ? ? ? if(temp.length() <2){
? ? ? ? ? ? ? ? sb.append(0);
? ? ? ? ? ? }
? ? ? ? ? ? sb.append(temp);
? ? ? ? }
? ? ? ? return sb.toString();
? ? }

? ? /**
? ? ?* 將16進(jìn)制字符串轉(zhuǎn)換成字節(jié)數(shù)組
? ? ?* @param hex 16進(jìn)制字符串
? ? ?* @return byte[]
? ? ?*/
? ? public static byte[] hexStringToBytes(String hex){
? ? ? ? int len = (hex.length() / 2);
? ? ? ? hex = hex.toUpperCase();
? ? ? ? byte[] result = new byte[len];
? ? ? ? char[] chars = hex.toCharArray();
? ? ? ? for (int i= 0;i<len;i++){
? ? ? ? ? ? int pos = i * 2;
? ? ? ? ? ? result[i] = (byte)(toByte(chars[pos]) << 4 | toByte(chars[pos + 1]));
? ? ? ? }
? ? ? ? return result;
? ? }

? ? /**
? ? ?* 將char轉(zhuǎn)換為byte
? ? ?* @param c char
? ? ?* @return byte
? ? ?*/
? ? private static byte toByte(char c){
? ? ? ? return (byte)"0123456789ABCDEF".indexOf(c);
? ? }

身份檢驗(yàn)

除了參數(shù)加密之外,我們還可以做一個(gè)簡(jiǎn)單的身份校驗(yàn)。這里就需要使用到Spring的攔截器了。

可以在header中放一個(gè)身份token,攔截器里面校驗(yàn)

具體實(shí)現(xiàn):

一個(gè)攔截器 TokenInterceptor.java 和配置類(lèi) WebConfig.java

package com.pay.filter;

import com.alibaba.fastjson.JSONObject;
import com.pay.common.ErrorCode;
import com.pay.common.GlobalEnums;
import com.pay.entity.SourceConfig;
import com.pay.service.SourceConfigService;
import com.pay.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

? ? @Autowired
? ? private SourceConfigService sourceConfigService;

? ? @Override
? ? public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
? ? ? ? String token = httpServletRequest.getHeader("token");
? ? ? ? httpServletResponse.setContentType("text/html;charset=utf-8");
? ? ? ? httpServletResponse.setCharacterEncoding("utf-8");
? ? ? ? ServletOutputStream outputStream = httpServletResponse.getOutputStream();
? ? ? ? JSONObject jsonObject =new JSONObject();
? ? ? ? if(StringUtils.isBlank(token)) {
? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode());
? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage());
? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes());
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? SourceConfig sourceConfig = sourceConfigService.selectBySource(token);
? ? ? ? if(sourceConfig == null) {
? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode());
? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage());
? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes());
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? if(sourceConfig.getStatus().equals(GlobalEnums.EnableEnum.FALSE.getEnable())) {
? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode());
? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage());
? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes());
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? return true;
? ? }

? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
? ? }

? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)
? ? ? ? ? ? throws Exception {
? ? ? ? RequestTokenHolder.remove();
? ? }

}
package com.pay.config;
import com.pay.filter.TokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class WebConfig implements WebMvcConfigurer {

? ? @Override
? ? public void addViewControllers(ViewControllerRegistry registry) {

? ? }

? ? @Resource
? ? private TokenInterceptor tokenInterceptor;

? ? /**
? ? ?* 這個(gè)方法用來(lái)注冊(cè)攔截器,我們自己寫(xiě)好的攔截器需要通過(guò)這里添加注冊(cè)才能生效
? ? ?*
? ? ?* @param registry ""
? ? ?*/
? ? @Override
? ? public void addInterceptors(InterceptorRegistry registry) {
? ? ? ? registry.addInterceptor(tokenInterceptor)
? ? ? ? ? ? ? ? .addPathPatterns("/**")
? ? ? ? ? ? ? ? .excludePathPatterns(
? ? ? ? ? ? ? ? ? ? ? ? "/pay/notify/**"http://登錄接口
? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? // 過(guò)濾swagger
? ? ? ? ? ? ? ? .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
? ? }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java?Collection集合接口的介紹和使用詳解

    java?Collection集合接口的介紹和使用詳解

    這篇文章主要為大家介紹了java?Collection集合接口的介紹和使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Maven提示jdk版本不正確的問(wèn)題

    Maven提示jdk版本不正確的問(wèn)題

    這篇文章主要介紹了Maven提示jdk版本不正確的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java集合和IO流實(shí)現(xiàn)水果攤項(xiàng)目

    Java集合和IO流實(shí)現(xiàn)水果攤項(xiàng)目

    最近閑來(lái)無(wú)事,使用java基礎(chǔ)知識(shí)集合和IO流做了一個(gè)簡(jiǎn)單的小項(xiàng)目,水果攤項(xiàng)目,用到GUI和Mysql數(shù)據(jù)庫(kù)搭建,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-06-06
  • Java編程中使用JDBC API連接數(shù)據(jù)庫(kù)和創(chuàng)建程序的方法

    Java編程中使用JDBC API連接數(shù)據(jù)庫(kù)和創(chuàng)建程序的方法

    這篇文章主要介紹了Java編程中使用JDBC API連接數(shù)據(jù)庫(kù)和創(chuàng)建程序的基本教程,JDBC是一種用于執(zhí)行SQL語(yǔ)句的Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪問(wèn)需要的朋友可以參考下
    2015-12-12
  • java實(shí)現(xiàn)快速打字游戲

    java實(shí)現(xiàn)快速打字游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)快速打字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 詳解java中面向?qū)ο笤O(shè)計(jì)模式類(lèi)與類(lèi)的關(guān)系

    詳解java中面向?qū)ο笤O(shè)計(jì)模式類(lèi)與類(lèi)的關(guān)系

    這篇文章主要介紹了java面向?qū)ο笤O(shè)計(jì)模式中類(lèi)與類(lèi)之間的關(guān)系,下面小編和大家一起來(lái)學(xué)習(xí)一下吧
    2019-05-05
  • 使用Spring?Boot+gRPC構(gòu)建微服務(wù)并部署的案例詳解

    使用Spring?Boot+gRPC構(gòu)建微服務(wù)并部署的案例詳解

    這篇文章主要介紹了使用Spring?Boot+gRPC構(gòu)建微服務(wù)并部署,Spring Cloud僅僅是一個(gè)開(kāi)發(fā)框架,沒(méi)有實(shí)現(xiàn)微服務(wù)所必須的服務(wù)調(diào)度、資源分配等功能,這些需求要借助Kubernetes等平臺(tái)來(lái)完成,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-06-06
  • 深入講解基于JDK的動(dòng)態(tài)代理機(jī)制

    深入講解基于JDK的動(dòng)態(tài)代理機(jī)制

    眾所周知相比于靜態(tài)代理,動(dòng)態(tài)代理避免了開(kāi)發(fā)人員編寫(xiě)各個(gè)繁鎖的靜態(tài)代理類(lèi),下面這篇文章主要給大家介紹了關(guān)于基于JDK的動(dòng)態(tài)代理機(jī)制的相關(guān)資料,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • 基于SpringBoot制作一個(gè)PDF切圖小工具

    基于SpringBoot制作一個(gè)PDF切圖小工具

    這篇文章主要為大家詳細(xì)介紹了如何基于SpringBoot制作一個(gè)PDF切圖小工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Maven打jar包的三種方式(小結(jié))

    Maven打jar包的三種方式(小結(jié))

    這篇文章主要介紹了Maven打jar包的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論