加密解密记录

发布时间 2023-06-28 15:14:41作者: 王飞侠

 

package com.javaweb.common.utils;

import com.alibaba.fastjson.JSON;
import com.javaweb.common.config.wxdto.WxPayApiConfig;
import com.javaweb.common.exception.CustomException;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.RSAConfig;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 微信支付操作工具类
 */
@Component
@Slf4j
public class WxPayUtil {
    /**
     * 加密算法提供方 - BouncyCastle
     */
    private static final String BC_PROVIDER = "BC";

//    @Resource
//    private WxPayApiConfig wxPayApiConfig;
    private byte[] certData;

    public static WxPayUtil create() {
        return new WxPayUtil();
    }
    /**
     * 微信支付私钥
     * @return
     * @throws CustomException
     */
    public static PrivateKey getMchPrivateKey(WxPayApiConfig wxPayApiConfig) throws CustomException {
        PrivateKey privateKey = null;
        try {
            privateKey = PemUtil.loadPrivateKey(
                    new FileInputStream(wxPayApiConfig.getKeyPath()));
        } catch (FileNotFoundException e) {
            throw new CustomException("[WxPayUtil.getMchPrivateKey] 获取私钥失败!文件找不到!");
        }
        return privateKey;
    }

    /**
     * 微信支付请求构建
     * @return https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN
     * @throws FileNotFoundException
     * @throws CustomException
     */
    public static WechatPayHttpClientBuilder getWechatPayHttpClientBuilder(WxPayApiConfig wxPayApiConfig) throws FileNotFoundException {
        WechatPayHttpClientBuilder builder = null;
        PrivateKey merchantPrivateKey = null;
        X509Certificate wechatPayCertificate = null;
        try {
            merchantPrivateKey = getMchPrivateKey(wxPayApiConfig);
            wechatPayCertificate = PemUtil.loadCertificate(
                    new FileInputStream(wxPayApiConfig.getPlatformCertPath()));

            ArrayList<X509Certificate> wechatPayCertificates = new ArrayList<>();
            wechatPayCertificates.add(wechatPayCertificate);

            builder = WechatPayHttpClientBuilder.create()
                    .withMerchant(wxPayApiConfig.getMchId(), wxPayApiConfig.getMchSerialNumber(), merchantPrivateKey)
                    .withWechatPay(wechatPayCertificates);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw e;
        } catch (CustomException e) {
            throw e;
        }
        return builder;
    }

    /**
     * 加载指定商户号对应的证书
     * @param pid 商户号id
     */
    public InputStream getCertStream() {
        try {
            InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("wx_cert_1/apiclient_cert.p12");
            this.certData = IOUtils.toByteArray(certStream);
            certStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);

        return certBis;
    }

    /**
     * 微信返回数据验签证书的获取 -- 获取证书管理器实例
     * @return
     */
    public static CertificatesManager getCertificatesManager(WxPayApiConfig wxPayApiConfig) throws CustomException, GeneralSecurityException, IOException, HttpCodeException {
        PrivateKey privateKey = getMchPrivateKey(wxPayApiConfig);

        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(
                wxPayApiConfig.getMchId(),
                new WechatPay2Credentials(wxPayApiConfig.getMchId(), new PrivateKeySigner(wxPayApiConfig.getMchSerialNumber(), privateKey)),
                wxPayApiConfig.getApiKey3().getBytes(StandardCharsets.UTF_8)
        );
        return certificatesManager;
    }

    /**
     * 获取验签器
     * @return
     */
    public static Verifier getVerifier(WxPayApiConfig wxPayApiConfig, CertificatesManager certificatesManager) throws NotFoundException {
        Verifier verifier = null;
        try {
            if (certificatesManager != null) {
                verifier = certificatesManager.getVerifier(wxPayApiConfig.getMchId());
            }
        } catch (NotFoundException e) {
            throw e;
        }
        return verifier;
    }

