Java如何实现http接口参数和返回值加密

这篇文章主要介绍了Java如何实现http接口参数和返回值加密问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

参数和返回值得加密目的

为了保证接口不被人拦截下来恶意请求,保证程序的稳定性,我们可以使用接口加密的方法来保证参数和返回值的保密性。

具体实现方式

因为本人是写Java 的,所以这里就直接以Java代码为例。思想都是一样的,只是不同的语言都不同的实现方式。

大致思路

  • 我们的参数和返回值只需要定义两个参数:ak,ct,ak存放堆成加密的秘钥,ct存放加密之后的请求内容。
  • 加密方式用到AES对称加密和RSA非对称加密,将请求参数使用AES加密,HTTP的POST请求和GET请求都可以将实际请求参数的格式定义成同一种格式(比如:JSON格式),便于后台处理。AES加密使用的秘钥用RSA加密。这样我们就不需要操心参数加密的秘钥是什么了,双方都可以随时更换。
  • 使用过滤器获取到请求的加密内容后,通过RSA解密将参数加密的秘钥解析出来,然后再通过解析出来的秘钥通过AES解密去获取实际的请求内容。

注意:不同的请求方式获取参数的方式不同,需要根据不同的请求方式去做不同的解析

代码实现

1. 首先需要一个过滤器,因为我们要拦截请求参数,和加密返回的数据。

