如何撰写一份关于网站开发中软件技术实验的详细报告?

摘要:网站开发需要的软件,网站开发技术实验报告,网络科技有限公司 网站建设,一个完整的网站制作需要哪些部分组成目录安全性功能介绍实现流程开放平台依赖代码AES加解密工具类PlatformConfigRequestUtilsPlatformServ
网站开发需要的软件,网站开发技术实验报告,网络科技有限公司 网站建设,一个完整的网站制作需要哪些部分组成目录安全性功能介绍实现流程开放平台依赖代码AES加解密工具类PlatformConfigRequestUtilsPlatformServiceCommonCodeZuulFilterHelperServerResponsePlatformContactRsaSignatureRsaUtilsStreamUtil开放平台-解密过滤器开放平台-加密过滤器调用方代码公共代码Get-DemoPost-Demo… 目录安全性功能介绍实现流程开放平台依赖代码AES加解密工具类PlatformConfigRequestUtilsPlatformServiceCommonCodeZuulFilterHelperServerResponsePlatformContactRsaSignatureRsaUtilsStreamUtil开放平台-解密过滤器开放平台-加密过滤器调用方代码公共代码Get-DemoPost-Demo安全性 既然你能看到我这篇文章就代表你目前或者是你想做或者已经做过接口加解密的功能做加密的目的一定是为了安全这是毋庸置疑的。 功能介绍 因为我们要开放我们自己的接口给接入方所以一些加密和限流是免不了要做的可以理解为我们要做一个开放平台。 既然要做开放平台肯定会同时把同一个接口开放给多个接入方每个接入方的身份标识私钥、签名都是不一样的。 目前我采用了2种加密方式一种非对称加密一种是对称加密非对称加密用于签名对称加密用于请求体加密和解密非对称加密采用RSA对称加密采用AES。 目前接入方的配置都是放置在redis中但是表已经有设计没放上来有需求的下方评论后期可以改造成配置写入表后更新到redis保证表和缓存一致性。 实现流程 开放平台采用zuul过滤器来实现以下步骤 校验接入方的签名是否正确对请求体进行解密对开放平台返回的响应内容进行加密校验接入方的IP地址是否在白名单内 过滤器依赖工具类较多不过我都放上来了可以实现从0到1主要代码就是2个过滤器 开放平台依赖代码 AES加解密工具类 package com.lwh.utils.encrypt;import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom;import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;/*** AES加解密工具类**/ public class AesUtil {/*** 加密* 1.构造密钥生成器* 2.根据ecnodeRules规则初始化密钥生成器* 3.产生密钥* 4.创建和初始化密码器* 5.内容加密* 6.返回字符串*/public static String aesEncode(String content,String pwd) {try {//1.构造密钥生成器指定为AES算法,不区分大小写KeyGenerator keyGenerator KeyGenerator.getInstance(AES);//2.根据ecnodeRules规则初始化密钥生成器//生成一个128位的随机源,根据传入的字节数组SecureRandom random SecureRandom.getInstance(SHA1PRNG);random.setSeed(pwd.getBytes());keyGenerator.init(128, random);//3.产生原始对称密钥SecretKey originalKey keyGenerator.generateKey();//4.获得原始对称密钥的字节数组byte[] raw originalKey.getEncoded();//5.根据字节数组生成AES密钥SecretKey key new SecretKeySpec(raw, AES);//6.根据指定算法AES自成密码器Cipher cipher Cipher.getInstance(AES);//7.初始化密码器第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作第二个参数为使用的KEYcipher.init(Cipher.ENCRYPT_MODE, key);//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码byte[] byteEncode content.getBytes(StandardCharsets.UTF_8);//9.根据密码器的初始化方式--加密将数据加密byte[] byteAES cipher.doFinal(byteEncode);//10.将加密后的数据转换为字符串//这里用Base64Encoder中会找不到包//解决办法//在项目的Build path中先移除JRE System Library再添加库JRE System Library重新编译后就一切正常了。//11.将字符串返回return new BASE64Encoder().encode(byteAES);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}//如果有错就返加nulllreturn null;}/*** 解密* 解密过程* 1.同加密1-4步* 2.将加密后的字符串反纺成byte[]数组* 3.将加密内容解密*/public static String aesDecode(String content,String pwd) {try {//1.构造密钥生成器指定为AES算法,不区分大小写KeyGenerator keygen KeyGenerator.getInstance(AES);//2.根据ecnodeRules规则初始化密钥生成器//生成一个128位的随机源,根据传入的字节数组SecureRandom random SecureRandom.getInstance(SHA1PRNG);random.setSeed(pwd.getBytes());keygen.init(128, random);//3.产生原始对称密钥SecretKey originalKey keygen.generateKey();//4.获得原始对称密钥的字节数组byte[] raw originalKey.getEncoded();//5.根据字节数组生成AES密钥SecretKey key new SecretKeySpec(raw, AES);//6.根据指定算法AES自成密码器Cipher cipher Cipher.getInstance(AES);//7.初始化密码器第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作第二个参数为使用的KEYcipher.init(Cipher.DECRYPT_MODE, key);//8.将加密并编码后的内容解码成字节数组byte[] byteContent new BASE64Decoder().decodeBuffer(content);/** 解密*/byte[] byteDecode cipher.doFinal(byteContent);return new String(byteDecode, StandardCharsets.UTF_8);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {throw new RuntimeException(兄弟配置文件中的密码需要使用AES加密请使用com.zheng.common.util.AESUtil工具类修改这些值);//e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}//如果有错就返加nulllreturn null;}} PlatformConfig package com.lwh.model;import java.io.Serializable;import lombok.Data;Data public class PlatformConfig implements Serializable {private static final long serialVersionUID 4705311536029751175L;/*** 白名单*/private String whiteIpList;/*** 平台提供ras公钥*/private String platformUploadPubRsa;/*** aes密码*/private String aesKey; } RequestUtils /*** 从请求中获取body数据** param request* return* throws Exception*/public static String getBodyString(HttpServletRequest request) throws Exception {request.setCharacterEncoding(UTF-8);String body null;StringBuilder stringBuilder new StringBuilder();BufferedReader bufferedReader null;try {InputStream inputStream request.getInputStream();if (inputStream ! null) {bufferedReader new BufferedReader(new InputStreamReader(inputStream, UTF-8));char[] charBuffer new char[128];int bytesRead -1;while ((bytesRead bufferedReader.read(charBuffer)) 0) {stringBuilder.append(charBuffer, 0, bytesRead);}}} catch (IOException ex) {throw ex;} finally {if (bufferedReader ! null) {try {bufferedReader.close();} catch (IOException ex) {throw ex;}}}body stringBuilder.toString();return body;}/*** 获取ip工具类除了getRemoteAddr其他ip均可伪造** param request* return*/public static String getIpAddr(HttpServletRequest request) {String ip request.getHeader(Cdn-Src-Ip); // 网宿cdn的真实ipif (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ip)) {ip request.getHeader(HTTP_CLIENT_IP); // 蓝讯cdn的真实ip}if (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ip)) {ip request.getHeader(X-Forwarded-For); // 获取代理ip}if (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ip)) {ip request.getHeader(Proxy-Client-IP); // 获取代理ip}if (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ip)) {ip request.getHeader(WL-Proxy-Client-IP); // 获取代理ip}if (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ip)) {ip request.getRemoteAddr(); // 获取真实ip}return ip;}/*** 获取head key* param request* param key* return*/public static String getHeadParams(HttpServletRequest request,String key){String token request.getHeader(key);if (token null) {token request.getParameter(key);if(token null){return null;}}return token.trim();}PlatformService package com.lwh.service;import com.lwh.constant.RedisKeyConstant; import com.lwh.model.PlatformConfig; import com.lwh.utils.JsonUtil;import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service;import lombok.extern.slf4j.Slf4j;Service Slf4j public class PlatformService {AutowiredStringRedisTemplate redisTemplate;/*** 根据appId 获取平台信息* return*/public PlatformConfig getPlatformByAppId(String appId){String redisKey RedisKeyConstant.Platform.PLATFORM_CONFIGappId;String json redisTemplate.opsForValue().get(redisKey);if(StringUtils.isBlank(json)){return null;}else{return JsonUtil.string2Obj(json,PlatformConfig.class);}} }package com.lwh.constant;public interface RedisKeyConstant {interface Platform {/*** 平台配置恒久缓存*/String PLATFORM_CONFIG PLATFORM_CONFIG_;}} CommonCode package com.lwh.response;public enum CommonCode implements ResultCode{//公共部分SUCCESS(200,成功),CODE_00001(1001,系统繁忙请稍后重试),CODE_00002(1002,参数异常),CODE_00404(1003,请求不存在),CODE_00405(1004,验签失败);CommonCode(Integer code, String msg) {this.code code;this.msg msg;}private Integer code;private String msg;Overridepublic Integer code() {return code;}Overridepublic String msg() {return msg;} } ZuulFilterHelper package com.lwh.filter;import com.lwh.response.ServerResponse; import com.lwh.utils.JsonUtil; import com.netflix.zuul.context.RequestContext;import javax.servlet.http.HttpServletResponse;import lombok.extern.slf4j.Slf4j;/** * 过滤器访问帮助类 */ Slf4j public class ZuulFilterHelper {/*** 拒绝访问*/public static void accessDenied(ServerResponse serverResponse) {log.error(网关拒绝访问:{}, JsonUtil.obj2StringPretty(serverResponse));RequestContext requestContext RequestContext.getCurrentContext();//得到responseHttpServletResponse response requestContext.getResponse();//拒绝访问requestContext.setSendZuulResponse(false);//设置响应代码requestContext.setResponseStatusCode(200);//转成jsonString jsonString JsonUtil.objectToJson(serverResponse);requestContext.setResponseBody(jsonString);//转成json设置contentTyperesponse.setContentType(application/json;charsetutf-8);} } ServerResponse package com.lwh.response;import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude;import java.io.Serializable;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty;JsonInclude(JsonInclude.Include.NON_NULL) ApiModel(value 服务响应,description 通用服务响应结果) public class ServerResponseT,Serializable {/*** 成功or失败*/ApiModelProperty(value 结果,example true)private boolean result;/*** 状态*/ApiModelProperty(value 状态码成功:00000,example 00000)private Integer code;/*** 描述*/ApiModelProperty(value 描述错误描述,example SUCCESS)private String message;private T data;public ServerResponse() {}public ServerResponse(boolean result, Integer code, T data) {this.result result;this.code code;this.data data;}public ServerResponse(Integer code, String message, T data) {this.code code;this.message message;this.data data;}public ServerResponse(boolean result, Integer code, String message, T data) {this.result result;this.code code;this.message message;this.data data;}public ServerResponse(boolean result, Integer code, String message) {this.result result;this.code code;this.message message;}/*** 使之不在json序列化结果当中* return*/JsonIgnorepublic boolean isSuccess() {return result;}public boolean isResult() {return result;}public Integer getCode() {return code;}public T getData() {return data;}public String getMessage() {return message;}public static T ServerResponseT createBySuccess() {return new ServerResponseT(true, CommonCode.SUCCESS.code(), CommonCode.SUCCESS.msg());}public static T ServerResponseT createBySuccess(T data) {return new ServerResponseT(true, CommonCode.SUCCESS.code(), CommonCode.SUCCESS.msg(), data);}public static T ServerResponseT createBySuccess(String message, T data) {return new ServerResponseT(true, CommonCode.SUCCESS.code(), message, data);}public static T ServerResponseT createByError() {return new ServerResponseT(false, CommonCode.CODE_00001.code(), CommonCode.CODE_00001.msg());}public static T ServerResponseT createByErrorMessage(String message) {return new ServerResponseT(false, CommonCode.CODE_00001.code(), message);}public static T ServerResponseT createByErrorCodeMessage(Integer code, String message) {return new ServerResponseT(false, code, message);}public static T ServerResponseT createErrorByCode(ResultCode statusCode) {return new ServerResponseT(false, statusCode.code(), statusCode.msg());}public void setCode(Integer code) {this.code code;}public void setData(T data) {this.data data;}public void setMessage(String message) {this.message message;}Overridepublic String toString() {return ServerResponse{ result result , code code \ , data data , message message \ };} } PlatformContact package com.lwh.common;public interface PlatformContact {String APP_IDappId;String VERSIONversion;String TIMESTAMPtimestamp;String SIGNsign; } RsaSignature package com.lwh.utils.encrypt;import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.InvalidKeySpecException; import java.util.ArrayList; import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.Map;import org.apache.commons.lang3.StringUtils;/*** RSA、RSA2算法签名*/ public class RsaSignature {private static final String RSA RSA;private static final String RSA2 RSA2;/*** 获取签名内容** param sortedParams* return*/public static String getSignContent(MapString, String sortedParams) {StringBuilder content new StringBuilder();ListString keys new ArrayList(sortedParams.keySet());Collections.sort(keys);int index 0;for (String key : keys) {String value sortedParams.get(key);if ((StringUtils.isNotEmpty(key) StringUtils.isNotEmpty(value))) {content.append(index 0 ? : ).append(key).append().append(value);index;}}return content.toString();}/*** 根据类型签名** param content 签名内容* param privateKey 私钥* param signType 签名类型RSA、RSA2* return* throws RuntimeException*/public static String rsaSign(String content, String privateKey, String signType) throws RuntimeException {if (RSA.equals(signType)) {return rsaSign(content, privateKey);} else if (RSA2.equals(signType)) {return rsa256Sign(content, privateKey);} else {throw new RuntimeException(Sign Type is Not Support : signType signType);}}/*** rsa签名** param content 签名内容* param privateKey 私钥* return* throws RuntimeException*/public static String rsaSign(String content, String privateKey) throws RuntimeException {try {PrivateKey priKey RsaUtils.getPrivateKey(privateKey);Signature signature Signature.getInstance(SHA1WithRSA);signature.initSign(priKey);signature.update(content.getBytes(StandardCharsets.UTF_8));byte[] signed signature.sign();return new String(Base64.getEncoder().encode(signed));} catch (InvalidKeySpecException var6) {throw new RuntimeException(RSA私钥格式不正确请检查是否正确配置了PKCS8格式的私钥, var6);} catch (Exception var7) {throw new RuntimeException(RSAContent content ; charset UTF-8, var7);}}/*** rsa签名** param params 参数map* param privateKey 私钥* return* throws RuntimeException*/public static String rsaSign(MapString, String params, String privateKey) throws RuntimeException {String signContent getSignContent(params);return rsaSign(signContent, privateKey);}/*** rsa2签名** param content 签名内容* param privateKey 私钥* return* throws RuntimeException*/public static String rsa256Sign(String content, String privateKey) throws RuntimeException {try {PrivateKey priKey RsaUtils.getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes()));Signature signature Signature.getInstance(SHA256WithRSA);signature.initSign(priKey);signature.update(content.getBytes(StandardCharsets.UTF_8));byte[] signed signature.sign();return new String(Base64.getEncoder().encode(signed));} catch (Exception var6) {throw new RuntimeException(RSAContent content ; charset UTF-8, var6);}}/*** rsa2签名** param params 参数map* param privateKey 私钥* return* throws RuntimeException*/public static String rsa256Sign(MapString, String params, String privateKey) throws RuntimeException {String signContent getSignContent(params);return rsa256Sign(signContent, privateKey);}/*** 获取签名内容字符串** param params 参数map* return*/public static String getSignCheckContent(MapString, String params) {if (params null) {return null;} else {params.remove(sign);StringBuilder content new StringBuilder();ListString keys new ArrayList(params.keySet());Collections.sort(keys);for (int i 0; i keys.size(); i) {String key keys.get(i);String value params.get(key);content.append(i 0 ? : ).append(key).append().append(value);}return content.toString();}}/*** rsa验签** param content 验签内容* param publicKey 公钥* param sign 签名* param signType 签名类型RSA/RSA2* return* throws RuntimeException*/public static boolean rsaCheck(String content, String publicKey, String sign, String signType) throws RuntimeException {if (RSA.equals(signType)) {return rsaCheck(content, sign, publicKey);} else if (RSA2.equals(signType)) {return rsa256Check(content, sign, publicKey);} else {throw new RuntimeException(Sign Type is Not Support : signType signType);}}/*** rsa验签** param params 参数map* param publicKey 公钥* return* throws RuntimeException*/public static boolean rsaCheck(MapString, String params, String publicKey) throws RuntimeException {String sign params.get(sign);String content getSignCheckContent(params);return rsaCheckContent(content, sign, publicKey, UTF-8);}/*** rsa2验签** param params* param publicKey* return* throws RuntimeException*/public static boolean rsa256Check(MapString, String params, String publicKey) throws RuntimeException {String sign params.get(sign);String content getSignCheckContent(params);return rsaCheckContent(content, sign, publicKey, UTF-8);}/*** rsa验签** param content* param sign* param publicKey* return* throws RuntimeException*/public static boolean rsaCheck(String content, String sign, String publicKey) throws RuntimeException {return rsaCheckContent(content, sign, publicKey, UTF-8);}/*** rsa2验签** param content* param sign* param publicKey* return* throws RuntimeException*/public static boolean rsa256Check(String content, String sign, String publicKey) throws RuntimeException {return rsa256CheckContent(content, sign, publicKey, UTF-8);}/*** rsa验签** param content* param sign* param publicKey* param charset* return* throws RuntimeException*/public static boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws RuntimeException {try {PublicKey pubKey RsaUtils.getPublicKey(publicKey);Signature signature Signature.getInstance(SHA1WithRSA);signature.initVerify(pubKey);if (StringUtils.isEmpty(charset)) {signature.update(content.getBytes());} else {signature.update(content.getBytes(charset));}return signature.verify(Base64.getDecoder().decode(sign.getBytes()));} catch (Exception var6) {throw new RuntimeException(RSAContent content ,sign sign ,charset charset, var6);}}/*** rsa2验签** param content* param sign 签名* param publicKey* param charset* return* throws RuntimeException*/public static boolean rsa256CheckContent(String content, String sign, String publicKey, String charset) throws RuntimeException {try {PublicKey pubKey RsaUtils.getPublicKey(publicKey);Signature signature Signature.getInstance(SHA256WithRSA);signature.initVerify(pubKey);if (StringUtils.isEmpty(charset)) {signature.update(content.getBytes());} else {signature.update(content.getBytes(charset));}return signature.verify(Base64.getDecoder().decode(sign.getBytes()));} catch (Exception var6) {throw new RuntimeException(RSAContent content ,sign sign ,charset charset, var6);}}} RsaUtils package com.lwh.utils.encrypt;import com.lwh.utils.StreamUtil;import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.security.KeyFactory; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64;import lombok.extern.slf4j.Slf4j;/*** 读取RSA密钥*/ Slf4j public class RsaUtils {private static final String CHARSET UTF-8;private static final String SIGN_ALGORITHMS SHA1WithRSA;/*** -----------------------------------------私钥读取start----------------------------------------------------*//*** 字符串转私钥** param keyString BASE64密钥字符串* return* throws Exception*/public static PrivateKey getPrivateKey(String keyString) throws Exception {return getPrivateKeyFromPKCS8(new ByteArrayInputStream(keyString.getBytes()));}/*** 根据私钥路径读取BASE64密钥字符串** param path 私钥路径* param pwd 私钥密码* return*/public static String getPrivateKeyStringFromFile(String path, String pwd) {PrivateKey privateKey getPrivateKeyFromFile(path, pwd);if (privateKey null) {return null;}return privateKeyToString(privateKey);}/*** 根据私钥路径读取私钥对象** param path 私钥路径* param priKeyPass 私钥密码* return*/public static PrivateKey getPrivateKeyFromFile(String path, String priKeyPass) {InputStream priKeyStream null;try {priKeyStream new FileInputStream(path);byte[] reads new byte[priKeyStream.available()];priKeyStream.read(reads);return getPrivateKeyFromPKCS8(new ByteArrayInputStream(reads));} catch (IOException e) {log.error(解析文件读取私钥失败:, e);} catch (KeyStoreException e) {log.error(私钥存储异常:, e);} catch (NoSuchAlgorithmException e) {log.error(不存在的解密算法:, e);} catch (CertificateException e) {log.error(证书异常:, e);} catch (UnrecoverableKeyException e) {log.error(不可恢复的秘钥异常, e);} catch (Exception e) {log.error(解析文件读取私钥失败:, e);} finally {if (priKeyStream ! null) {try {priKeyStream.close();} catch (Exception e) {e.printStackTrace();}}}return null;}/*** 流转换密钥** param ins 密钥流* return* throws Exception*/public static PrivateKey getPrivateKeyFromPKCS8(InputStream ins) throws Exception {if (ins ! null) {KeyFactory keyFactory KeyFactory.getInstance(RSA);byte[] encodedKey StreamUtil.readText(ins).getBytes();encodedKey Base64.getDecoder().decode(encodedKey);return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));} else {return null;}}public static String privateKeyToString(PrivateKey privateKey) {Base64.Encoder encoder Base64.getEncoder();byte[] publicKeyString encoder.encode(privateKey.getEncoded());return new String(publicKeyString);}/*** -----------------------------------------公钥start----------------------------------------------------*//*** 字符串转公钥** param keyString* return* throws Exception*/public static PublicKey getPublicKey(String keyString) throws Exception {Base64.Decoder decoder Base64.getDecoder();byte[] keyBytes decoder.decode(keyString);X509EncodedKeySpec keySpec new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory KeyFactory.getInstance(EncryptMode.RSA.value());return keyFactory.generatePublic(keySpec);}/*** 指定路径读取公钥BASE64字符串** param path* return*/public static String getPublicKeyStringFromFile(String path) {PublicKey publicKey null;FileInputStream pubKeyStream null;try {pubKeyStream new FileInputStream(path);byte[] reads new byte[pubKeyStream.available()];pubKeyStream.read(reads);publicKey getPublicKey(new String(reads));} catch (Exception e) {e.printStackTrace();} finally {if (pubKeyStream ! null) {try {pubKeyStream.close();} catch (Exception e) {e.printStackTrace();}}}if (publicKey null) {return null;}return publicKeyToString(publicKey);}/*** 指定路径读取公钥BASE64字符串** param path* return*/public static PublicKey getPublicKeyFromFile(String path) {FileInputStream pubKeyStream null;try {pubKeyStream new FileInputStream(path);byte[] reads new byte[pubKeyStream.available()];pubKeyStream.read(reads);return getPublicKeyFromX509(new ByteArrayInputStream(reads));} catch (Exception e) {e.printStackTrace();} finally {if (pubKeyStream ! null) {try {pubKeyStream.close();} catch (Exception e) {e.printStackTrace();}}}return null;}public static PublicKey getPublicKeyFromX509(InputStream ins) throws Exception {KeyFactory keyFactory KeyFactory.getInstance(RSA);StringWriter writer new StringWriter();StreamUtil.io(new InputStreamReader(ins), writer);byte[] encodedKey writer.toString().getBytes();encodedKey Base64.getDecoder().decode(encodedKey);return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));}public static String publicKeyToString(PublicKey publicKey) {Base64.Encoder encoder Base64.getEncoder();byte[] publicKeyString encoder.encode(publicKey.getEncoded());return new String(publicKeyString);}/*** RSA验签名检查** param content 待签名数据* param sign 签名值* param public_key 公钥* return 布尔值*/public static boolean verify(String content, String sign, String public_key) {try {KeyFactory keyFactory KeyFactory.getInstance(RSA);byte[] encodedKey org.apache.commons.codec.binary.Base64.decodeBase64(public_key);PublicKey pubKey keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));Signature signature Signature.getInstance(SIGN_ALGORITHMS);signature.initVerify(pubKey);signature.update(content.getBytes(CHARSET));return signature.verify(org.apache.commons.codec.binary.Base64.decodeBase64(sign));} catch (Exception e) {throw new RuntimeException(验签时遇到异常, e);}}} StreamUtil package com.lwh.utils;import java.io.*; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate;public class StreamUtil {private static final int DEFAULT_BUFFER_SIZE 8192;public StreamUtil() {}public static void io(InputStream in, OutputStream out) throws IOException {io((InputStream) in, (OutputStream) out, -1);}public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {if (bufferSize -1) {bufferSize 8192;}byte[] buffer new byte[bufferSize];int amount;while ((amount in.read(buffer)) 0) {out.write(buffer, 0, amount);}}public static void io(Reader in, Writer out) throws IOException {io((Reader) in, (Writer) out, -1);}public static void io(Reader in, Writer out, int bufferSize) throws IOException {if (bufferSize -1) {bufferSize 4096;}char[] buffer new char[bufferSize];int amount;while ((amount in.read(buffer)) 0) {out.write(buffer, 0, amount);}}public static OutputStream synchronizedOutputStream(OutputStream out) {return new StreamUtil.SynchronizedOutputStream(out);}public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {return new StreamUtil.SynchronizedOutputStream(out, lock);}public static String readText(InputStream in) throws IOException {return readText(in, (String) null, -1);}public static String readText(InputStream in, String encoding) throws IOException {return readText(in, encoding, -1);}public static String readText(InputStream in, String encoding, int bufferSize) throws IOException {Reader reader encoding null ? new InputStreamReader(in) : new InputStreamReader(in, encoding);return readText(reader, bufferSize);}public static String readText(Reader reader) throws IOException {return readText(reader, -1);}public static String readText(Reader reader, int bufferSize) throws IOException {StringWriter writer new StringWriter();io((Reader) reader, (Writer) writer, bufferSize);return writer.toString();}private static class SynchronizedOutputStream extends OutputStream {private OutputStream out;private Object lock;SynchronizedOutputStream(OutputStream out) {this(out, out);}SynchronizedOutputStream(OutputStream out, Object lock) {this.out out;this.lock lock;}Overridepublic void write(int datum) throws IOException {Object var2 this.lock;synchronized (this.lock) {this.out.write(datum);}}Overridepublic void write(byte[] data) throws IOException {Object var2 this.lock;synchronized (this.lock) {this.out.write(data);}}Overridepublic void write(byte[] data, int offset, int length) throws IOException {Object var4 this.lock;synchronized (this.lock) {this.out.write(data, offset, length);}}Overridepublic void flush() throws IOException {Object var1 this.lock;synchronized (this.lock) {this.out.flush();}}Overridepublic void close() throws IOException {Object var1 this.lock;synchronized (this.lock) {this.out.close();}}}public static T PredicateT distinctByKey(Function? super T, ? keyExtractor) {SetObject seen ConcurrentHashMap.newKeySet();return t - seen.add(keyExtractor.apply(t));}} 开放平台-解密过滤器 package com.lwh.filter.zrs;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.lwh.common.PlatformContact; import com.lwh.filter.ZuulFilterHelper; import com.lwh.model.PlatformConfig; import com.lwh.response.CommonCode; import com.lwh.response.ServerResponse; import com.lwh.service.PlatformService; import com.lwh.utils.RequestUtil; import com.lwh.utils.encrypt.AesUtil; import com.lwh.utils.encrypt.RsaSignature; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import com.netflix.zuul.http.ServletInputStreamWrapper; import com.zcckj.common.utils.JsonUtils; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.WebUtils;import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.List;/*** description 开放接口验签解密过滤器*/ Slf4j Component public class ZrsOpenApiDecryptFilter extends ZuulFilter {Value(${openapi.uri.prefix})private String openApiPrefix;Value(${system.ip.whiteList})private String systemIpWhiteList;Autowiredprivate PlatformService platformService;Overridepublic String filterType() {/*pre请求在被路由之前执行routing在路由请求时调用post在routing和error过滤器之后调用error处理请求时发生错误调用*/return pre;}Overridepublic int filterOrder() {/*过虑器序号越小越被优先执行*/return 1;}SneakyThrowsOverridepublic boolean shouldFilter() {//返回true表示要执行此过虑器RequestContext requestContext RequestContext.getCurrentContext();HttpServletRequest request requestContext.getRequest();//需要转换uri的条件String requestURI request.getRequestURI();String[] uriArray openApiPrefix.split(,);for (String anUriArray : uriArray) {if (requestURI.startsWith(anUriArray)) {//后续根据此条件判断是否加密响应与是否重置路由映射log.info(请求地址:{} 是开放接口, requestURI);requestContext.set(isOpenApi, true);return true;}}requestContext.set(isOpenApi, false);return false;}Overridepublic Object run() throws ZuulException {try {RequestContext requestContext RequestContext.getCurrentContext();HttpServletRequest request requestContext.getRequest();//1解析请求参数String appId RequestUtil.getHeadParams(request, PlatformContact.APP_ID);if (StringUtils.isBlank(appId)) {ZuulFilterHelper.accessDenied(ServerResponse.createByErrorCodeMessage(CommonCode.CODE_00405.code(), appId不能为空));return null;}//3查询平台信息PlatformConfig platformConfig platformService.getPlatformByAppId(appId);if(platformConfignull){ZuulFilterHelper.accessDenied(ServerResponse.createByErrorCodeMessage(CommonCode.CODE_00405.code(),非法appId));return null;}requestContext.set(platformConfigDTO, platformConfig);//4白名单验证/* if (!this.checkWhiteIpList(RequestUtil.getIpAddr(request), platformConfig)) {ZuulFilterHelper.accessDenied(ServerResponse.createByErrorCodeMessage(CommonCode.CODE_00405.code(),白名单拦截));return null;}*///5验签if (!this.verifySign(request, platformConfig)) {ZuulFilterHelper.accessDenied(ServerResponse.createByErrorCodeMessage(CommonCode.CODE_00405.code(),签名失败));return null;}//文件上传特殊处理,不进行解密了String contentType request.getHeader(Content-Type);if(!StringUtils.isBlank(contentType)contentType.contains(multipart/form-data)){return null;}//请求体不为空不校验String bodyString RequestUtil.getBodyString(request);JSONObject jsonObjectnull;if(StringUtils.isBlank(bodyString)){jsonObjectnew JSONObject();}else{//6解密String jsonData this.decryptData(bodyString, platformConfig);jsonObject JSON.parseObject(jsonData);}//增加jsonjsonObject.put(distributorId, platformConfig.getDistributorId());String dataContent JsonUtils.toJsonString(jsonObject);if (StringUtils.isBlank(dataContent)) {ZuulFilterHelper.accessDenied(ServerResponse.createByErrorCodeMessage(CommonCode.CODE_00405.code(),请求参数解密失败));return null;}log.info(解密成功后请求参数:{}, dataContent);//7重置请求上下文requestContext.setRequest(new HttpServletRequestWrapper(requestContext.getRequest()) {Overridepublic ServletInputStream getInputStream() {return new ServletInputStreamWrapper(dataContent.getBytes());}Overridepublic int getContentLength() {return dataContent.getBytes().length;}Overridepublic long getContentLengthLong() {return dataContent.getBytes().length;}});} catch (Exception e) {ZuulFilterHelper.accessDenied(ServerResponse.createErrorByCode(CommonCode.CODE_00001));e.printStackTrace();log.error(ZRS解密验签流程出现异常,e);}return null;}private JSONObject parse(HttpServletRequest request) {JSONObject jsonObject null;try {//转换参数String res RequestUtil.getBodyString(request);jsonObject JSON.parseObject(res);} catch (Exception e) {log.error(服务网关请求参数解析异常, e);return null;}return jsonObject;}/*** 校验请求地址是否符合白名单** param ip* param platformConfig* return*/private boolean checkWhiteIpList(String ip, PlatformConfig platformConfig) {//判断是否 生产环境||测试环境ListString ipArray new ArrayList();//平台配置白名单if (platformConfig ! null) {String ipArrayStr platformConfig.getWhiteIpList();if (StringUtils.isBlank(ipArrayStr) || StringUtils.isBlank(ip)) {return false;}ListString ips Arrays.asList(ipArrayStr.split(,));ipArray.addAll(ips);}//系统配置白名单if (!StringUtils.isBlank(systemIpWhiteList)) {ListString ips Arrays.asList(systemIpWhiteList.split(,));ipArray.addAll(ips);}log.info(当前请求ip:{},构建白名单地址列表{},ip, ipArray);boolean contains ipArray.contains(ip);if (!contains) {log.error(请求地址:{}未加入到白名单列表请求拒绝, ip);return false;}return true;}/*** 使用对接方的DSA公钥进行验签** param request 请求上下文* param platformConfig 平台配置* return* throws* author 房维超* date 2018/10/24 16:07*/private boolean verifySign(HttpServletRequest request, PlatformConfig platformConfig) {//1获取对方公钥String dsaPublicKeyStr platformConfig.getPlatformUploadPubRsa();StringBuilder originalSign new StringBuilder();originalSign.append(RequestUtil.getHeadParams(request,PlatformContact.APP_ID));originalSign.append(RequestUtil.getHeadParams(request,PlatformContact.VERSION));originalSign.append(RequestUtil.getHeadParams(request,PlatformContact.TIMESTAMP));String sign RequestUtil.getHeadParams(request,PlatformContact.SIGN);try {if (!RsaSignature.rsaCheck(originalSign.toString(), sign,dsaPublicKeyStr)) {//签名验证失败return false;}} catch (Exception e) {log.error(网关延签异常, e);return false;}log.info(验证签名成功:{}, originalSign);return true;}/*** 使用我方平台RSA私钥进行解密** param dataContent 密文数据* return 解密后的数据* throws* author 房维超* date 2018/10/24 16:14*/private String decryptData(String dataContent, PlatformConfig platformConfig) {try {//1应用私钥String aesKey platformConfig.getAesKey();log.info(密码aesKey);//2使用私钥解密dataContent AesUtil.aesDecode(URLDecoder.decode(dataContent, UTF-8), aesKey);} catch (Exception e) {log.error(解密请求数据发生异常报文{} 错误信息{},,dataContent, e.getMessage(), e);return null;}return dataContent;}/*** 打印请求参数** param request*/private String getRequestBody(ContentCachingRequestWrapper request) {ContentCachingRequestWrapper wrapper WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);if (wrapper ! null) {byte[] buf wrapper.getContentAsByteArray();if (buf.length 0) {String payload;try {payload new String(buf, 0, buf.length, wrapper.getCharacterEncoding());} catch (UnsupportedEncodingException e) {payload [unknown];}return payload.replaceAll(\\n, );}}return ;} } 开放平台-加密过滤器 package com.lwh.filter.zrs;import com.lwh.model.PlatformConfig; import com.lwh.loancloud.response.ServerResponse; import com.lwh.loancloud.utils.JsonUtil; import com.lwh.loancloud.utils.encrypt.AesUtil; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils;import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.nio.charset.StandardCharsets;/*** description 开放接口响应加密过滤器*/ Slf4j Component public class ZrsOpenApiEncryptFilter extends ZuulFilter {Autowiredprivate RedisTemplate redisTemplate;Value(${openapi.uri.prefix})private String openApiPrefix;Overridepublic String filterType() {/*pre请求在被路由之前执行routing在路由请求时调用post在routing和error过滤器之后调用error处理请求时发生错误调用*/return post;}Overridepublic int filterOrder() {/*过虑器序号越小越被优先执行*/return 0;}Overridepublic boolean shouldFilter() {//返回true表示要执行此过虑器RequestContext requestContext RequestContext.getCurrentContext();return (boolean) requestContext.get(isOpenApi);}Overridepublic Object run() throws ZuulException {try {RequestContext requestContext RequestContext.getCurrentContext();HttpServletResponse response requestContext.getResponse();response.setContentType(application/json;charsetutf-8);InputStream stream requestContext.getResponseDataStream();if (stream null) {log.error(网关加密处理失败响应数据为空);return null;}String responseContent StreamUtils.copyToString(stream, StandardCharsets.UTF_8);log.info(网关加密处理返回值:{}, responseContent);PlatformConfig platformConfig (PlatformConfig) requestContext.get(platformConfigDTO);ServerResponse serverResponse JsonUtil.jsonToPojo(responseContent, ServerResponse.class);if (serverResponse null) {log.error(网关加密处理失败反序列化ServerResponse失败内容:{}, requestContext);return null;}if (serverResponse.getData() ! null) {//加密处理this.encrypt(serverResponse, platformConfig);}//设置响应代码requestContext.setResponseStatusCode(200);//转成jsonString jsonString JsonUtil.objectToJson(serverResponse);requestContext.setResponseBody(jsonString);} catch (Exception e) {e.printStackTrace();log.error(ZRS响应加密流程出现异常,e);}return null;}/*** 组装返回数据** param serverResponse 请求需要的返回数据* param platformConfig 请求用于的相关配置* return*/private ServerResponse encrypt(ServerResponse serverResponse, PlatformConfig platformConfig) {try {//使用aes加密String key platformConfig.getAesKey();String data JsonUtil.obj2StringPretty(serverResponse.getData());serverResponse.setData(AesUtil.aesEncode(data,key));return serverResponse;} catch (Exception e) {log.error(加密响应数据发生异常{}, e.getMessage(), e);}return null;}} 调用方代码 公共代码 /*** 生成签名** param content* param privateKey* return* throws RuntimeException*/public static String rsaSign(String content, String privateKey) throws RuntimeException {try {KeyFactory keyFactory KeyFactory.getInstance(RSA);byte[] encodedKey Base64.getDecoder().decode(privateKey.getBytes());PrivateKey priKey keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));Signature signature Signature.getInstance(SHA1WithRSA);signature.initSign(priKey);signature.update(content.getBytes(StandardCharsets.UTF_8));byte[] signed signature.sign();return new String(Base64.getEncoder().encode(signed));} catch (InvalidKeySpecException var6) {throw new RuntimeException(RSA私钥格式不正确请检查是否正确配置了PKCS8格式的私钥, var6);} catch (Exception var7) {throw new RuntimeException(RSAContent content ; charset UTF-8, var7);}}/*** 加密* 1.构造密钥生成器* 2.根据ecnodeRules规则初始化密钥生成器* 3.产生密钥* 4.创建和初始化密码器* 5.内容加密* 6.返回字符串*/public static String aesEncode(String content, String pwd) {try {//1.构造密钥生成器指定为AES算法,不区分大小写KeyGenerator keyGenerator KeyGenerator.getInstance(AES);//2.根据ecnodeRules规则初始化密钥生成器//生成一个128位的随机源,根据传入的字节数组SecureRandom random SecureRandom.getInstance(SHA1PRNG);random.setSeed(pwd.getBytes());keyGenerator.init(128, random);//3.产生原始对称密钥SecretKey originalKey keyGenerator.generateKey();//4.获得原始对称密钥的字节数组byte[] raw originalKey.getEncoded();//5.根据字节数组生成AES密钥SecretKey key new SecretKeySpec(raw, AES);//6.根据指定算法AES自成密码器Cipher cipher Cipher.getInstance(AES);//7.初始化密码器第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作第二个参数为使用的KEYcipher.init(Cipher.ENCRYPT_MODE, key);//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码byte[] byteEncode content.getBytes(StandardCharsets.UTF_8);//9.根据密码器的初始化方式--加密将数据加密byte[] byteAES cipher.doFinal(byteEncode);//10.将加密后的数据转换为字符串//这里用Base64Encoder中会找不到包//解决办法//在项目的Build path中先移除JRE System Library再添加库JRE System Library重新编译后就一切正常了。//11.将字符串返回return new BASE64Encoder().encode(byteAES);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}//如果有错就返加nulllreturn null;}/*** 解密* 解密过程* 1.同加密1-4步* 2.将加密后的字符串反纺成byte[]数组* 3.将加密内容解密*/public static String aesDecode(String content, String pwd) {try {//1.构造密钥生成器指定为AES算法,不区分大小写KeyGenerator keygen KeyGenerator.getInstance(AES);//2.根据ecnodeRules规则初始化密钥生成器//生成一个128位的随机源,根据传入的字节数组SecureRandom random SecureRandom.getInstance(SHA1PRNG);random.setSeed(pwd.getBytes());keygen.init(128, random);//3.产生原始对称密钥SecretKey originalKey keygen.generateKey();//4.获得原始对称密钥的字节数组byte[] raw originalKey.getEncoded();//5.根据字节数组生成AES密钥SecretKey key new SecretKeySpec(raw, AES);//6.根据指定算法AES自成密码器Cipher cipher Cipher.getInstance(AES);//7.初始化密码器第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作第二个参数为使用的KEYcipher.init(Cipher.DECRYPT_MODE, key);//8.将加密并编码后的内容解码成字节数组byte[] byteContent new BASE64Decoder().decodeBuffer(content);/** 解密*/byte[] byteDecode cipher.doFinal(byteContent);return new String(byteDecode, StandardCharsets.UTF_8);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {throw new RuntimeException(兄弟配置文件中的密码需要使用AES加密请使用com.zheng.common.util.AESUtil工具类修改这些值);//e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}//异常返nullreturn null;}Get-Demo package com.example.demo.open;import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.example.demo.entity.Result; import com.google.common.collect.Maps; import sun.misc.BASE64Decoder;import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.HashMap;/*** author lwh* date 2023/2/14* description 调用开放平台接口**/ public class OpenGetDemo {// 密钥aesprivate static final String secretKey ;// 私钥private static final String privateKey ;// 接入方身份标识private static final String appId ;// 目前版本号private static final String version ;public static void main(String[] args) {getRequest();}private static void getRequest() {String url 域名HttpRequest httpRequest HttpUtil.createGet(url地址);// 时间戳String timestamp String.valueOf(DateUtil.current());// 签名String sign rsaSign(appId version timestamp, privateKey);HashMapString, String maps Maps.newHashMap();maps.put(appId, appId);maps.put(version, version);maps.put(timestamp, timestamp);maps.put(sign, sign);httpRequest.addHeaders(maps);HashMapString, String parameterMap Maps.newHashMap();parameterMap.put(key, 传入的内容是什么返回的就是什么);httpRequest.formStr(parameterMap);HttpResponse execute httpRequest.execute();System.out.println(返回的内容);System.out.println(execute.body());Result result JSON.parseObject(execute.body(), Result.class);System.out.println(aes解密 aesDecode((String) result.getData(), secretKey));} } Post-Demo package com.example.demo.open;import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.example.demo.entity.PostTestRecordRequest; import com.example.demo.entity.Result; import com.example.demo.utils.AesUtil; import com.google.common.collect.Maps; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; import java.util.HashMap;/*** author lwh* date 2023/2/14* description 调用开放平台接口**/ public class OpenPostDemo {// 密钥aesprivate static final String secretKey ;// 私钥private static final String privateKey ;// 接入方身份标识private static final String appId ;// 目前版本号private static final String version ;public static void main(String[] args) throws UnsupportedEncodingException {postRequest();}private static void postRequest() throws UnsupportedEncodingException {String url 域名HttpRequest httpRequest HttpUtil.createPost(url地址);// 时间戳String timestamp String.valueOf(DateUtil.current());// 签名String sign rsaSign(appId version timestamp, privateKey);HashMapString, String maps Maps.newHashMap();maps.put(appId, appId);maps.put(version, version);maps.put(timestamp, timestamp);maps.put(sign, sign);httpRequest.addHeaders(maps);// body加密之后要设置content-typehttpRequest.header(content-type, application/json);PostTestRecordRequest request new PostTestRecordRequest();request.setName(xxx);request.setSize(10);request.setAmount(new BigDecimal(100.25));request.setIdList(Arrays.asList(1L, 2L, 3L));String jsonBody JSON.toJSONString(request);// json加密String content aesEncode(jsonBody, secretKey);// 加密之后要URL编码否则传输会出现乱码String encode URLEncoder.encode(content, UTF-8);httpRequest.body(encode);System.out.println(请求加密Encode encode);HttpResponse execute httpRequest.execute();System.out.println(返回的内容);System.out.println(execute.body());Result result JSON.parseObject(execute.body(), Result.class);System.out.println(aes解密 aesDecode((String) result.getData(), secretKey));} } 到这双方请求数据和响应数据的加密和解密就完成了能看出还是有很多东西的但是毕竟包含了所有东西你这基本拿过去就能用了对吧在做加密和解密的同时也做了接口的限流后面把接口的限流发布上来供大家参考。