generated from root/miduo_server
小七0.1新渠道
parent
19b8c84ba4
commit
cff0ee7a9c
|
@ -18,6 +18,7 @@ import java.util.*;
|
||||||
* 爱玩游戏支付
|
* 爱玩游戏支付
|
||||||
* @author hj
|
* @author hj
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class AiWanRechargeController {
|
public class AiWanRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* 安久
|
* 安久
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class AnJiuRechargeController {
|
public class AnJiuRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.TreeMap;
|
||||||
* @date 2021/6/8
|
* @date 2021/6/8
|
||||||
* @discribe 草花支付接口
|
* @discribe 草花支付接口
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class CHGnRechargeController {
|
public class CHGnRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.TreeMap;
|
||||||
/**
|
/**
|
||||||
* 多游游戏支付
|
* 多游游戏支付
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class DuoYouRechargeController {
|
public class DuoYouRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class DyRechargeController {
|
public class DyRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* 浩凡游戏
|
* 浩凡游戏
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class HaoFanRechargeController {
|
public class HaoFanRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* 好游戏
|
* 好游戏
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class HaoGameRechargeController {
|
public class HaoGameRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* KT游戏
|
* KT游戏
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class KTGameRechargeController {
|
public class KTGameRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.*;
|
||||||
* @date 2021/3/15
|
* @date 2021/3/15
|
||||||
* @discribe 国内先遣
|
* @discribe 国内先遣
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class MHTGnWebRechargeController {
|
public class MHTGnWebRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.*;
|
||||||
* time 平台支付时间
|
* time 平台支付时间
|
||||||
* sign 签名
|
* sign 签名
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class MHTHwNetRechargeController {
|
public class MHTHwNetRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.*;
|
||||||
* time 平台支付时间
|
* time 平台支付时间
|
||||||
* sign 签名
|
* sign 签名
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class MHTHwRechargeController {
|
public class MHTHwRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.*;
|
||||||
* time 平台支付时间
|
* time 平台支付时间
|
||||||
* sign 签名
|
* sign 签名
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class MHTRechargeController {
|
public class MHTRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
* @date 2021/6/8
|
* @date 2021/6/8
|
||||||
* @discribe
|
* @discribe
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class MHTZFGnRechargeController extends MHTGnWebRechargeController {
|
public class MHTZFGnRechargeController extends MHTGnWebRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* 乾游支付回调
|
* 乾游支付回调
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class QYGameRechargeController {
|
public class QYGameRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.io.StringReader;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class QuickRechargeController {
|
public class QuickRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.io.StringReader;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class QuickRechargeController2 {
|
public class QuickRechargeController2 {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class RechargeController {
|
public class RechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.jmfy.controller;
|
||||||
|
|
||||||
|
import com.jmfy.paramBean.PaySdkEnum;
|
||||||
|
import com.jmfy.util.JsonUtil;
|
||||||
|
import com.jmfy.util.MD5Util;
|
||||||
|
import com.jmfy.util.SignSerialization;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自在封神游戏
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class U1GameRechargeController {
|
||||||
|
|
||||||
|
private static final String PAY_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKRZpZWZJIjEy/MDlwPijq9dTVLoXpQaLlSYfzgAEBtO/5zVgtED/2r0mSrMCY561/cY7tw/FkI5ywJ+HcR+OZ4ch/05J8LMnRqFQJTyoytzR4r9mMOTq5LlMianUYLJcoTeNCLdb5qMeuLYe/8B/8Q1PAUFmxIs5yz/gPZlqWVxAgMBAAECgYAwvt4b5tYtMqGDLHdoEZRccwHyKzWSG8nOEYT6KRqd3up1q+Ym9FaXdIDRbr8O4WSYx25hKN0DO3z4+kr98qpHv0DJLVQlg/9QHfPcprP6vXKMXwf1OMkI4k7m1IwZUp2N/MNBH0WfMnWdqkZlINysbr6wK+kkwnz5q7tS/vOkeQJBANdQFSaKVmHCUWDV3Ndr0/bSphDEIZjn9c7RS86pz19ZPaeyy1le5AqvHRZB9WyMy3j8o9RzBz1oJQniyvwUAGcCQQDDaDVuqAcIQKQ/1lZMQNTfc8pTvL0nHhivILObUq0wUr6VE46+h9fhAUSJCptOrPtghDHFl5xdSRWYJl1tw2RnAkBRhDQ9vyotINCGhPFzbZN2YxIUTu0ZYtihUIQO3iNwyeyZzQtH7rEPinTMtHQigLuYNq4gBNy81u0O7RpEjZ4JAkEAidWz+v4jF7shILZ74QXKImR2z2JOuo0MNFwI1QMYjwGO1XEaO2Nu75QJV/FXY8O4/XfB8/LhpRusU8qcFJTC+QJAcWOeo2ZFf0E6EOmjfbTVdhUybCKuLdW16MHg0MoRulKdYSKKNZCd5u4BUAQCRLLeo2hTYXUHVdSgG5AnM4oqpA==";
|
||||||
|
|
||||||
|
public static final String NOTIFY_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHaFanJLyR4PsHRGIImpX6w7zsA9s3rCcos6kwZit5WMiJA3f1KQf8u+u9wj5OWjPjSkir6YsxVyp1iu+a6yaWvrTe0OW3TLMPIcZog0HDfyet8+flvxbbXQpvG2itr8hoGQTfjMWM5AzghTXN8IbfwrYVr39ebbW8yG1wcxBr/QIDAQAB";
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(U1GameRechargeController.class);
|
||||||
|
|
||||||
|
@RequestMapping(value = "/u1gameCallback")
|
||||||
|
public String u1gameCallback(HttpServletRequest request) throws Exception {
|
||||||
|
return callback(request, NOTIFY_PUBLIC_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/u1gameGetSign")
|
||||||
|
public String u1gameGetSign(HttpServletRequest request) throws Exception {
|
||||||
|
// SignSerialization为ICC SDK 工具类(游戏接入方可直接使用)
|
||||||
|
SignSerialization signSerialization = new SignSerialization();
|
||||||
|
signSerialization.setPrivateKey(PAY_PRIVATE_KEY);
|
||||||
|
// 游戏客户端传递过来的订单ID等信息
|
||||||
|
String productID = request.getParameter("productID");
|
||||||
|
// 游戏支付业务编号(游戏标识),有且唯一,请在SDK提供的密钥文件下readme.txt中查看
|
||||||
|
String service = "21930001";
|
||||||
|
/*
|
||||||
|
* 模拟游戏客户端传递过来的支付下单数据
|
||||||
|
* 下单数据示例:
|
||||||
|
* comment:游戏扩展数据,支付完成回调时,会完整返回给游戏服务端
|
||||||
|
* content:[{"id":"game.onegold","name":"onegold","count":1,"price":100}] -> 内容只允许数字、英文字母、中文,不允许出现空格等其他特殊字符
|
||||||
|
* game_user_id:123456789 -> iccgame sdk 用户唯一标识
|
||||||
|
* notify_url:http://game-server.com/PayNotifyVerify.jsp -> 游戏服务器充值回调地址
|
||||||
|
* out_trade_no:20220509XXXXXXXX -> 游戏订单号
|
||||||
|
* service : 21930001 -> 游戏唯一支付业务标识,请在SDK提供的密钥文件下readme.txt中查看
|
||||||
|
* total_fee : 100 -> 充值额度(以分为单位,必须为整数)
|
||||||
|
*/
|
||||||
|
signSerialization.setItem("comment", request.getParameter("comment"));
|
||||||
|
// 注:一般游戏商品表会配置在服务端,可根据游戏客户端传递的商品ID寻找到商品详情,如:商品名、商品价格等
|
||||||
|
signSerialization.setItem("content", request.getParameter("content"));
|
||||||
|
signSerialization.setItem("game_user_id", request.getParameter("game_user_id"));
|
||||||
|
signSerialization.setItem("notify_url", "游戏服务器回调地址");
|
||||||
|
signSerialization.setItem("out_trade_no", productID);
|
||||||
|
signSerialization.setItem("service", service);
|
||||||
|
signSerialization.setItem("total_fee", request.getParameter("total_fee"));
|
||||||
|
// 调用serialize函数对参数升序排列并进行URLEncoder,参数串进行RSA签名,,签名串也做URLEncoder,将
|
||||||
|
// 将当前订单签名数据,返回给“游戏客户端”
|
||||||
|
return signSerialization.serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调
|
||||||
|
*/
|
||||||
|
public static String callback(HttpServletRequest request, String payKey) throws Exception {
|
||||||
|
HashMap<String, String> parameterMap = JsonUtil.getInstence().getParameterMap2(request);
|
||||||
|
if (parameterMap.isEmpty()) {
|
||||||
|
LOGGER.info("u1game---> callback data is null");
|
||||||
|
return "data is null";
|
||||||
|
}
|
||||||
|
boolean sign = verifySign(parameterMap, payKey);
|
||||||
|
if (!sign) {
|
||||||
|
LOGGER.info("u1game---> sign error");
|
||||||
|
return "sign error";
|
||||||
|
}
|
||||||
|
|
||||||
|
String order = parameterMap.get("out_trade_no"); // 支付订单号 唯一
|
||||||
|
int amount = Integer.parseInt(parameterMap.get("total_fee")); // 充值金额 分
|
||||||
|
String gameExt = request.getParameter("comment"); //透传参数
|
||||||
|
String[] callback = gameExt.split("_");
|
||||||
|
return PayLogic.initOrder(gameExt, order, String.valueOf(amount), new Date(), callback[0], PaySdkEnum.U1GAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证sign
|
||||||
|
*/
|
||||||
|
public static boolean verifySign(Map<String, String> map, String payKey) throws Exception {
|
||||||
|
// SDK服务端通过HTTP传递过来的支付订单信息
|
||||||
|
String data = map.get("data");
|
||||||
|
// SignSerialization为ICC SDK 工具类(游戏接入方可直接使用)
|
||||||
|
// 调用unserialize函数对参数进行反序列化并URLDecoder,调用setPublicKey函数设置登录公钥
|
||||||
|
// 调用verify函数验签可返回boolean类型,根据结果去重组游戏客户端需要的数据
|
||||||
|
SignSerialization signSerialization = SignSerialization.unserialize(data);
|
||||||
|
signSerialization.setPublicKey(payKey);
|
||||||
|
return signSerialization.verify();
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import java.util.HashMap;
|
||||||
* @date 2021/6/9
|
* @date 2021/6/9
|
||||||
* @discribe 喜扑专服
|
* @discribe 喜扑专服
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class XPRechargeController {
|
public class XPRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* @discribe 喜扑ios
|
* @discribe 喜扑ios
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class XPiosRechargeController {
|
public class XPiosRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.jmfy.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小七0.1游戏
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class XqTenthRechargeController {
|
||||||
|
|
||||||
|
private static final String PAYKEY = "0370457c8e8f12489b7568b60ef85b61";
|
||||||
|
|
||||||
|
@RequestMapping(value = "/Web/xqTenthCallback")
|
||||||
|
public String xqTenthCallback(HttpServletRequest request) throws Exception {
|
||||||
|
return YouGuRechargeController.callback(request, PAYKEY);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,10 +32,6 @@ public class YouGuRechargeController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回调
|
* 回调
|
||||||
* @param request
|
|
||||||
* @param payKey
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public static String callback(HttpServletRequest request, String payKey) throws IOException {
|
public static String callback(HttpServletRequest request, String payKey) throws IOException {
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Map;
|
||||||
/**
|
/**
|
||||||
* 悠谷游戏
|
* 悠谷游戏
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class YouGuXQRechargeController {
|
public class YouGuXQRechargeController {
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@Deprecated
|
||||||
@RestController
|
@RestController
|
||||||
public class YxylRechargeController {
|
public class YxylRechargeController {
|
||||||
@Resource
|
@Resource
|
||||||
|
|
|
@ -21,6 +21,7 @@ public enum PaySdkEnum {
|
||||||
ANJIU(11, "ANJIU"),
|
ANJIU(11, "ANJIU"),
|
||||||
YOUGU(12,"YOUGU"),
|
YOUGU(12,"YOUGU"),
|
||||||
FENGTI(13,"FENGTI"),
|
FENGTI(13,"FENGTI"),
|
||||||
|
U1GAME(14, "U1GAME")
|
||||||
;
|
;
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The MobileSecurePay Project
|
||||||
|
* All right reserved.
|
||||||
|
* author: shiqun.shi@alipay.com
|
||||||
|
*/
|
||||||
|
package com.jmfy.util;
|
||||||
|
|
||||||
|
public final class Base64 {
|
||||||
|
|
||||||
|
static private final int BASELENGTH = 128;
|
||||||
|
static private final int LOOKUPLENGTH = 64;
|
||||||
|
static private final int TWENTYFOURBITGROUP = 24;
|
||||||
|
static private final int EIGHTBIT = 8;
|
||||||
|
static private final int SIXTEENBIT = 16;
|
||||||
|
static private final int FOURBYTE = 4;
|
||||||
|
static private final int SIGN = -128;
|
||||||
|
static private final char PAD = '=';
|
||||||
|
static private final boolean fDebug = false;
|
||||||
|
static final private byte[] base64Alphabet = new byte[BASELENGTH];
|
||||||
|
static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < BASELENGTH; ++i) {
|
||||||
|
base64Alphabet[i] = -1;
|
||||||
|
}
|
||||||
|
for (int i = 'Z'; i >= 'A'; i--) {
|
||||||
|
base64Alphabet[i] = (byte) (i - 'A');
|
||||||
|
}
|
||||||
|
for (int i = 'z'; i >= 'a'; i--) {
|
||||||
|
base64Alphabet[i] = (byte) (i - 'a' + 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = '9'; i >= '0'; i--) {
|
||||||
|
base64Alphabet[i] = (byte) (i - '0' + 52);
|
||||||
|
}
|
||||||
|
|
||||||
|
base64Alphabet['+'] = 62;
|
||||||
|
base64Alphabet['/'] = 63;
|
||||||
|
|
||||||
|
for (int i = 0; i <= 25; i++) {
|
||||||
|
lookUpBase64Alphabet[i] = (char) ('A' + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 26, j = 0; i <= 51; i++, j++) {
|
||||||
|
lookUpBase64Alphabet[i] = (char) ('a' + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 52, j = 0; i <= 61; i++, j++) {
|
||||||
|
lookUpBase64Alphabet[i] = (char) ('0' + j);
|
||||||
|
}
|
||||||
|
lookUpBase64Alphabet[62] = (char) '+';
|
||||||
|
lookUpBase64Alphabet[63] = (char) '/';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isWhiteSpace(char octect) {
|
||||||
|
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPad(char octect) {
|
||||||
|
return (octect == PAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isData(char octect) {
|
||||||
|
return (octect < BASELENGTH && base64Alphabet[octect] != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes hex octects into Base64
|
||||||
|
*
|
||||||
|
* @param binaryData Array containing binaryData
|
||||||
|
* @return Encoded Base64 array
|
||||||
|
*/
|
||||||
|
public static String encode(byte[] binaryData) {
|
||||||
|
|
||||||
|
if (binaryData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lengthDataBits = binaryData.length * EIGHTBIT;
|
||||||
|
if (lengthDataBits == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
|
||||||
|
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
|
||||||
|
int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
|
||||||
|
char encodedData[] = null;
|
||||||
|
|
||||||
|
encodedData = new char[numberQuartet * 4];
|
||||||
|
|
||||||
|
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
|
||||||
|
|
||||||
|
int encodedIndex = 0;
|
||||||
|
int dataIndex = 0;
|
||||||
|
if (fDebug) {
|
||||||
|
System.out.println("number of triplets = " + numberTriplets);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < numberTriplets; i++) {
|
||||||
|
b1 = binaryData[dataIndex++];
|
||||||
|
b2 = binaryData[dataIndex++];
|
||||||
|
b3 = binaryData[dataIndex++];
|
||||||
|
|
||||||
|
if (fDebug) {
|
||||||
|
System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
|
||||||
|
}
|
||||||
|
|
||||||
|
l = (byte) (b2 & 0x0f);
|
||||||
|
k = (byte) (b1 & 0x03);
|
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
|
||||||
|
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
|
||||||
|
byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
|
||||||
|
|
||||||
|
if (fDebug) {
|
||||||
|
System.out.println("val2 = " + val2);
|
||||||
|
System.out.println("k4 = " + (k << 4));
|
||||||
|
System.out.println("vak = " + (val2 | (k << 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
|
||||||
|
}
|
||||||
|
|
||||||
|
// form integral number of 6-bit groups
|
||||||
|
if (fewerThan24bits == EIGHTBIT) {
|
||||||
|
b1 = binaryData[dataIndex];
|
||||||
|
k = (byte) (b1 & 0x03);
|
||||||
|
if (fDebug) {
|
||||||
|
System.out.println("b1=" + b1);
|
||||||
|
System.out.println("b1<<2 = " + (b1 >> 2));
|
||||||
|
}
|
||||||
|
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
|
||||||
|
encodedData[encodedIndex++] = PAD;
|
||||||
|
encodedData[encodedIndex++] = PAD;
|
||||||
|
} else if (fewerThan24bits == SIXTEENBIT) {
|
||||||
|
b1 = binaryData[dataIndex];
|
||||||
|
b2 = binaryData[dataIndex + 1];
|
||||||
|
l = (byte) (b2 & 0x0f);
|
||||||
|
k = (byte) (b1 & 0x03);
|
||||||
|
|
||||||
|
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
|
||||||
|
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
|
||||||
|
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
|
||||||
|
encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
|
||||||
|
encodedData[encodedIndex++] = PAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(encodedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes Base64 data into octects
|
||||||
|
*
|
||||||
|
* @param encoded string containing Base64 data
|
||||||
|
* @return Array containind decoded data.
|
||||||
|
*/
|
||||||
|
public static byte[] decode(String encoded) {
|
||||||
|
|
||||||
|
if (encoded == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] base64Data = encoded.toCharArray();
|
||||||
|
// remove white spaces
|
||||||
|
int len = removeWhiteSpace(base64Data);
|
||||||
|
|
||||||
|
if (len % FOURBYTE != 0) {
|
||||||
|
return null;//should be divisible by four
|
||||||
|
}
|
||||||
|
|
||||||
|
int numberQuadruple = (len / FOURBYTE);
|
||||||
|
|
||||||
|
if (numberQuadruple == 0) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte decodedData[] = null;
|
||||||
|
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
|
||||||
|
char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int encodedIndex = 0;
|
||||||
|
int dataIndex = 0;
|
||||||
|
decodedData = new byte[(numberQuadruple) * 3];
|
||||||
|
|
||||||
|
for (; i < numberQuadruple - 1; i++) {
|
||||||
|
|
||||||
|
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
|
||||||
|
|| !isData((d3 = base64Data[dataIndex++]))
|
||||||
|
|| !isData((d4 = base64Data[dataIndex++]))) {
|
||||||
|
return null;
|
||||||
|
}//if found "no data" just return null
|
||||||
|
|
||||||
|
b1 = base64Alphabet[d1];
|
||||||
|
b2 = base64Alphabet[d2];
|
||||||
|
b3 = base64Alphabet[d3];
|
||||||
|
b4 = base64Alphabet[d4];
|
||||||
|
|
||||||
|
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
|
||||||
|
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
|
||||||
|
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
|
||||||
|
return null;//if found "no data" just return null
|
||||||
|
}
|
||||||
|
|
||||||
|
b1 = base64Alphabet[d1];
|
||||||
|
b2 = base64Alphabet[d2];
|
||||||
|
|
||||||
|
d3 = base64Data[dataIndex++];
|
||||||
|
d4 = base64Data[dataIndex++];
|
||||||
|
if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
|
||||||
|
if (isPad(d3) && isPad(d4)) {
|
||||||
|
if ((b2 & 0xf) != 0)//last 4 bits should be zero
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] tmp = new byte[i * 3 + 1];
|
||||||
|
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
|
||||||
|
tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
|
||||||
|
return tmp;
|
||||||
|
} else if (!isPad(d3) && isPad(d4)) {
|
||||||
|
b3 = base64Alphabet[d3];
|
||||||
|
if ((b3 & 0x3) != 0)//last 2 bits should be zero
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] tmp = new byte[i * 3 + 2];
|
||||||
|
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
|
||||||
|
tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
|
||||||
|
tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
|
||||||
|
return tmp;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else { //No PAD e.g 3cQl
|
||||||
|
b3 = base64Alphabet[d3];
|
||||||
|
b4 = base64Alphabet[d4];
|
||||||
|
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
|
||||||
|
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
|
||||||
|
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return decodedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove WhiteSpace from MIME containing encoded Base64 data.
|
||||||
|
*
|
||||||
|
* @param data the byte array of base64 data (with WS)
|
||||||
|
* @return the new length
|
||||||
|
*/
|
||||||
|
private static int removeWhiteSpace(char[] data) {
|
||||||
|
if (data == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count characters that's not whitespace
|
||||||
|
int newSize = 0;
|
||||||
|
int len = data.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (!isWhiteSpace(data[i])) {
|
||||||
|
data[newSize++] = data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newSize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.jmfy.util;
|
||||||
|
|
||||||
|
import java.security.KeyFactory;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
|
||||||
|
public class RSA {
|
||||||
|
|
||||||
|
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA签名
|
||||||
|
*
|
||||||
|
* @param content 待签名数据
|
||||||
|
* @param private_key 商户私钥
|
||||||
|
* @param input_charset 编码格式
|
||||||
|
* @return 签名值
|
||||||
|
*/
|
||||||
|
public static String sign(String content, String private_key, String input_charset) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(private_key)));
|
||||||
|
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
|
||||||
|
signature.initSign(privateKey);
|
||||||
|
signature.update(content.getBytes(input_charset));
|
||||||
|
return Base64.encode(signature.sign());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA验签名检查
|
||||||
|
*
|
||||||
|
* @param content 待签名数据
|
||||||
|
* @param sign 签名值
|
||||||
|
* @param public_key 支付宝公钥
|
||||||
|
* @param input_charset 编码格式
|
||||||
|
* @return 布尔值
|
||||||
|
*/
|
||||||
|
public static boolean verify(String content, String sign, String public_key, String input_charset) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(public_key)));
|
||||||
|
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
|
||||||
|
signature.initVerify(publicKey);
|
||||||
|
signature.update(content.getBytes(input_charset));
|
||||||
|
return signature.verify(Base64.decode(sign));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Class
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
package com.jmfy.util;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Administrator
|
||||||
|
*/
|
||||||
|
public class SignSerialization {
|
||||||
|
|
||||||
|
public static final String TYPE_MD5 = "md5";
|
||||||
|
public static final String TYPE_RSA = "rsa";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数容器
|
||||||
|
*/
|
||||||
|
protected TreeMap<String, String> _properties = new TreeMap<String, String>(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String s, String t1) {
|
||||||
|
return s.compareTo(t1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥
|
||||||
|
*/
|
||||||
|
protected String _publicKey = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥
|
||||||
|
*/
|
||||||
|
protected String _privateKey = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名类型
|
||||||
|
*/
|
||||||
|
protected String _signType = "rsa";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名结果
|
||||||
|
*/
|
||||||
|
protected String _sign = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反序列化方法
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SignSerialization unserialize(String data) {
|
||||||
|
// 实例自己
|
||||||
|
SignSerialization that = new SignSerialization();
|
||||||
|
// 解析数据
|
||||||
|
String[] rows = data.split("&");
|
||||||
|
for (int i = 0; i < rows.length; i++) {
|
||||||
|
int offset = rows[i].indexOf("=");
|
||||||
|
String k = rows[i].substring(0, offset);
|
||||||
|
String v = "";
|
||||||
|
try {
|
||||||
|
v = URLDecoder.decode(rows[i].substring(offset + 1), "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (k.equals("sign_type")) {
|
||||||
|
that._signType = v;
|
||||||
|
continue;
|
||||||
|
} else if (k.equals("sign")) {
|
||||||
|
that._sign = v;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
that.setItem(k, v);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取一项数据
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getItem(String key) {
|
||||||
|
return this._properties.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置一项数据
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public SignSerialization setItem(String key, String value) throws Exception {
|
||||||
|
if (key.equals("sign") || key.equals("sign_type")) {
|
||||||
|
throw new Exception("sign and sign_type not change.");
|
||||||
|
}
|
||||||
|
this._properties.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理注释
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String clearComment(String key) {
|
||||||
|
Pattern pattern1 = Pattern.compile("^[-]+[\\s]*[\\w]+[\\s]+[\\w]+[\\s]+[\\w]+[\\s]*[-]+$", Pattern.CASE_INSENSITIVE + Pattern.MULTILINE);
|
||||||
|
Pattern pattern2 = Pattern.compile("[\\s]+", Pattern.CASE_INSENSITIVE + Pattern.MULTILINE);
|
||||||
|
key = pattern1.matcher(key).replaceAll("");
|
||||||
|
key = pattern2.matcher(key).replaceAll("");
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置公钥
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SignSerialization setPublicKey(String key) {
|
||||||
|
this._publicKey = this.clearComment(key);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置私钥
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SignSerialization setPrivateKey(String key) {
|
||||||
|
this._privateKey = this.clearComment(key);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证结果
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public boolean verify() throws Exception {
|
||||||
|
String data = this.getSignData();
|
||||||
|
String sign = this._sign;
|
||||||
|
return this.verify(data, sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证结果
|
||||||
|
*
|
||||||
|
* @param sign
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean verify(String sign) throws Exception {
|
||||||
|
String data = this.getSignData();
|
||||||
|
return this.verify(data, sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证签名
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param sign
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public boolean verify(String data, String sign) throws Exception {
|
||||||
|
if (this._publicKey == null || this._publicKey.isEmpty()) {
|
||||||
|
throw new Exception("public key not empty.");
|
||||||
|
}
|
||||||
|
return RSA.verify(data, sign, this._publicKey, "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名数据
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String sign() throws Exception {
|
||||||
|
// 签名数据
|
||||||
|
String data = this.getSignData();
|
||||||
|
return this.sign(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名数据
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String sign(String data) throws Exception {
|
||||||
|
if (this._privateKey == null || this._privateKey.isEmpty()) {
|
||||||
|
throw new Exception("private key not empty.");
|
||||||
|
}
|
||||||
|
// 签名数据
|
||||||
|
String sign = RSA.sign(data, this._privateKey, "UTF-8");
|
||||||
|
return sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得签名数据
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getSignData() {
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
Iterator iter = this._properties.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
if (buffer.length() > 0) {
|
||||||
|
buffer.append("&");
|
||||||
|
}
|
||||||
|
Map.Entry entry = (Map.Entry) iter.next();
|
||||||
|
String k = (String) entry.getKey();
|
||||||
|
String v = (String) entry.getValue();
|
||||||
|
buffer.append(k);
|
||||||
|
buffer.append("=");
|
||||||
|
try {
|
||||||
|
buffer.append(URLEncoder.encode(v, "UTF-8"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列化数据
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public String serialize() throws Exception {
|
||||||
|
String data = this.getSignData();
|
||||||
|
String sign = this.sign(data);
|
||||||
|
return data + "&sign_type=rsa&sign=" + URLEncoder.encode(sign, "UTF-8");
|
||||||
|
}
|
||||||
|
// End Class
|
||||||
|
}
|
Loading…
Reference in New Issue