    /**
     * 获取POST请求
     * @param url
     * @return
     */
    public static HttpPost getHttpPost(String url) {
        HttpPost httpPost = new HttpPost(url);//"https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi"
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        return httpPost;
    }

    public static HttpPost getHttpPostXML(String url) {
        HttpPost httpPost = new HttpPost(url);//"https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi"
        httpPost.addHeader("Accept", "application/xml");
        //httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/xml");
        httpPost.addHeader("Content-type","application/xml; charset=utf-8");
        return httpPost;
    }


    /**
     *
     * @param orderedComponents
     * @return
     */
    public static String doRequestSign(WxPayApiConfig wxPayApiConfig, String... orderedComponents) {
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            // 商户私钥
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                    new FileInputStream(wxPayApiConfig.getKeyPath()));
            Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
            signer.initSign(merchantPrivateKey);
            final String signatureStr = createSign(true, orderedComponents);
            signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
            return Base64Utils.encodeToString(signer.sign());
        } catch (InvalidKeyException e) {
            log.error("InvalidKeyException: {}", e);
        } catch (SignatureException e) {
            log.error("SignatureException: {}", e);
        } catch (NoSuchProviderException e) {
            log.error("NoSuchProviderException: {}", e);
        } catch (NoSuchAlgorithmException e) {
            log.error("NoSuchAlgorithmException: {}", e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 请求时设置签名   组件
     * @param components the components
     * @return string string
     */
    private static String createSign(boolean newLine, String... components) {
        String suffix = newLine ? "\n" : "";
        return Arrays.stream(components).collect(Collectors.joining("\n", "", suffix));
    }

    /**
     * 公共请求
     * @param data
     * @param url
     * @param mchid
     * @param privateKey
     * @param certificate
     * @param serialNo
     * @return
     */
    public static String response(String data, String url, String mchid, String privateKey, String certificate, String serialNo, WxPayApiConfig wxPayApiConfig) {
        log.info("====>>> wxpay response, mchid: {}, serialNo: {}, url: {}, privateKey: {}, certificate: {}, data: {}",
                mchid, serialNo, url, privateKey, certificate, data);
        // ...
        HttpPost httpPost = new HttpPost(url);
        StringEntity reqEntity = new StringEntity(data, ContentType.create("application/json", "utf-8"));
        // ...
        httpPost.setEntity(reqEntity);
        httpPost.addHeader("Accept", "application/json");
        // ...
        CloseableHttpResponse response = null;
        // 返回
        String body = null;
        try {
            // 商户私钥
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
            // ...
            response = getClient(mchid, serialNo, merchantPrivateKey, certificate, wxPayApiConfig).execute(httpPost);
            log.info("====>>> wxpay response, result: {}", JSON.toJSONString(response));
            // response = httpClient.execute(httpPost);
            // assertTrue(response.getStatusLine().getStatusCode() != 401);
            int statusCode = response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            body = EntityUtils.toString(entity);
            log.info("====>>> wxpay response, success: {}, body: {}", statusCode, body);
            if (statusCode != 200) {
                @SuppressWarnings("unchecked")
                Map<String, String> errorMsg = StringHelper.string2Map(body);
                throw new CustomException(errorMsg.get("message"));
            }
            // 执行释放
            EntityUtils.consume(entity);
        } catch (CustomException e) {
            log.error("======>>> wxpay response, client exception: {}", e);
            throw new CustomException(e.getMessage(), e.getCode());
        } catch (Exception e) {
            log.error("======>>> wxpay response, exception: {}", e);
            throw new CustomException("微信请求失败,请重试(1)", e.getCause());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("======>>> wxpay response, ioe exception: {}", e);
                throw new CustomException("微信请求失败,请重试(2)", e.getCause());
            }
        }
        return body;
    }

    /**
     * 创建Client
     * @param mchid
     * @param serialNo
     * @param privateKey
     * @param certificate
     * @return
     * @throws UnsupportedEncodingException
     */
    public static CloseableHttpClient getClient(String mchid, String serialNo, PrivateKey privateKey, String certificate, WxPayApiConfig wxPayApiConfig) throws FileNotFoundException {

        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new FileInputStream("D:/mywang/wxpay/apiclient_key.pem"));

        X509Certificate wechatPayCertificate = PemUtil.loadCertificate(
                new FileInputStream("D:/mywang/wxpay/wechatpay_5BBEE5195961BEE997E2171B598E93D9297ED659.pem"));

        ArrayList<X509Certificate> wechatPayCertificates = new ArrayList<>();
        wechatPayCertificates.add(wechatPayCertificate);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(wxPayApiConfig.getMchId(), wxPayApiConfig.getMchSerialNumber(), merchantPrivateKey)
                .withWechatPay(wechatPayCertificates);
        // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
        return builder.build();

    }

    public static void micropay(WxPayApiConfig wxPayApiConfig) {
        // 初始化商户配置
        RSAConfig config =
                new RSAConfig.Builder()
                        .merchantId(wxPayApiConfig.getMchId())
                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
                        .privateKeyFromPath(wxPayApiConfig.getKeyPath())
                        .merchantSerialNumber(wxPayApiConfig.getMchSerialNumber())
                        .wechatPayCertificatesFromPath(wxPayApiConfig.getPlatformCertPath())
                        .build();
        // 初始化服务
        JsapiService  service = new JsapiService.Builder().config(config).build();

        // ... 调用接口
        try {
//            closeOrder();
        } catch (HttpException e) { // 发送HTTP请求失败
            // 调用e.getHttpRequest()获取请求打印日志或上报监控,更多方法见HttpException定义
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控,更多方法见ServiceException定义
        } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
            // 调用e.getMessage()获取信息打印日志或上报监控,更多方法见MalformedMessageException定义
        }

    }

    public static void micropay2(WxPayApiConfig wxPayApiConfig) {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(wxPayApiConfig.getMchId())
                        .privateKeyFromPath(wxPayApiConfig.getKeyPath())
                        .merchantSerialNumber(wxPayApiConfig.getMchSerialNumber())
                        .apiV3Key(wxPayApiConfig.getApiKey3())
                        .build();

        JsapiService service = new JsapiService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数,具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(100);
        request.setAmount(amount);
        request.setAppid("wxa9d9651ae******");
        request.setMchid("190000****");
        request.setDescription("测试商品标题");
        request.setNotifyUrl("https://notify_url");
        request.setOutTradeNo("out_trade_no_001");
        Payer payer = new Payer();
        payer.setOpenid("oLTPCuN5a-nBD4rAL_fa********");
        request.setPayer(payer);
        PrepayResponse response = service.prepay(request);
        System.out.println(response.getPrepayId());
    }

    /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        Map<String, String> data = new HashMap<String, String>();
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

        // 禁用XML外部实体注入
        /**
         * XXE
         * XML 外部实体注入漏洞(XML External Entity Injection,简称 XXE),
         * 是一种容易被忽视,但危害巨大的漏洞。它可以利用 XML 外部实体加载注入,
         * 执行不可预控的代码,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
         */

        /**
         * 原理:
         * 通常,我们在使用微信支付时,商家会有一个通知的 URL 来接收异步支付结果。
         * 然而,微信在 JAVA 版本的 SDK 存在一个 XXE 漏洞来处理这个结果。
         * 由此攻击者可以向通知的 URL 中构建恶意的回调数据,以便根据需要窃取商家服务器上的任意信息。
         * 一旦攻击者获得商家的关键安全密钥(md5-key 和merchant-Id),
         * 那么他们可以通过发送伪造的信息来欺骗商家而无需付费购买任意商品。
         */
        documentBuilderFactory.setExpandEntityReferences(false);
        documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
        InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
        org.w3c.dom.Document doc = documentBuilder.parse(stream);
        doc.getDocumentElement().normalize();
        NodeList nodeList = doc.getDocumentElement().getChildNodes();
        for (int idx=0; idx<nodeList.getLength(); ++idx) {
            Node node = nodeList.item(idx);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                data.put(element.getNodeName(), element.getTextContent());
            }
        }
        try {
            stream.close();
        }
        catch (Exception ex) {

        }
        return data;
    }

    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data 待签名数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (WXPayConstants.SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 生成 HMACSHA256
     * @param data 待处理数据
     * @param key 密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
}

 

