package com.zsElectric.boot.core.pay.swiftpass.util;

import com.zsElectric.boot.core.pay.swiftpass.config.SwiftpassConfig;
import org.apache.commons.codec.binary.Base64;

import java.util.*;


/**
 * @author zeming.fan@swiftpass.cn
 *
 */
public class SignUtil {
	
	//请求时根据不同签名方式去生成不同的sign
    public static String getSign(String signType, String preStr, SwiftpassConfig sw){
    	if("RSA_1_256".equals(signType)){
        	try {
        		return SignUtil.sign(preStr,"RSA_1_256",sw.getMchPrivateKey());
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
        }else{
        	return MD5.sign(preStr, "&key=" + sw.getKey(), "utf-8");
        }
    	return null;
    }
    
    //对返回参数的验证签名
    public static boolean verifySign(String sign,String signType,Map<String,String> resultMap,SwiftpassConfig sw) throws Exception{
    	System.out.println("签名方式："+signType);
    	System.out.println("签名："+sign);
    	System.out.println("返回的结果："+resultMap);
    	System.out.println("签名公钥："+sw.getPlatPublicKey());
    	if("RSA_1_256".equals(signType)){
    		Map<String,String> Reparams = SignUtils.paraFilter(resultMap);
            StringBuilder Rebuf = new StringBuilder((Reparams.size() +1) * 10);
            SignUtils.buildPayParams(Rebuf,Reparams,false);
            String RepreStr = Rebuf.toString();
            if(SignUtil.verifySign(RepreStr,sign, signType,sw.getPlatPublicKey())){
            	System.out.println("已经验证了签名，且验证通过");
            	return true;
            }
    	}else if("MD5".equals(signType)){
    		if(SignUtils.checkParam(resultMap, sw.getKey())){
    			return true;
    		}
    	}
    	return false;
    }
	public static boolean verifySign(String preStr,String sign,String signType, String platPublicKey) throws Exception {
		// 调用这个函数前需要先判断是MD5还是RSA
		// 商户的验签函数要同时支持MD5和RSA
		RSAUtil.SignatureSuite suite = null;
		
		if ("RSA_1_1".equals(signType)) {
			suite = RSAUtil.SignatureSuite.SHA1;
		} else if ("RSA_1_256".equals(signType)) {
			suite = RSAUtil.SignatureSuite.SHA256;
		} else {
			throw new Exception("不支持的签名方式");
		}
        
		boolean result = RSAUtil.verifySign(suite, preStr.getBytes("UTF8"), Base64.decodeBase64(sign.getBytes("UTF8")),
                platPublicKey);
        
		return result;
    }

    public static String sign(String preStr, String signType, String mchPrivateKey) throws Exception {
		RSAUtil.SignatureSuite suite = null;
		if ("RSA_1_1".equals(signType)) {
			suite = RSAUtil.SignatureSuite.SHA1;
		} else if ("RSA_1_256".equals(signType)) {
			suite = RSAUtil.SignatureSuite.SHA256;
		} else {
			throw new Exception("不支持的签名方式");
		}
        byte[] signBuf = RSAUtil.sign(suite, preStr.getBytes("UTF8"),
                mchPrivateKey);
        return new String(Base64.encodeBase64(signBuf), "UTF8");
    }
    
    public static void main(String[] args) throws Exception {

    	String xml = "<xml><attach><![CDATA[支付人匿名]]></attach>\n" +
				"<body><![CDATA[购票]]></body>\n" +
				"<charset><![CDATA[UTF-8]]></charset>\n" +
				"<is_minipg><![CDATA[1]]></is_minipg>\n" +
				"<is_raw><![CDATA[1]]></is_raw>\n" +
				"<mch_create_ip><![CDATA[172.16.0.25]]></mch_create_ip>\n" +
				"<mch_id><![CDATA[105550131844]]></mch_id>\n" +
				"<nonce_str><![CDATA[1706770173138]]></nonce_str>\n" +
				"<notify_url><![CDATA[http://120.78.228.211:8880/orderApi/enditPay]]></notify_url>\n" +
				"<out_trade_no><![CDATA[zp_ticket_pay_45]]></out_trade_no>\n" +
				"<service><![CDATA[pay.weixin.jspay]]></service>\n" +
				"<sign><![CDATA[OG5GZktLKUjGx4+QkqM35r19oiiEtnUeK0ug7dmAjas+USMfdQLUOpbQzVIVPb1drwj8kfeqAXvYpLCbc0oRuGGeSe0fPD3YBN7YA+lrj7fHTcuiaov4jFkz2F/GQF3r6mCVCoNeev/c1P0TGgp1w8CxzDAn+asCzQRaO74WqD6gggCN7m5OqSAots2r1Cm13OGi41Z2MCaahtxLuAT/T+qNP7idfYUYw/MooV3dzmUBEjyZHmgPpKAD1VpPVLwaQTeQblfSWoOkNLXnyTEPINDtVfeFdgBZlYssIy6cPT2Sxh7ZRPjgaXjYDQPUsnfX/r8IvhuAg7MtTk1/Z5kcMQ==]]></sign>\n" +
				"<sign_type><![CDATA[RSA_1_256]]></sign_type>\n" +
				"<sub_appid><![CDATA[wx80f7a21fbbe7980c]]></sub_appid>\n" +
				"<sub_openid><![CDATA[oUCV765SRSydZ2PMlmMzOKvvjv6M]]></sub_openid>\n" +
				"<total_fee><![CDATA[1]]></total_fee>\n" +
				"<version><![CDATA[2.0]]></version>\n" +
				"</xml>";

		//解析xml成map
		Map<String, String> m = new HashMap<String, String>();
		//log.info("获取到xml"+sb);
		System.out.println("开始解析xml");
		m = XmlUtils.toMap(xml.toString().getBytes(), "utf-8");
		System.out.println("已经解析过了xml");

		//过滤空 设置 TreeMap
		SortedMap<Object,Object> packageParams = new TreeMap<Object, Object>();
		Iterator it = m.keySet().iterator();
		while (it.hasNext()) {
			String parameter = (String) it.next();
			String parameterValue = m.get(parameter);

			String v = "";
			if(null != parameterValue) {
				v = parameterValue.trim();
			}
			packageParams.put(parameter, v);
		}

		Map<String,String> Reparams = SignUtils.paraFilter((TreeMap)packageParams);
		StringBuilder Rebuf = new StringBuilder((Reparams.size() +1) * 10);
		SignUtils.buildPayParams(Rebuf,Reparams,false);
		String RepreStr = Rebuf.toString();
		String sign = "OG5GZktLKUjGx4+QkqM35r19oiiEtnUeK0ug7dmAjas+USMfdQLUOpbQzVIVPb1drwj8kfeqAXvYpLCbc0oRuGGeSe0fPD3YBN7YA+lrj7fHTcuiaov4jFkz2F/GQF3r6mCVCoNeev/c1P0TGgp1w8CxzDAn+asCzQRaO74WqD6gggCN7m5OqSAots2r1Cm13OGi41Z2MCaahtxLuAT/T+qNP7idfYUYw/MooV3dzmUBEjyZHmgPpKAD1VpPVLwaQTeQblfSWoOkNLXnyTEPINDtVfeFdgBZlYssIy6cPT2Sxh7ZRPjgaXjYDQPUsnfX/r8IvhuAg7MtTk1/Z5kcMQ==";
		String platPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtO+txxud/Tn8CZtcDCutWk1CNFSKzH7Mtpaplq8rm6pGPuUjUC4TMApnDPhLKPD8klF/Y1KPN1wMcvyV3CmUk0etPzqaeXmOP4rsPe9YCBmFtJTEfpTW+5/mM0r5rm9nDjXpcQJWghc3XnWDRUlJwcWgv5oVYsHgCyFv1Lz82A1B9Yjf6f2bd9NCHA3Fc3+xfTHQnOU1LcaLppHhJ8X/JyLCAJkhoZ2W8Ils81pSDqIGnvVxxjOmNCPzeOCfe73F/CJbOpcb2j47ws+p/KmM/xaSaFrhyxFT0PdMwpOTnCrgC6dJFgqdPAPFOJLMqzUG9YX2+o02XNs1Dq+UCLwTnwIDAQAB";
		System.out.println(verifySign(RepreStr, sign, "RSA_1_256", platPublicKey));

		//    	String preStr = "attach=支付人匿名&body=购票&charset=UTF-8&is_minipg=1&is_raw=1&mch_create_ip=172.16.0.25&mch_id=105550131844&nonce_str=1706757253245&notify_url=http://120.78.228.211:8880/orderApi/enditPay&out_trade_no=zp_ticket_pay_43&service=pay.weixin.jspay&sign=B+CxGl13bnD1yJylWJI/uJNN9Xd0TZ1GR0eQdXL9BByzIWCU4wJofmJfVRTTygo9Asisi1ey0BTwwtLsNJr1uXBKLvodEKp8rAxgm8hRAmy82F6KjjDQtQ4VORDWGHtoAECs2RNcSnsXUtggVj5lO4o0DceYuyPbnGPDI/oCHNbDt9LNQ0FMRKP0LbOFVwaa064qYTyI70xXsl2U/Rh2z5zjIf5CT06evL/r7yDc9psvg4yK39NUu53cajr5P5WnYw2Pxw1VdQbX9vwkhkC1veBRyh3e+2LUDtQ0g+4Ph2b0Z1UOlpVnX6yNp3tND5EkBQX4eC/xks7jgHXaz557XQ==&sign_type=RSA_1_256&sub_appid=wx80f7a21fbbe7980c&sub_openid=oUCV765SRSydZ2PMlmMzOKvvjv6M&total_fee=1&version=2.0";
//    	String platPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlxmhbZBDvQt4ZVLXyAU8JMyvu0sNgdft4qAdS+c+spN1u1sewQf7d7CuMxFZqaprJboAUaCJN/7V/4wYBerDzXzqXzPuGvFV00GDYtRezVe8VJBfgpvmaNK8cq2pqaUVAxPFJJ9Nl/YTc4gaD38m+CYpopRP70Fgrq7BT4eGuak5Rpb50ICQ0yopex3yV8zS99EkgNeeI66K6Xgp3oQKs8YP6oig5NJrhc2Ct+aXxuYUHUzdDByetXtXYJmWlx5SBRfYYHWt/L6w8XUb3EUTUob9wLpMgbWJGDWFqXrSQagjKVo7vzcHXL4LsbIK7OPO3k7oOI8aPdgLbPCP0/cjkQIDAQAB";
//    	String sign = "B+CxGl13bnD1yJylWJI/uJNN9Xd0TZ1GR0eQdXL9BByzIWCU4wJofmJfVRTTygo9Asisi1ey0BTwwtLsNJr1uXBKLvodEKp8rAxgm8hRAmy82F6KjjDQtQ4VORDWGHtoAECs2RNcSnsXUtggVj5lO4o0DceYuyPbnGPDI/oCHNbDt9LNQ0FMRKP0LbOFVwaa064qYTyI70xXsl2U/Rh2z5zjIf5CT06evL/r7yDc9psvg4yK39NUu53cajr5P5WnYw2Pxw1VdQbX9vwkhkC1veBRyh3e+2LUDtQ0g+4Ph2b0Z1UOlpVnX6yNp3tND5EkBQX4eC/xks7jgHXaz557XQ==";
//    	System.out.println(verifySign(preStr, sign, "RSA_1_256", platPublicKey));
	}
}
