package cn.tencent.data.ext.service.handler.common.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class TCRsaUtil {
    private static PrivateKey privateKey;
    private static PublicKey publicKey;
    private static PublicKey provideKey;
    /**
     * 数字签名 签名/验证算法
     */
    static String SIGNATURE_ALGORITHM ="SHA1withRSA";
    static String RSA ="RSA";
    /**
     * 获取公钥
     * X.509是定义了公钥证书结构的基本标准
     *
     * @param bytes 公钥的字节形式
     * @return 公钥对象
     * @throws Exception
     */
    public static void getPublicKey(byte[] bytes) throws Exception {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance(RSA);
        publicKey = factory.generatePublic(spec);
    }
    public static void getProvideKey(byte[] bytes) throws Exception {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance(RSA);
        provideKey = factory.generatePublic(spec);
    }
    /**
     * 获取私钥
     *
     * @param bytes 私钥的字节形式
     * @return 私钥对象
     * @throws Exception
     */
    public static void getPrivateKey(byte[] bytes) throws Exception {
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance(RSA);
        privateKey = factory.generatePrivate(spec);
    }
    public static String decrypt(String data) throws RuntimeException {
        try {
            if (privateKey == null) {
                throw new RuntimeException("私钥不存在!请先导入私钥");
            }
            KeyFactory factory = KeyFactory.getInstance(RSA);
            // 对数据解密
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return Base64.encodeBase64String(cipher.doFinal(Base64.decodeBase64(data)));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
    public static String encrypt(String data) throws RuntimeException {
        if (publicKey == null) {
            throw new RuntimeException("公钥不存在!请先导入公钥");
        }
        // 对数据加密
        try {
            KeyFactory factory = KeyFactory.getInstance(RSA);
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64.encodeBase64String(cipher.doFinal(Base64.decodeBase64(data)));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
    public static String sign(byte[] data) throws RuntimeException {
        // 实例化Signature
        try {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            // 初始化Signature
            signature.initSign(privateKey);
            // 更新
            signature.update(data);
            // 签名
            return Base64.encodeBase64String(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
    public static boolean verify(String data,String signStr) throws RuntimeException {
        // 实例化Signature
        try {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            // 初始化Signature
            signature.initVerify(provideKey);
            // 更新
            signature.update(Base64.decodeBase64(data));
            // 验证
            return signature.verify(Base64.decodeBase64(signStr));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
}
package cn.tencent.data.ext.service.handler.common.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
public class AESUtil {
    /**
     * 密钥算法
     */
    public static final String KEY_ALGORITHM = "AES";
    /**
     * 加密/解密算法 / 工作模式 / 填充方式
     * Java 6支持PKCS5Padding填充方式
     * Bouncy Castle支持PKCS7Padding填充方式
     */
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    //AES加密
    public static String encryptAES(String str, String key) {
        if (key == null) {
            //System.out.print("Key为空null");
            System.out.println("Key为空null");
            return null;
        }
        // 判断Key是否为16位
        if (key.length() != 16) {
            //System.out.print("Key长度不是16位");
            System.out.println("Key长度不是16位");
            return null;
        }
        byte[] encrypted = null;
        try {
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            encrypted = cipher.doFinal(str.getBytes("utf-8"));
            return new Base64().encodeToString(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
    //AES解密
    public static String decryptAES(String str, String key) {
        try {
            // 判断Key是否正确
            if (key == null) {
                //System.out.print("Key为空null");
                System.out.println("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (key.length() != 16) {
                //System.out.print("Key长度不是16位");
                System.out.println("Key长度不是16位");
                return null;
            }
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] encrypted1 = new Base64().decode(str);//先用base64解密
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original, "utf-8");
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }
    /**
     * 解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[] 解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 还原密钥
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 还原密钥
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 初始化,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }
    public static Key toKey(byte[] key) throws Exception {
        // 实例化AES密钥材料
        SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
        return secretKey;
    }
}
package cn.tencent.data.ext.service.handler.common;
import cn.tencent.core.util.StringUtils;
import cn.tencent.data.core.enumeration.ApiType;
import cn.tencent.data.core.service.dto.ApiDataSourceDto;
import cn.tencent.data.core.service.dto.ApiDto;
import cn.tencent.data.core.service.impl.ApiDataSourceService;
import cn.tencent.data.ext.domain.ApiDataSourceInvokeContext;
import cn.tencent.data.ext.exception.ApiDataSourceException;
import cn.tencent.data.ext.service.dto.ApiResponseDto;
import cn.tencent.data.ext.service.handler.RestfulApiDataSourceHandler;
import cn.tencent.data.ext.service.handler.common.util.AESUtil;
import cn.tencent.data.ext.service.handler.common.util.TCRsaUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jodd.util.StringUtil;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
@Component
public class TCPersonReportHandler extends RestfulApiDataSourceHandler {
    private static String AES_KEY;
    private final Logger log = LoggerFactory.getLogger(TCPersonReportHandler.class);
    @Autowired
    @Lazy
    private cn.tencent.data.core.service.IApiService apiService;
    @Autowired
    @Lazy
    private cn.tencent.data.ext.service.IApiCoreService apiCoreService;
    @Autowired
    private ApiDataSourceService apiDataSourceService;
    private final static String ACCESS_TOKEN_LINK = "?access_token=";
    private static String TC_QUERY_APICODE = "tcQueryInterface";
    private static String TC_INITIATE_QUERY_APICODE = "tcInitiateQuery";
    private static String TC_QUERY_REPORT_APICODE = "tcQueryReport";
    @Override
    protected ResponseEntity<String> callDataSource(Map<String, String> dataSourceHeaderParams,
                                                    Map<String, String> query,
                                                    Map<String, String> dataSourceParams,
                                                    ApiDataSourceInvokeContext context) throws ApiDataSourceException {
        log.info("------- dataSourceParams -------" + dataSourceParams.toString());
        ApiResponseDto response = new ApiResponseDto();
        String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIAmtbRh93omnB8sSlfZwzaPsyGuWjjZ46NFZglxSD2LVqM0igjsc77yWne7yLqnF7M4p/+rdLY3P76j8hm9HzUMw1pvCFFR46BW9fRUfN359c6sLYFQ4rl0sUbud9lamNaysIgxnE4wWfRpJ+RML9GMovYBRnS2XgTU8S5iVQvtAgMBAAECgYBaXXGByhcdXn52iN+/hQHfxoLVPEHIlvSrG/Owst3y7/9exFyVoE6aFgFvLs6Dt/HBYjEs2zVIjDr57ld4iOCoodqOPUELPHUJSBREAp41lVqB4E9Fuz19qn1ixnscvaHYYYLi0AHote4XW2Lw2MGNDsojAPnzqgXAndXCCarGLQJBAMpqB5B4fDbkbdmu/Zqel9FiSOBieGTjQxgD3rQgNLKrDdNNIDd6GwO/icj/62WGatfY06LBXejfpa4A3p1U75cCQQCiE78JOHFseKdXIPNlvNYLrm69zKFI6W0tcl1umQOu4LSmtiYcus+czBDo4L+vPHSgEKMw858+DL7//lU8F1EbAkB+h08ZMSe8jIhahffDmpWebojNsuA9eI6tSWYCRQuMED9BMboM08hlTGsN+WQlf6P0L3cEC0nv0zXXEnYV9U0bAkBHDlkmdbRkVdEnha6v38YHgQXT+C6NhKj0z7rejf7rYGBS5nB3D/+NQnn3XvEqplqLAkBJacVassPZ/2rm2WIZAkEAiNd9lF3ZYY6S3OmOPr4gAd7MDvfeOVoJFo1NJV/ow0MpgCc2KQpqzjawAqvt16KLOQ9twX2sYge133aOdxk1dQ==";
        String providerKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChCppyswOIwA/Cay8h+MSEjaVCRuC9WjwVMknOAecmGUjNGtZOZUgf8B/lm7ClzHTTdQ7IsjwxOrmbx+SZx02+H1kLpO6k1JQH6yBepb7ctMLMGj9hEF5tD80OWBrqRstUiCM2WB3AWGiog5sRFXvvkNTwGRh+OyfEG/4eDWwhgwIDAQAB";
        try {
            String token = "";
            String jsonString = "";
            String appid = "TestApp";
            String secret = "9C5AF28FE4A201F1904732A32CFB3913";
            Map<String, String> param = new HashMap<>();
            param.put("appid", appid);
            param.put("secret", secret);
            log.info("------- param -------" + param.toString());
            //校验机制凭证
            Long apiId = getApiId(TC_QUERY_APICODE);
            log.info("------- apiId -------" + apiId);
            if (apiId == null) {
                return new ResponseEntity<String>("api已失效,apiCode: tcQueryInterface", HttpStatus.INTERNAL_SERVER_ERROR);
            }
            response = apiCoreService.handle(context.getPrincipal(), apiId,
                    param, ApiType.COMBINED_REPORT,
                    context.getIp(), context.getInvoId());
            log.info("------- response -------" + JSON.toJSONString(response));
            if (response == null) {
                return new ResponseEntity<String>("校验机制凭证返回值为空,请核查!", HttpStatus.OK);
            }
            if (response.getId() != null) {
                JSONObject jsonResult = JSONObject.parseObject(response.getResultData().toString());
                log.info("------- jsonResult -------" + jsonResult);
                token = null == jsonResult.get("access_token") ? null : String.valueOf(jsonResult.get("access_token"));
                String encryptKey = null == jsonResult.get("encrypt_key") ? null : String.valueOf(jsonResult.get("encrypt_key"));
                TCRsaUtil.getPrivateKey(Base64.decodeBase64(privateKey));
                TCRsaUtil.getProvideKey(Base64.decodeBase64(providerKey));
                AES_KEY = TCRsaUtil.decrypt(encryptKey);
                log.info("------- AES_KEY -------" + AES_KEY);
                if (StringUtils.isEmpty(token)) {
                    return new ResponseEntity<String>("校验机制凭证token无效,请核查", HttpStatus.OK);
                }
                //姓名
                String name = "";
                //身份征
                String idNum = "";
                //手机号
                String mobile = "";
                //身份类型
                String idType = "10";
                if (StringUtil.isNotBlank(dataSourceParams.get("name"))) {
                    name = dataSourceParams.get("name");
                }
                if (StringUtil.isNotBlank(dataSourceParams.get("idNum"))) {
                    idNum = dataSourceParams.get("idNum");
                }
                if (StringUtil.isNotBlank(dataSourceParams.get("mobile"))) {
                    mobile = dataSourceParams.get("mobile");
                }
                //发起查询接口
                Map<String, String> params = new HashMap<>();
                params.put("reqNo", UUID.randomUUID().toString());
                params.put("appid", appid);
                params.put("name", name);
                params.put("idType", idType);
                params.put("idNum", idNum);
                params.put("mobile", mobile);
                log.info("------- params -------" + params.toString());
                String inputStr = JSONObject.toJSONString(params);
                //客户端加密及签名
                //aes加密
                byte[] encryptData = AESUtil.encrypt(inputStr.getBytes(), Base64.decodeBase64(AES_KEY));
                log.info("------- encryptData -------" + encryptData.toString());
                String reqData = Base64.encodeBase64String(encryptData);
                //私钥签名
                String sign = TCRsaUtil.sign(encryptData);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("reqData", reqData);
                jsonObject.put("sign", sign);
                log.info("------- jsonObject -------" + jsonObject);
                String personCreditOrder = "";
                //发起查询接口
                //117:测试;   22:生产
                Long apiIdInitiate = getApiId(TC_INITIATE_QUERY_APICODE);
                log.info("------- apiIdInitiate -------" + apiIdInitiate);
                if (apiIdInitiate == null) {
                    return new ResponseEntity<String>("api已失效,apiCode: tcInitiateQuery", HttpStatus.INTERNAL_SERVER_ERROR);
                }
                List<ApiDataSourceDto> apiDataSourceDtos = apiDataSourceService.findByApiId(apiIdInitiate);
                if (apiDataSourceDtos != null) {
                    String url = apiDataSourceDtos.get(0).getUrl() + ACCESS_TOKEN_LINK + token;
                    log.info("------- tcInitiateQueryurl -------" + url);
                    personCreditOrder = doPost(jsonObject.toString(), url);
                    log.info("------- personCreditOrder -------" + personCreditOrder);
                }
                String retDatas = "";
                if (StringUtils.isNotEmpty(personCreditOrder)) {
                    JSONObject jsonPersonCredit = JSONObject.parseObject(personCreditOrder);
                    retDatas = null == jsonPersonCredit.get("retData") ? null : String.valueOf(jsonPersonCredit.get("retData"));
                }
                String taskId = "";
                String reqNo = "";
                //aes解密
                byte[] decryptData = AESUtil.decrypt(Base64.decodeBase64(retDatas), Base64.decodeBase64(AES_KEY));
                jsonString = new String(decryptData);
                JSONObject json = JSONObject.parseObject(jsonString);
                //任务id
                taskId = null == json.getString("taskId") ? null : json.getString("taskId");
                //请求交易流水号
                reqNo = null == json.getString("reqNo") ? null : json.getString("reqNo");
                if (StringUtils.isEmpty(taskId) || StringUtils.isEmpty(reqNo)) {
                    return new ResponseEntity<String>("获取taskId或reqNo的值无效,请核查", HttpStatus.OK);
                }
                //查询报告接口
                Map<String, String> paramss = new HashMap<>();
                paramss.put("reqNo", reqNo);
                paramss.put("taskId", taskId);
                paramss.put("appid", appid);
                log.info("------- paramss -------" + paramss.toString());
                String inputStrs = JSONObject.toJSONString(paramss);
                //aes加密
                byte[] encryptDatas = AESUtil.encrypt(inputStrs.getBytes(), Base64.decodeBase64(AES_KEY));
                String reqDatass = Base64.encodeBase64String(encryptDatas);
                //私钥签名
                String signs = TCRsaUtil.sign(encryptDatas);
                JSONObject jsonMap = new JSONObject();
                jsonMap.put("reqData", reqDatass);
                jsonMap.put("sign", signs);
                log.info("------- jsonMap -------" + jsonMap.toString());
                String order = "";
                //查询报告接口
                //118  :测试;    23: 生产
                Long apiIdQuery = getApiId(TC_QUERY_REPORT_APICODE);
                log.info("------- apiIdQuery -------" + apiIdQuery);
                if (apiIdQuery == null) {
                    return new ResponseEntity<String>("api已失效,apiCode: tcQueryReport", HttpStatus.INTERNAL_SERVER_ERROR);
                }
                List<ApiDataSourceDto> apiDataSourceDto = apiDataSourceService.findByApiId(apiIdQuery);
                if (apiDataSourceDto != null) {
                    String url = apiDataSourceDto.get(0).getUrl() + ACCESS_TOKEN_LINK + token;
                    log.info("------- tcQueryReport -------" + url);
                    order = doPost(jsonObject.toString(), url);
                }
                if (StringUtils.isNotEmpty(order)) {
                    JSONObject jsonOrder = JSONObject.parseObject(order);
                    log.info("------- jsonOrder -------" + jsonOrder.toJSONString());
                    return new ResponseEntity<String>(jsonOrder.toJSONString(), HttpStatus.OK);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public Long getApiId(String apiCode) {
        ApiDto dto = apiService.findByApiCode(apiCode);
        if (dto != null) {
            return dto.getId();
        } else {
            return null;
        }
    }
    private static String doPost(String appInfoStr, String url) throws UnsupportedEncodingException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        StringEntity entity;
        entity = new StringEntity(appInfoStr);
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);
        CloseableHttpResponse response = null;
        String tokenDataStr = null;
        try {
            response = httpClient.execute(httpPost);
            tokenDataStr = handleResponse(response);
        } catch (Exception e) {
            //log.warn(e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                ;
            }
        }
        return tokenDataStr;
    }
    public static String handleResponse(CloseableHttpResponse response) throws Exception {
        StatusLine statusLine = response.getStatusLine();
        HttpEntity entity = response.getEntity();
        try {
            if (statusLine.getStatusCode() >= 300) {
                EntityUtils.consume(entity);
                throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
            } else {
                return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8);
            }
        } catch (IOException e) {
            throw new Exception(e);
        }
    }
}
package cn.tencent.data.ext.service.handler.common;
import cn.tencent.data.ext.service.handler.common.util.AESUtil;
import cn.tencent.data.ext.service.handler.common.util.MD5Util;
import cn.tencent.data.ext.service.handler.common.util.ProjectConfig;
import cn.tencent.data.ext.service.handler.common.util.RSAUtil;
import cn.tencent.data.ext.vo.WyParamVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.tencent.data.ext.domain.ApiDataSourceInvokeContext;
import cn.tencent.data.ext.exception.ApiDataSourceException;
import cn.tencent.data.ext.service.handler.RestfulApiDataSourceHandler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.Map;
/**
 * @author ex-jian.xiang
 */
@Component
public class WyWindControlHandler extends RestfulApiDataSourceHandler {
    private final Logger log = LoggerFactory.getLogger(WyWindControlHandler.class);
    @Override
    protected ResponseEntity<String> callDataSource(Map<String, String> dataSourceHeaderParams,
                                                    Map<String, String> query,
                                                    Map<String, String> dataSourceParams,
                                                    ApiDataSourceInvokeContext context) throws ApiDataSourceException {
        log.info("------- dataSourceParams --------:{}", dataSourceParams.toString());
        //请求微言参数定义
        WyParamVo wyParamVo = new WyParamVo();
        //1. 处理入参,将sourceId,eventCode取出,其余参数为content内容,进行加密
        JSONObject content = new JSONObject();
        for (String key: dataSourceParams.keySet()) {
            if(key.equals("source_id")){
                wyParamVo.setSource_id(dataSourceParams.get(key));
            }else if(key.equals("event_code")){
                wyParamVo.setEvent_code(dataSourceParams.get(key));
            }else {
                content.put(key, dataSourceParams.get(key));
            }
        }
        log.info("sourceId为:{},eventCode为:{},需加密的content:{}", wyParamVo.getSource_id(), wyParamVo.getEvent_code(), content.toJSONString());
        //2. content进行AES加密
        String encryptedContent = AESUtil.encryptAES(content.toJSONString(), ProjectConfig.AESKEY);
        if (StringUtils.isEmpty(encryptedContent)){
            log.error("AES encrypt is null");
            return new ResponseEntity<String>("AES encrypt EXP", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        log.info("加密后content:{}", encryptedContent);
        //3. 获取签名,先对AES加密后content进行MD5摘要
        String md5Content = MD5Util.getMd5(encryptedContent);
        String signString = StringUtils.EMPTY;
        try {
            signString = RSAUtil.sign(md5Content, ProjectConfig.PRIVATEKEY, false);
        } catch (Exception e) {
            log.error("获取签名失败,{}", e);
            e.printStackTrace();
            return new ResponseEntity<String>("sign encrypt failed", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        log.info("数字签名:{}", signString);
        //4. 请求微言接口
        wyParamVo.setContent(encryptedContent);
        wyParamVo.setSignature(signString);
        String url = context.getMetadata().getUrl();
        String result = postJson(url, JSON.parseObject(JSON.toJSONString(wyParamVo)));
        //5. 解密content
        JSONObject resultObj = JSONObject.parseObject(result);
        String needDecryptString = resultObj.getString("content");
        String contentStr = AESUtil.decryptAES(needDecryptString, ProjectConfig.AESKEY);
        resultObj.put("content", JSON.parseObject(contentStr));
        log.info("微言接口返回报文:{}", resultObj.toJSONString());
        return new ResponseEntity<String>(resultObj.toJSONString(), HttpStatus.OK);
    }
    /**
     * 发送POST请求
     *
     * @param url
     *            目的地址
     * @param jsonObject
     * @return 远程响应结果
     */
    public static String postJson(String url, JSONObject jsonObject) {
        String result = "";// 返回的结果
        BufferedReader in = null;// 读取响应输入流
        PrintWriter out = null;
        try {
            java.net.URL connURL = new java.net.URL(url);
            java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL
                    .openConnection();
            httpConn.setRequestProperty("Content-Type", "application/json");
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            out = new PrintWriter(httpConn.getOutputStream());
            out.write(jsonObject.toJSONString());
            out.flush();
            in = new BufferedReader(new InputStreamReader(httpConn
                    .getInputStream(), "UTF-8"));
            String line;
            // 读取返回的内容
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}
package cn.tencent.data.ext.vo;
import lombok.Data;
/**
 * @Author: xj
 * @CreateTime: 2023-05-08  13:52
 * @Description: 微言接口入参
 * @Version: 1.0
 **/
public class WyParamVo {
    /**
     *不同产品对应不同sourceId
     */
    private String source_id;
    /**
     *不同产品对应不同eventCode
     */
    private String event_code;
    /**
     *对加密content字段做MD5摘要,再对摘要进⾏rsa私钥签名,对签名后的字符串做base64编码
     */
    private String signature;
    /**
     *对content明⽂字符串使⽤AES加密,对加密后的字符串base64编码
     */
    private String content;
    public String getSource_id() {
        return source_id;
    }
    public void setSource_id(String source_id) {
        this.source_id = source_id;
    }
    public String getEvent_code() {
        return event_code;
    }
    public void setEvent_code(String event_code) {
        this.event_code = event_code;
    }
    public String getSignature() {
        return signature;
    }
    public void setSignature(String signature) {
        this.signature = signature;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}