SHA1

package com.example.demo.test;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Arrays;

/**
 * 基础加密组件
 * 支持SHA-1、MD5、HMAC、BASE64
 * @since 2015年12月29日
 * @author yuanliu
 */
public class SHA1 {
    /**
     * 合法时间段
     */
    private static final Long n = 5L;
    public final static String DSRIS_STD_INTERFACE_ENCODING = "UTF8";
    private static final String KEY_SHA = "SHA-1";
    private static final String KEY_MD5 = "MD5";

    /**
     * MAC算法可选以下多种算法
     * 
     * <pre>
     * HmacMD5 
     * HmacSHA1 
     * HmacSHA256 
     * HmacSHA384 
     * HmacSHA512
     * </pre>
     */
    private static final String KEY_MAC = "HmacMD5";

    /**
     * BASE64解密
     * 
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] decryptBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
     * BASE64加密
     * 
     * @param key
     * @return
     * @throws Exception
     */
    private static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
     * MD5加密
     * 
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encryptMD5(byte[] data) throws Exception {

        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
        md5.update(data);

        return md5.digest();

    }

    /**
     * SHA加密
     * 
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encryptSHA(byte[] data) throws Exception {

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
        sha.update(data);
        //增加一位,解决符号问题
        byte[] _val = sha.digest();
        byte[] val = new byte[_val.length+1];
        val[0] = 0;
        for(int i=1;i<val.length;i++){
            val[i] = _val[i-1];
        }
        return val;
    }
    public static String encryptSHA1(String timestamp,String nonce,String token) throws Exception {
        String[] arr = new String[]{timestamp,nonce,token}; 
        Arrays.sort(arr);
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
//        System.out.println(content.toString());
        String signature = org.apache.commons.codec.digest.DigestUtils.shaHex(content.toString().getBytes("UTF-8"));

        return signature;
    }
    /**
     * SHA加密
     * @param timestamp 时间戳
     * @param nonce 随机码
     * @param token 授权码
     * @return
     * @throws Exception
     */
    public static byte[]  encryptSHA(String timestamp,String nonce,String token) throws Exception {
        //
        String[] arr = new String[]{timestamp,nonce,token}; 
        Arrays.sort(arr);
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        return encryptSHA(content.toString().getBytes("UTF-8"));

    }
    /**
     * 初始化HMAC密钥
     * 
     * @return
     * @throws Exception
     */
    private static String initMacKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