因为并不是所有的接口都需要加密,过滤器不能想Spring拦截器那样直接配置拦截和不拦截的类,所以定义了一个ALLOWED_PATHS 集合,用于过滤不需要加解密的请求。然后根据不同的请求方式去解析不同的请求内容,我这里只处理了get请求和post请求这两种常用的请求方式。

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; /**  * 请求信息加解密  */ @Log4j2 @Component @WebFilter(filterName = "EncryptionFilter", urlPatterns = {"/*"}) public class EncryptionFilter implements Filter {     private static final Set 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请求");             } else { //其余默认get请求                 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(); //获取接口返回内容             //加密处理返回             response.getOutputStream().write(HttpEncryptUtil.serverEncrypt(resp).getBytes(StandardCharsets.UTF_8));         }     } }

2. 对于POST请求,定义一个解析request中参数的类 MyHttpServletRequestWrapper继承HttpServletRequestWrapper ,去解析请求参数。

具体实现方式如下:

readBody:实际解析请求参数

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)) {             //解密请求参数             return HttpEncryptUtil.serverDecrypt(param);         }         return param;     } }

3. 对于get请求,定义一个参数类ParameterRequestWrapper,继承HttpServletRequestWrapper 去解析URL上的参数

具体方式如下:

重载构造方法获取加密之后的参数,去解析出来

ParameterRequestWrapper(HttpServletRequest request)

重写getParameter和setParameter等获取参数和设置参数的方法

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 params = new HashMap();     @SuppressWarnings("unchecked")     public ParameterRequestWrapper(HttpServletRequest request) {         // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似         super(request);         //将参数表,赋予给当前的Map以便于持有request中的参数         //解析         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));     }     //重载一个构造方法     public ParameterRequestWrapper(HttpServletRequest request , Map extendParams) {         this(request);         addAllParameters(extendParams);//这里将扩展参数写入参数表     }     @Override     public String getParameter(String name) {//重写getParameter,代表参数从当前类中的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(MapotherParams) {//增加多个参数         for(Map.Entryentry : otherParams.entrySet()) {             addParameter(entry.getKey() , entry.getValue());         }     }     public void addParameter(String name , Object value) {//增加参数         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)});             }         }     } }

注意:为了便于区分我才把获取post请求内容和get请求内容的类写成了两个,其实可以尝试着去将两个解析类合成一个

4. 加解密工具类 HttpEncryptUtil ,和两个网上百度的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 {     //解密请求内容     public static String serverDecrypt(String content) {         JSONObject result = JSONObject.parseObject(content);         String encryptAesKeyStr = result.getString("ak");         String encryptContent = result.getString("ct");         //使用私钥解密 获取解密内容的AES密钥 //        encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解码         PrivateKey privateKey = RSAUtil.getPrivateKey(HTTP_PRIVATE_KEY);         String aesKey = RSAUtil.decryptByPrivate(decodeBase64String(encryptAesKeyStr), privateKey);         //使用解密出来的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");         //使用私钥解密 获取解密内容的AES密钥 //        encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解码         RSAPublicKey publicKey = RSAUtil.getPublicKey(HTTP_PUBLIC_KEY);         String aesKey = RSAUtil.decryptByPublic(decodeBase64String(encryptAesKeyStr), publicKey);         //使用解密出来的key解密content:使用AES         return AESUtil.decryptAES(decodeBase64String(encryptContent), aesKey);     }     //加密返回内容     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  需要加密的内容      * @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);// 创建密码器             byte[] byteContent = content.getBytes(CHARSET);             cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化             return cipher.doFinal(byteContent); // 加密         } catch (Exception e) {             e.printStackTrace();         }         return null;     }     /**      * 解密      *      * @param content  待解密内容      * @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);// 创建密码器             cipher.init(Cipher.DECRYPT_MODE, key);// 初始化             return cipher.doFinal(content); // 加密         } catch (Exception e) {             e.printStackTrace();         }         return null;     }     /**      * 将二进制转换成16进制      *      * @param buf      * @return      */     public static String parseByte2HexStr(byte buf[]) {         StringBuffer sb = new StringBuffer();         for (int i = 0; i 
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算法加密/解密工具类  */ @Slf4j public class RSAUtil {     /** 算法名称 */     private static final String ALGORITHM =  "RSA";     /** 默认密钥大小 */     private static final int KEY_SIZE = 1024;     /** 用来指定保存密钥对的文件名和存储的名称 */     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";     /** 密钥对生成器 */     private static      KeyPairGenerator keyPairGenerator = null;     private static KeyFactory keyFactory = null;     /** 缓存的密钥对 */     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);         }     }     /** 私有构造器 */     private RSAUtil(){}     /**      * 生成密钥对      * 将密钥分别用Base64编码保存到#publicKey.properties#和#privateKey.properties#文件中      * 保存的默认名称分别为publicKey和privateKey      */     public static synchronized Map 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 keyPair = new HashMap<>();         keyPair.put("public", publicKeyString);         keyPair.put("private", privateKeyString);         return keyPair;     }     /**      * 将指定的密钥字符串保存到文件中,如果找不到文件,就创建      * @param keyString 密钥的Base64编码字符串(值)      * @param keyName  保存在文件中的名称(键)      * @param fileName 目标文件名      */     private static void storeKey(String keyString,String keyName,String fileName){         Properties properties = new Properties();         //存放密钥的绝对地址         String path = null;         try{             path = RSAUtil.class.getClassLoader().getResource(fileName).toString();             path = path.substring(path.indexOf(":") + 1);         }catch (NullPointerException e){             //如果不存#fileName#就创建             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 等待加密的数据      * @param publicKey RSA 公钥 if null then getPublicKey()      * @return 加密后的密文(16进制的字符串)      */     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);             //该密钥能够加密的最大字节长度             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 等待加密的数据      * @param privateKey RSA 私钥 if null then getPrivateKey()      * @return 加密后的密文(16进制的字符串)      */     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);             //该密钥能够加密的最大字节长度             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 等待解密的数据      * @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);             //该密钥能够加密的最大字节长度             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 等待解密的数据      * @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);             //该密钥能够加密的最大字节长度             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;     }     /**      * 根据限定的每组字节长度,将字节数组分组      * @param bytes 等待分组的字节组      * @param splitLength 每组长度      * @return 分组后的字节组      */     public static byte[][] splitBytes(byte[] bytes,int splitLength){         //bytes与splitLength的余数         int remainder = bytes.length % splitLength;         //数据拆分后的组数,余数不为0时加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

身份检验

除了参数加密之外,我们还可以做一个简单的身份校验。这里就需要使用到Spring的拦截器了。

可以在header中放一个身份token,拦截器里面校验

具体实现:

一个拦截器 TokenInterceptor.java 和配置类 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;     /**      * 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效      *      * @param registry ""      */     @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(tokenInterceptor)                 .addPathPatterns("/**")                 .excludePathPatterns(                         "/pay/notify/**"//登录接口                 )                 // 过滤swagger                 .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");     } }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持0133技术站。

以上就是Java如何实现http接口参数和返回值加密的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java