        SecretKey secretKey = keyGenerator.generateKey();
        return encryptBASE64(secretKey.getEncoded());
    }

    /**
     * HMAC加密
     * 
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] encryptHMAC(byte[] data, String key) throws Exception {

        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);

        return mac.doFinal(data);

    }
    
    /**
     * 验证是否合法 验方式: 
     *         1、通过时间戳、随机码、授权码加密
     *         2、认证密钥与加密后的密文比较

     * @param signature 认证密钥
     * @param timestamp 时间戳
     * @param nonce 随机码
     * @param token 授权码
     * @return true,认证成功;false认证失败
     * 
     * 备注:
     *     因前期已对接部分单位,不能修改加解密方式;
     *     考虑各个单位开发语言不同,所以新增验证方法
     *     20180329 yuanl
     * 
     * @author yuanliu
     */
    public static boolean validToken(String signature, String timestamp, String nonce,String token) {
        try {
                String v_signature = new BigInteger(SHA1.encryptSHA(timestamp, nonce, token)).toString(64);//java
                String c_signature = SHA1.encryptSHA1(timestamp, nonce, token) ;//C#
            if (signature.equals(v_signature)) {
                return true;
            } else if (signature.equals(c_signature)){
                return true;
            }else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**  
       * 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]  
       * hexStr2ByteArr(String strIn) 互为可逆的转换过程  
       *   
       * @param arrB  
       *            需要转换的byte数组  
       * @return 转换后的字符串  
       * @throws Exception  
       *             本方法不处理任何异常,所有异常全部抛出  
       */
      public static String byteArr2HexStr(byte[] arrB) throws Exception {
        int iLen = arrB.length;
        // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍   
        StringBuffer sb = new StringBuffer(iLen * 2);
        for (int i = 0; i < iLen; i++) {
          int intTmp = arrB[i];
          // 把负数转换为正数   
          while (intTmp < 0) {
            intTmp = intTmp + 256;
          }
          // 小于0F的数需要在前面补0   
          if (intTmp < 16) {
            sb.append("0");
          }
          sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
      }

      /**  
       * 将表示16进制值的字符串转换为byte数组, 和public static String byteArr2HexStr(byte[] arrB)  
       * 互为可逆的转换过程  
       *   
       * @param strIn  
       *            需要转换的字符串  
       * @return 转换后的byte数组  
       * @throws Exception  
       *             本方法不处理任何异常,所有异常全部抛出  
       * @author <a href="mailto:leo841001@163.com">LiGuoQing</a>  
       */
      public static byte[] hexStr2ByteArr(String strIn) throws Exception {
        byte[] arrB = strIn.getBytes();
        int iLen = arrB.length;

        // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2   
        byte[] arrOut = new byte[iLen / 2];
        for (int i = 0; i < iLen; i = i + 2) {
          String strTmp = new String(arrB, i, 2);
          arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
        }
        return arrOut;
      }

    public static void main(String[] args) throws Exception {
        SHA1 SHA1=new SHA1();
        
//        byte[] a = SHA1.encryptSHA("1535098755", "7C40CAE9-CF2E-4280-AAE2-9843DA84DCE5", "14ae1d2d-cf31-4a12-a53e-215e94115232");
//        System.out.println(new BigInteger(a).toString(64));
        String timestamp="1552292054";
        String nonce="667fc15f-db3e-4484-ab0b-1dd7c900a6b8";
        String token="38bc6b85-af6c-46ff-bb3b-f8cace39ea8d";
        System.out.println(SHA1.encryptSHA1(timestamp, nonce, token));
        //System.out.println(new BigInteger(SHA1.encryptSHA(timestamp, nonce, token)).toString(64));
        //System.out.println(SHA1.validToken(oldString, "1461046490", "fdafads", "b9c0aca5-ba76-4983-9ead-34346f69d700"));
        
        StringBuffer sb = new StringBuffer();
        java.util.List<String> toSendFiles = FileUtil.getFileList("C:\\Users\\Administrator\\Desktop\\xml", ".xml");
        File file = new File(toSendFiles.get(0));
        InputStreamReader read = new InputStreamReader(
                new FileInputStream(file), "UTF-8");// 考虑到编码格式
        BufferedReader bufferedReader = new BufferedReader(read);
        String lineTxt = bufferedReader.readLine();
        while (bufferedReader.ready()) {
            lineTxt = lineTxt + bufferedReader.readLine();
        }
        sb.append(lineTxt);
        String dataMD5 = Util.EncoderByMd5("<Test>测试MD5加密</Test>");
        System.out.println(dataMD5);
    }
}

 

MD5

package com.example.demo.test;


import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class testMd51 {
    public static String EncoderByMd5(String str) {
        String result = "";
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            // ����ǹؼ�
            md5.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte b[] = md5.digest();
        int i;
        StringBuffer buf = new StringBuffer("");
        for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0)
                i += 256;
            if (i < 16)
                buf.append("0");
            buf.append(Integer.toHexString(i));
        }
        result = buf.toString();

        return result;
    }
    public static byte[] desCrypto(byte[] data, String key) {
        try{
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(key.getBytes("UTF-8"));
            //����һ���ܳ׹�����Ȼ��������DESKeySpecת����
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            //Cipher����ʵ����ɼ��ܲ���
            Cipher cipher = Cipher.getInstance("DES");
            //���ܳ׳�ʼ��Cipher����
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            //���ڣ���ȡ���ݲ�����
            //��ʽִ�м��ܲ���
            return cipher.doFinal(data);
        }catch(Throwable e){
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmsssss");
        String currdate = sf.format(new Date());
        String currdate1 = sf.format(new Date());
        System.out.println(">>currdate:"+currdate);
        System.out.println(">>currdate1:"+currdate1);

        Date date = new SimpleDateFormat("yyyy-MM-dd hh").parse("2020-08-11 09");
        System.out.println(date);

        String nonce ="dc54975f-910e-46c0-af21-19c670b22d3f";
        String token  = "6e4012f9-3167-426b-9aa3-39987a93664e";

        String test ="�����ı�123ABC_!@#$%_abc{}()+��������";
        System.out.println("�����ı���"+test);
        System.out.println("MD5:"+EncoderByMd5(test));
        String timestamp="1604459554";
        System.out.println("nonce:"+nonce);
        System.out.println("token:"+token);
//        System.out.println("currentTimeMillis:"+System.currentTimeMillis());
        System.out.println("timeStamp:"+timestamp);
        System.out.println("singnature:"+new BigInteger(encryptSHA(timestamp, nonce, token)).toString(64));
        String[] arr = new String[]{timestamp,nonce,token};
        Arrays.sort(arr);
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        System.out.println("�����:"+content);

        System.out.println("");
        byte[] bytes = desCrypto(test.getBytes("UTF-8"),token+timestamp);

        System.out.println("���ݼ���>>:"+toHex(bytes));


    }

    public static byte[]  encryptSHA(String timestamp,String nonce,String token) throws Exception {
        String[] arr = new String[]{timestamp,nonce,token};
        Arrays.sort(arr);
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        return encryptSHA(content.toString().getBytes("UTF-8"));
    }

    private static final String KEY_SHA = "SHA-1";

    public static byte[] encryptSHA(byte[] data) throws Exception {

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
        sha.update(data);
        //����һλ�������������
        byte[] _val = sha.digest();
        byte[] val = new byte[_val.length+1];
        val[0] = 0;
        for(int i=1;i<val.length;i++){
            val[i] = _val[i-1];
        }
        return val;
    }

    public static String toHex(byte[] bytes) {
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (int i=0; i<bytes.length; i++) {
            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0xf]);
            ret.append(HEX_DIGITS[bytes[i] & 0xf]);
        }
        return ret.toString();
    }

    private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();

}

 

package com.example.demo.test;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

public class DesFactory {

    private static String SIGN_ALGORITHMS ="SIGN_ALGORITHMS";
    /**
     * des 加密
     * @param data  需要加密内容
     * @param key 密令
     * @return
     */
    public static byte[] desCrypto(byte[] data, String key) {            
        try{
        SecureRandom random = new SecureRandom();
        DESKeySpec desKey = new DESKeySpec(key.getBytes("UTF-8"));
        //创建一个密匙工厂,然后用它把DESKeySpec转换成
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        //Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance("DES");
        //用密匙初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
        //现在,获取数据并加密
        //正式执行加密操作
        return cipher.doFinal(data);
        }catch(Throwable e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * des 解密
     * @param data  需要加密内容
     * @param key 密令
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, String key) throws Exception {
        try{
            // DES算法要求有一个可信任的随机数源
            SecureRandom random = new SecureRandom();
            // 创建一个DESKeySpec对象
            DESKeySpec desKey = new DESKeySpec(key.getBytes("UTF-8"));
            // 创建一个密匙工厂
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            // 将DESKeySpec对象转换成SecretKey对象
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
            // 真正开始解密操作
            return cipher.doFinal(data);
        }catch(Exception e ){
            e.printStackTrace();
            System.out.println("使用第二种解密");
            try{

                byte[] b = Base64Utils.decode(new String(data,"UTF-8")); //hexStr2ByteArr(n);
                // DES算法要求有一个可信任的随机数源
                SecureRandom random = new SecureRandom();
                // 创建一个DESKeySpec对象
                DESKeySpec desKey = new DESKeySpec(key.getBytes("UTF-8"));
                // 创建一个密匙工厂
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
                // 将DESKeySpec对象转换成SecretKey对象
                SecretKey securekey = keyFactory.generateSecret(desKey);
                // Cipher对象实际完成解密操作
                Cipher cipher = Cipher.getInstance("DES");
                // 用密匙初始化Cipher对象
                cipher.init(Cipher.DECRYPT_MODE, securekey, random);
                // 真正开始解密操作
                return cipher.doFinal(b);
            }catch(Exception e1){
                e1.printStackTrace();
            }
        }
        return null;
    }
    /**  
       * 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]  
       * hexStr2ByteArr(String strIn) 互为可逆的转换过程  
       *   
       * @param arrB  
       *            需要转换的byte数组  
       * @return 转换后的字符串  
       * @throws Exception  
       *             本方法不处理任何异常,所有异常全部抛出  
       */
      public static String byteArr2HexStr(byte[] arrB) throws Exception {
        int iLen = arrB.length;
        // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍   
        StringBuffer sb = new StringBuffer(iLen * 2);
        for (int i = 0; i < iLen; i++) {
          int intTmp = arrB[i];
          // 把负数转换为正数   
          while (intTmp < 0) {
            intTmp = intTmp + 256;
          }
          // 小于0F的数需要在前面补0   
          if (intTmp < 16) {
            sb.append("0");
          }
          sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
      }

      /**  
       * 将表示16进制值的字符串转换为byte数组, 和public static String byteArr2HexStr(byte[] arrB)  
       * 互为可逆的转换过程  
       *   
       * @param strIn  
       *            需要转换的字符串  
       * @return 转换后的byte数组  
       * @throws Exception  
       *             本方法不处理任何异常,所有异常全部抛出  
       * @author <a href="mailto:leo841001@163.com">LiGuoQing</a>  
       */
      public static byte[] hexStr2ByteArr(String strIn) throws Exception {
        byte[] arrB = strIn.getBytes("UTF-8");
        int iLen = arrB.length;

        // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2   
        byte[] arrOut = new byte[iLen / 2];
        for (int i = 0; i < iLen; i = i + 2) {
          String strTmp = new String(arrB, i, 2);
          arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
        }
        return arrOut;
      }


    /*
    * //字符串加密
    * */
    public static String encrypt(String str, String sKey,String sIv){
        String result = "";
        byte[] bKey;
        byte[] bIv;
        try {
            bKey = sKey.getBytes("utf-8");
            bIv = sIv.getBytes("utf-8");
            DESedeKeySpec keySpec=new DESedeKeySpec(bKey);
            SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("desede");
            SecretKey key=keyFactory.generateSecret(keySpec);
            Cipher cipher=Cipher.getInstance("desede/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(bIv));
            byte[] encrypted = cipher.doFinal(str.getBytes("utf-8"));
            result = new BASE64Encoder().encode(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String decrypt(String src, String sKey ,String sIv) {
        byte[] key;
        byte[] bIv;
        String result = "";
        try {
            key = sKey.getBytes("utf-8");
            bIv = sIv.getBytes("utf-8");
            IvParameterSpec iv = new IvParameterSpec(bIv);
            DESedeKeySpec desKey = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("desede");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, securekey, iv);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(src);
            result = new String(cipher.doFinal(encrypted1),"utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
      
      public static void main(String[] args) throws UnsupportedEncodingException, Exception {
            String timestamp = "1531382430000"; // 时间戳 String
            String nonce = "91b9a8bd6b174fee833a5ef5cc60d0be"; // 随机定义一随机码 String token =
            String token  = "c1e89908-d565-44f3-ab7e-614d47240292";//"53cce612-dfd2-4956-a19b-7f6407c3368d";//"612c219c-9c7d-40fe-a6f7-990aad14ef01";
            String userName="rmyy5";//appDataTest zzsdlrmyy
            String passWord = "88888888";
            System.out.println(passWord);
            // 调用接口方法进行SHA加密
            //String signature = new BigInteger(SHA1.encryptSHA(timestamp, nonce, token)).toString(64);
            //System.out.println("-------:"+signature);
            String signature = SHA1.encryptSHA1(timestamp, nonce, token);
            System.out.println(">>signature:"+signature);
            
    }
}

 

package com.example.demo.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;
import java.util.Base64;
/** *//** 
 * <p> 
 * BASE64������빤�߰� 
 * </p> 
 * <p> 
 * ����javabase64-1.3.1.jar 
 * </p> 
 *  
 * @author IceWee 
 * @date 2012-5-19 
 * @version 1.0 
 */  
public class Base64Utils {  
  
    /** *//** 
     * �ļ���ȡ��������С 
     */  
    private static final int CACHE_SIZE = 1024;  
      
    /** *//** 
     * <p> 
     * BASE64�ַ�������Ϊ���������� 
     * </p> 
     *  
     * @param base64 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decode(String base64) throws Exception {
        final Base64.Decoder decoder = Base64.getDecoder();
        return decoder.decode(base64);
    }  
      
    /** *//** 
     * <p> 
     * ���������ݱ���ΪBASE64�ַ��� 
     * </p> 
     *  
     * @param bytes 
     * @return 
     * @throws Exception 
     */  
    public static String encode(byte[] bytes) throws Exception {
        final Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(bytes);
    }  
      
    /** *//** 
     * <p> 
     * ���ļ�����ΪBASE64�ַ��� 
     * </p> 
     * <p> 
     * ���ļ����ã����ܻᵼ���ڴ���� 
     * </p> 
     *  
     * @param filePath �ļ�����·�� 
     * @return 
     * @throws Exception 
     */  
    public static String encodeFile(String filePath) throws Exception {  
        byte[] bytes = fileToByte(filePath);  
        return encode(bytes);  
    }  
      
    /** *//** 
     * <p> 
     * BASE64�ַ���ת���ļ� 
     * </p> 
     *  
     * @param filePath �ļ�����·�� 
     * @param base64 �����ַ��� 
     * @throws Exception 
     */  
    public static void decodeToFile(String filePath, String base64) throws Exception {  
        byte[] bytes = decode(base64);  
        byteArrayToFile(bytes, filePath);  
    }  
      
    /** *//** 
     * <p> 
     * �ļ�ת��Ϊ���������� 
     * </p> 
     *  
     * @param filePath �ļ�·�� 
     * @return 
     * @throws Exception 
     */  
    public static byte[] fileToByte(String filePath) throws Exception {  
        byte[] data = new byte[0];  
        File file = new File(filePath);  
        if (file.exists()) {  
            FileInputStream in = new FileInputStream(file);  
            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);  
            byte[] cache = new byte[CACHE_SIZE];  
            int nRead = 0;  
            while ((nRead = in.read(cache)) != -1) {  
                out.write(cache, 0, nRead);  
                out.flush();  
            }  
            out.close();  
            in.close();  
            data = out.toByteArray();  
         }  
        return data;  
    }  
      
    /** *//** 
     * <p> 
     * ����������д�ļ� 
     * </p> 
     *  
     * @param bytes ���������� 
     * @param filePath �ļ�����Ŀ¼ 
     */  
    public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {  
        InputStream in = new ByteArrayInputStream(bytes);     
        File destFile = new File(filePath);  
        if (!destFile.getParentFile().exists()) {  
            destFile.getParentFile().mkdirs();  
        }  
        destFile.createNewFile();  
        OutputStream out = new FileOutputStream(destFile);  
        byte[] cache = new byte[CACHE_SIZE];  
        int nRead = 0;  
        while ((nRead = in.read(cache)) != -1) {     
            out.write(cache, 0, nRead);  
            out.flush();  
        }  
        out.close();  
        in.close();  
    }  
      
      
}