From eb179632c884a3784810329d5969702357c58605 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 27 Jun 2019 19:20:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=94=E5=9B=9Esign=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdk-csharp/SDKCSharp/Client/OpenClient.cs | 105 +++++++++-- .../SDKCSharp/Client/OpenRequest.cs | 12 +- .../Common/DefaultDataNameBuilder.cs | 2 +- .../SDKCSharp/Common/ErrorResponse.cs | 8 + .../sdk-csharp/SDKCSharp/Common/OpenConfig.cs | 166 ++++++------------ .../SDKCSharp/Common/SopSdkConstants.cs | 8 + .../SDKCSharp/Common/SopSdkErrors.cs | 27 +++ sop-sdk/sdk-csharp/SDKCSharp/Program.cs | 7 +- .../SDKCSharp/Request/BaseRequest.cs | 47 +++-- .../sdk-csharp/SDKCSharp/Utility/JsonUtil.cs | 2 + .../sdk-csharp/SDKCSharp/Utility/SignUtil.cs | 38 +++- .../com/gitee/sop/sdk/client/OpenClient.java | 81 +++++++-- .../com/gitee/sop/sdk/client/OpenRequest.java | 14 +- .../sdk/common/DefaultDataNameBuilder.java | 2 +- .../com/gitee/sop/sdk/common/OpenConfig.java | 24 ++- .../com/gitee/sop/sdk/common/SdkConfig.java | 4 + .../gitee/sop/sdk/common/SopSdkConstants.java | 7 + .../gitee/sop/sdk/common/SopSdkErrors.java | 56 ++++++ .../gitee/sop/sdk/request/BaseRequest.java | 31 ++-- .../gitee/sop/sdk/response/ErrorResponse.java | 7 + .../com/gitee/sop/sdk/sign/SopSignature.java | 12 +- .../test/java/com/gitee/sop/sdk/SdkTest.java | 10 +- 22 files changed, 452 insertions(+), 218 deletions(-) create mode 100644 sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs create mode 100644 sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs create mode 100644 sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs create mode 100644 sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkConstants.java create mode 100644 sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkErrors.java create mode 100644 sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/ErrorResponse.java diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenClient.cs b/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenClient.cs index fc6d2880..427db732 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenClient.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenClient.cs @@ -11,6 +11,7 @@ using SDKCSharp.Request; using SDKCSharp.Response; using SDKCSharp.Utility; using System.IO; +using Newtonsoft.Json.Linq; namespace SDKCSharp.Client { @@ -21,7 +22,6 @@ namespace SDKCSharp.Client { private static OpenConfig DEFAULT_CONFIG = new OpenConfig(); - private const string ERROR_RESPONSE_KEY = "error_response"; private Dictionary header = new Dictionary(); @@ -29,22 +29,37 @@ namespace SDKCSharp.Client private string url; private string appId; private string privateKey; + private string publicKeyPlatform; private OpenConfig openConfig; private OpenRequest openRequest; private DataNameBuilder dataNameBuilder; - public OpenClient(string url, string appId, string privateKey) : this(url, appId, privateKey,false, DEFAULT_CONFIG) + public OpenClient(string url, string appId, string privateKey) + : this(url, appId, privateKey,false, DEFAULT_CONFIG) { } - public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile) : this(url, appId, privateKey, priKeyFromFile, DEFAULT_CONFIG) + public OpenClient(string url, string appId, string privateKey, string publicKeyPlatform) + : this(url, appId, privateKey) + { + this.publicKeyPlatform = publicKeyPlatform; + } + + public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile) + : this(url, appId, privateKey, priKeyFromFile, DEFAULT_CONFIG) { } + public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile, string publicKeyPlatform) + : this(url, appId, privateKey, priKeyFromFile) + { + this.publicKeyPlatform = publicKeyPlatform; + } + public OpenClient(string url, string appId, string privateKey,bool priKeyFromFile, OpenConfig openConfig) { this.url = url; @@ -60,6 +75,12 @@ namespace SDKCSharp.Client this.dataNameBuilder = openConfig.DataNameBuilder; } + public OpenClient(string url, string appId, string privateKey, bool priKeyFromFile, string publicKeyPlatform, OpenConfig openConfig) + : this(url, appId, privateKey, priKeyFromFile, openConfig) + { + this.publicKeyPlatform = publicKeyPlatform; + } + /// /// 加载秘钥文件 /// @@ -106,7 +127,7 @@ namespace SDKCSharp.Client form[this.openConfig.AccessTokenName] = accessToken; } form[this.openConfig.AppKeyName] = this.appId; - string sign = SignUtil.CreateSign(form, privateKey, request.Charset, request.SignType); + string sign = SignUtil.CreateSign(form, privateKey, openConfig.Charset, openConfig.SignType); form[this.openConfig.SignName] = sign; string resp = this.DoExecute(url, requestForm, header); @@ -133,22 +154,84 @@ namespace SDKCSharp.Client /// 服务器响应内容 /// 请求Request /// 返回Response - protected virtual T ParseResponse(string resp, BaseRequest request) where T: BaseResponse { + protected virtual T ParseResponse(string resp, BaseRequest request) where T: BaseResponse + { string method = request.Method; - string dataName = this.dataNameBuilder.Build(method); - Dictionary jsonObject = JsonUtil.ParseToDictionary(resp); - bool errorResponse = jsonObject.ContainsKey(ERROR_RESPONSE_KEY); + string rootNodeName = this.dataNameBuilder.Build(method); + string errorRootNode = openConfig.ErrorResponseName; + Dictionary responseData = JsonUtil.ParseToDictionary(resp); + bool errorResponse = responseData.ContainsKey(errorRootNode); if (errorResponse) { - dataName = ERROR_RESPONSE_KEY; + rootNodeName = errorRootNode; + } + object data = responseData[rootNodeName]; + responseData.TryGetValue(openConfig.SignName, out object sign); + if (sign != null && !string.IsNullOrEmpty(publicKeyPlatform)) + { + string signContent = BuildBizJson(rootNodeName, resp); + if (!CheckResponseSign(signContent, sign.ToString(), publicKeyPlatform)) + { + ErrorResponse checkSignErrorResponse = SopSdkErrors.CHECK_RESPONSE_SIGN_ERROR; + data = JsonUtil.ToJSONString(checkSignErrorResponse); + } } - object data = jsonObject[dataName]; - string jsonData = data == null ? "{}" : data.ToString(); + string jsonData = data == null ? "{}" : data.ToString(); T t = JsonUtil.ParseObject(jsonData); t.Body = jsonData; return t; } + /// + /// 验证服务端返回的sign + /// + /// true, if response sign was checked, false otherwise. + /// Response data. + /// sign data. + /// Public key platform. + protected virtual bool CheckResponseSign(string signContent, string sign, string publicKeyPlatform) + { + try + { + Encoding charset = openConfig.Charset; + SignType signType = openConfig.SignType; + return SignUtil.RsaCheck(signContent, sign, publicKeyPlatform, charset, signType); + } + catch (Exception) + { + return false; + } + } + + protected virtual string BuildBizJson(string rootNodeName, string body) + { + int indexOfRootNode = body.IndexOf(rootNodeName); + if (indexOfRootNode < 0) + { + rootNodeName = openConfig.ErrorResponseName; + indexOfRootNode = body.IndexOf(rootNodeName); + } + string result = null; + if (indexOfRootNode > 0) + { + result = BuildJsonNodeData(body, rootNodeName, indexOfRootNode); + } + return result; + } + + protected virtual string BuildJsonNodeData(string body, string rootNode, int indexOfRootNode) + { + int signDataStartIndex = indexOfRootNode + rootNode.Length + 2; + int indexOfSign = body.IndexOf("\"" + openConfig.SignName + "\""); + if (indexOfSign < 0) + { + return null; + } + int signDataEndIndex = indexOfSign - 1; + int length = signDataEndIndex - signDataStartIndex; + + return body.Substring(signDataStartIndex, length); + } } } diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenRequest.cs b/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenRequest.cs index 6c46c823..6974a405 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenRequest.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Client/OpenRequest.cs @@ -13,9 +13,6 @@ namespace SDKCSharp.Client { public class OpenRequest { - - private const string HTTP_ERROR_CODE = "-400"; - private OpenConfig openConfig; private OpenHttp openHttp; @@ -77,17 +74,10 @@ namespace SDKCSharp.Client protected string CauseException(Exception e) { - ErrorResponse result = new ErrorResponse(); - result.SubCode = HTTP_ERROR_CODE; - result.SubMsg = e.Message; - result.Code = HTTP_ERROR_CODE; - result.Msg = e.Message; + ErrorResponse result = SopSdkErrors.HTTP_ERROR; return JsonUtil.ToJSONString(result); } } - class ErrorResponse : BaseResponse - { - } } diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Common/DefaultDataNameBuilder.cs b/sop-sdk/sdk-csharp/SDKCSharp/Common/DefaultDataNameBuilder.cs index b19b8047..29705a5a 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Common/DefaultDataNameBuilder.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Common/DefaultDataNameBuilder.cs @@ -10,7 +10,7 @@ namespace SDKCSharp.Common private const char DOT = '.'; private const char UNDERLINE = '_'; - private const string DATA_SUFFIX = "_response"; + private const string DATA_SUFFIX = SopSdkConstants.DATA_SUFFIX; public string Build(string method) { diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs b/sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs new file mode 100644 index 00000000..90ddf919 --- /dev/null +++ b/sop-sdk/sdk-csharp/SDKCSharp/Common/ErrorResponse.cs @@ -0,0 +1,8 @@ +using System; +namespace SDKCSharp.Common +{ + public class ErrorResponse: Response.BaseResponse + { + + } +} diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Common/OpenConfig.cs b/sop-sdk/sdk-csharp/SDKCSharp/Common/OpenConfig.cs index e77f132f..7eee7261 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Common/OpenConfig.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Common/OpenConfig.cs @@ -5,192 +5,132 @@ using System.Text; using System.Threading.Tasks; using SDKCSharp; +using SDKCSharp.Utility; namespace SDKCSharp.Common { public class OpenConfig { - - private String successCode = SdkConfig.SUCCESS_CODE; + public static DataNameBuilder DATA_NAME_BUILDER = new DefaultDataNameBuilder(); /// /// 返回码成功值 /// - public String SuccessCode - { - get { return successCode; } - set { successCode = value; } - } + public string SuccessCode { get; set; } = "10000"; - private String defaultVersion = SdkConfig.DEFAULT_VERSION; /// /// 默认版本号 /// - public String DefaultVersion - { - get { return defaultVersion; } - set { defaultVersion = value; } - } + public string DefaultVersion { get; set; } = "1.0"; + + /// + /// 字符编码 + /// + /// The charset. + public Encoding Charset { get; set; } = Encoding.UTF8; + + /// + /// 签名类型 + /// + /// The type of the sign. + public SignType SignType { get; set; } = SignType.RSA2; + + /// + /// 格式类型 + /// + public string FormatType { get; set; } = "json"; + + /// + /// 时间戳格式 + /// + public string TimestampPattern { get; set; } = "yyyy-MM-dd HH:mm:ss"; + - private String methodName = "method"; /// /// 接口属性名 /// - public String MethodName - { - get { return methodName; } - set { methodName = value; } - } + public string MethodName { get; set; } = "method"; - private String versionName = "version"; /// /// 版本号名称 /// - public String VersionName - { - get { return versionName; } - set { versionName = value; } - } + public string VersionName { get; set; } = "version"; - private String charsetName = "charset"; /// /// 编码名称 /// /// The name of the charset. - public string CharsetName { get => charsetName; set => charsetName = value; } + public string CharsetName { get; set; } = "charset"; - private String appKeyName = "app_id"; /// /// appKey名称 /// - public String AppKeyName - { - get { return appKeyName; } - set { appKeyName = value; } - } + public string AppKeyName { get; set; } = "app_id"; - private String dataName = "biz_content"; /// /// data名称 /// - public String DataName - { - get { return dataName; } - set { dataName = value; } - } + public string DataName { get; set; } = "biz_content"; - private String timestampName = "timestamp"; /// /// 时间戳名称 /// - public String TimestampName - { - get { return timestampName; } - set { timestampName = value; } - } + public string TimestampName { get; set; } = "timestamp"; - private String timestampPattern = "yyyy-MM-dd HH:mm:ss"; /// - /// 时间戳格式 + /// 签名串名称 /// - public String TimestampPattern - { - get { return timestampPattern; } - set { timestampPattern = value; } - } + public string SignName { get; set; } = "sign"; - private String signName = "sign"; - /// - /// 签名串名称 + /// + /// 签名类型名称 /// - public String SignName - { - get { return signName; } - set { signName = value; } - } + /// The name of the sign type. + public string SignTypeName { get; set; } = "sign_type"; - private String formatName = "format"; /// /// 格式化名称 /// - public String FormatName - { - get { return formatName; } - set { formatName = value; } - } + public string FormatName { get; set; } = "format"; + - private String formatType = "json"; - /// - /// 格式类型 - /// - public String FormatType - { - get { return formatType; } - set { formatType = value; } - } - private String accessTokenName = "app_auth_token"; /// accessToken名称 /// - public String AccessTokenName - { - get { return accessTokenName; } - set { accessTokenName = value; } - } + public string AccessTokenName { get; set; } = "app_auth_token"; - private String locale = "zh-CN"; /// /// 国际化语言 /// - public String Locale - { - get { return locale; } - set { locale = value; } - } + public string Locale { get; set; } = "zh-CN"; - private String responseCodeName = "code"; /// /// 响应code名称 /// - public String ResponseCodeName - { - get { return responseCodeName; } - set { responseCodeName = value; } - } + public string ResponseCodeName { get; set; } = "code"; + + /// + /// 错误响应节点 + /// + /// The name of the error response. + public string ErrorResponseName { get; set; } = "error_response"; - private int connectTimeoutSeconds = 10; /// /// 请求超时时间 /// - public int ConnectTimeoutSeconds - { - get { return connectTimeoutSeconds; } - set { connectTimeoutSeconds = value; } - } + public int ConnectTimeoutSeconds { get; set; } = 10; - private int readTimeoutSeconds = 10; /// /// http读取超时时间 /// - public int ReadTimeoutSeconds - { - get { return readTimeoutSeconds; } - set { readTimeoutSeconds = value; } - } + public int ReadTimeoutSeconds { get; set; } = 10; - private string signTypeName = "sign_type"; - /// - /// 签名类型名称 - /// - /// The name of the sign type. - public string SignTypeName { get => signTypeName; set => signTypeName = value; } - private DataNameBuilder dataNameBuilder = SdkConfig.dataNameBuilder; /// /// 节点名称构造器 /// /// The data name builder. - public DataNameBuilder DataNameBuilder { get => dataNameBuilder; set => dataNameBuilder = value; } + public DataNameBuilder DataNameBuilder { get; set; } = DATA_NAME_BUILDER; } } diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs b/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs new file mode 100644 index 00000000..6db9f260 --- /dev/null +++ b/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkConstants.cs @@ -0,0 +1,8 @@ +using System; +namespace SDKCSharp.Common +{ + public static class SopSdkConstants + { + public const string DATA_SUFFIX = "_response"; + } +} diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs b/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs new file mode 100644 index 00000000..c855b294 --- /dev/null +++ b/sop-sdk/sdk-csharp/SDKCSharp/Common/SopSdkErrors.cs @@ -0,0 +1,27 @@ +using System; +namespace SDKCSharp.Common +{ + public class SopSdkErrors + { + /// + /// 网络错误 + /// + public static ErrorResponse HTTP_ERROR = BuildErrorResponse("836875001", "网络错误"); + + /// + /// 验证返回sign错误 + /// + public static ErrorResponse CHECK_RESPONSE_SIGN_ERROR = BuildErrorResponse("836875002", "验证服务端sign出错"); + + public static ErrorResponse BuildErrorResponse(string code, string msg) + { + return new ErrorResponse + { + Code = code, + SubCode = code, + SubMsg = msg, + Msg = msg + }; + } + } +} diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Program.cs b/sop-sdk/sdk-csharp/SDKCSharp/Program.cs index aee43161..3591af77 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Program.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Program.cs @@ -15,15 +15,18 @@ namespace SDKTest { static string url = "http://localhost:8081/api"; static string appId = "201904035630907729292csharp"; - // 私钥, PKCS1 2048 + // 开发者私钥, PKCS1 2048 static string privateKey = "MIIEowIBAAKCAQEA5+OvJxeSzf44NxQ/cl7Ii+BzPg2k6sRcvH4ffOtU5Dzq1/oEvg02nxIhmwOHBZmjbmuUu0aLsfglUTAwqfXftfAKZidshsgj9NNh0/kxk0avRZ1UoljWGz/FxVZA0ogbxxhohPZ9jWcD+eBQcIwF2DtHfAJqWWZrYFnCMeHD8mPzxo2kwXSvDzi0vf9I2tKiYvNG26a9FqeYtPOoi81sdS3+70HOMdxP8ejXtyfnKpKz7Dx506LCIRS5moWS3Q5eTLV3NGX/1CSJ8wpQA2DAQTjVhX5eVu7Yqz12t8W+sjWM/tHUR6cgwYYR10p7tSCeCPzkigjGxKm4cYXWtATQJQIDAQABAoIBAHFDsgrrJca+NKEan77ycwx3jnKx4WrWjOF4zVKL9AQjiSYDNgvKknJyPb3kpC/lEoHdxGERHSzJoxib7DkoIqRQYhPxj73pxj5QfYk3P7LLJNNg/LTrpXDb3nL8JV9wIflGf87qQvstZTDJEyFWE4jBs7Hr0BxovWvri8InnzkmERJ1cbGJgNHe1Y3Zo2tw0yaHxQCxLuajP+notRZhD9bEp7uKeI0w9AvlW6k8m/7y10F0BK/TlyW8rQiEC391yOiRYoMcUh4hd2Q9bMx3jngZgX8PXIvZZcup4/pvWlv1alwhB2tsnLdazP62r1MO80vLyLunzGO+7WwCjEYlVaECgYEA+lQRFmbhKaPuAuXMtY31Fbga8nedka5TjnEV7+/kX+yowE2OlNujF+ZG8UTddTxAGv56yVNi/mjRlgD74j8z0eOsgvOq9mwbCrgLhLo51H9O/wAxtb+hBKtC5l50pBr4gER6d8W6EQNTSGojnMIaLXTkAZ5Qf6Z8e2HFVdOn0X0CgYEA7SSrTokwzukt5KldNu5ukyyd+C3D1i6orbg6qD73EP9CfNMfGSBn7dDv9wMSJH01+Ty+RgTROgtjGRDbMJWnfbdt/61NePr9ar5sb6Nbsf7/I0w7cZF5dsaFYgzaOfQYquzXPbLQHkpMT64bqpv/Mwy4F2lFvaYWY5fA4pC2uckCgYEAg75Ym9ybJaoTqky8ttQ2Jy8UZ4VSVQhVC0My02sCWwWXLlXi8y7An+Rec73Ve0yxREOn5WrQT6pkmzh7V/ABWrYi5WxODpCIjtSbo0fLBa3Wqle00b0/hdCITetqIa/cFs1zUrOqICgK3bKWeXqiAkhhcwSZwwSgwOKM04Wn7ZUCgYBvhHX2mbdVJfyJ8kc+hMOE/E9RHRxiBVEXWHJlGi8PVCqNDq8qHr4g7Mdbzprig+s0yKblwHAvrpkseWvKHiZEjVTyDipHgShY4TGXEigVvUd37uppTrLi8xpYcJjS9gH/px7VCdiq1d+q/MJP6coJ1KphgATm2UrgDMYNBWaYWQKBgEHRxrmER7btUF60/YgcqPHFc8RpYQB2ZZE0kyKGDqk2Data1XYUY6vsPAU28yRLAaWr/D2H17iyLkxP80VLm6QhifxCadv90Q/Wl1DFfOJQMW6avyQ0so6G0wFq/LJxaFK4iLXQn1RJnmTp6BYiJMmK2BhFbRzw8ssMoF6ad2rr"; + // 开放平台给的公钥 + // 前往SOP-ADMIN,ISV管理--秘钥管理,选择PKCS1,生成平台提供的公私钥,然后把【平台公钥】放到这里 + static string publicKeyPlatform = ""; // 从文件中加载 //static string filePath = "/Users/thc/logs/priKey.txt"; //static OpenClient client = new OpenClient(url, appId, filePath, true); // 声明一个就行 - static OpenClient client = new OpenClient(url, appId, privateKey); + static OpenClient client = new OpenClient(url, appId, privateKey, publicKeyPlatform); public static void Main(string[] args) diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Request/BaseRequest.cs b/sop-sdk/sdk-csharp/SDKCSharp/Request/BaseRequest.cs index b0d6dcd9..e6ce1a82 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Request/BaseRequest.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Request/BaseRequest.cs @@ -12,11 +12,7 @@ namespace SDKCSharp.Request /// 对应的Response对象 public abstract class BaseRequest { - private string method; - private string format = SdkConfig.FORMAT_TYPE; - private Encoding charset = SdkConfig.CHARSET; - private SignType signType = SdkConfig.SIGN_TYPE; - private string timestamp = DateTime.Now.ToString(SdkConfig.TIMESTAMP_PATTERN); + private string method; private string version; private string bizContent; @@ -30,8 +26,6 @@ namespace SDKCSharp.Request public string BizContent { set => bizContent = value; } public object BizModel { set => bizModel = value; } public string Version { get => version; set => version = value; } - public Encoding Charset { get => charset; set => charset = value; } - public SignType SignType { get => signType; set => signType = value; } /// /// 返回接口名 @@ -45,7 +39,7 @@ namespace SDKCSharp.Request /// public virtual string GetVersion() { - return SdkConfig.DEFAULT_VERSION; + return null; } /// @@ -66,7 +60,7 @@ namespace SDKCSharp.Request protected BaseRequest(string name, string version) { this.method = name; - this.version = version == null ? SdkConfig.DEFAULT_VERSION : version; + this.version = version; } /// @@ -88,23 +82,28 @@ namespace SDKCSharp.Request /// public RequestForm CreateRequestForm(OpenConfig openConfig) { - Dictionary dict = new Dictionary(); - dict[openConfig.MethodName] = this.Method; - dict[openConfig.FormatName] = this.format; - dict[openConfig.CharsetName] = this.charset.BodyName; - dict[openConfig.SignTypeName] = this.signType.ToString(); - dict[openConfig.TimestampName] = this.timestamp; - dict[openConfig.VersionName] = this.version; - + string timestamp = DateTime.Now.ToString(openConfig.TimestampPattern); + string v = this.version ?? openConfig.DefaultVersion; // 业务参数 - String biz_content = BuildBizContent(); - - dict[openConfig.DataName] = biz_content; + string biz_content = BuildBizContent(); - RequestForm requestForm = new RequestForm(dict); - requestForm.Charset = this.charset; - requestForm.RequestMethod = GetRequestMethod(); - requestForm.Files = this.files; + Dictionary dict = new Dictionary + { + [openConfig.MethodName] = this.Method, + [openConfig.FormatName] = openConfig.FormatType, + [openConfig.CharsetName] = openConfig.Charset.BodyName, + [openConfig.SignTypeName] = openConfig.SignType.ToString(), + [openConfig.TimestampName] = timestamp, + [openConfig.VersionName] = v, + [openConfig.DataName] = biz_content + }; + + RequestForm requestForm = new RequestForm(dict) + { + Charset = openConfig.Charset, + RequestMethod = GetRequestMethod(), + Files = this.files + }; return requestForm; } diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Utility/JsonUtil.cs b/sop-sdk/sdk-csharp/SDKCSharp/Utility/JsonUtil.cs index 59de42db..d366e1cf 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Utility/JsonUtil.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Utility/JsonUtil.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using Newtonsoft.Json; +using SDKCSharp.Request; namespace SDKCSharp.Utility { @@ -36,6 +37,7 @@ namespace SDKCSharp.Utility return JsonConvert.DeserializeObject>(json); } + /// /// 对象转换成json字符串 /// diff --git a/sop-sdk/sdk-csharp/SDKCSharp/Utility/SignUtil.cs b/sop-sdk/sdk-csharp/SDKCSharp/Utility/SignUtil.cs index b3fc3dc4..cc4af3f9 100644 --- a/sop-sdk/sdk-csharp/SDKCSharp/Utility/SignUtil.cs +++ b/sop-sdk/sdk-csharp/SDKCSharp/Utility/SignUtil.cs @@ -2,13 +2,14 @@ using System.Collections; using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; namespace SDKCSharp.Utility { /// /// 签名工具类 /// - public class SignUtil + public static class SignUtil { /// @@ -26,6 +27,13 @@ namespace SDKCSharp.Utility return rsa.Sign(content); } + public static bool RsaCheck(string content, string sign, string publicKeyPlatform, Encoding charset, + SignType signType) + { + RSAHelper rsa = new RSAHelper(signType, charset, null, publicKeyPlatform); + return rsa.Verify(content, sign); + } + /// /// 构建签名内容 /// @@ -53,5 +61,33 @@ namespace SDKCSharp.Utility return content; } + /// + /// 构建签名内容 + /// + /// The sign content. + /// Parameters. + public static string GetSignContentObject(IDictionary parameters) + { + // 第一步:把字典按Key的字母顺序排序 + IDictionary sortedParams = new SortedDictionary(parameters); + IEnumerator> dem = sortedParams.GetEnumerator(); + + // 第二步:把所有参数名和参数值串在一起 + StringBuilder query = new StringBuilder(""); + while (dem.MoveNext()) + { + string key = dem.Current.Key; + string value = Convert.ToString(dem.Current.Value); + value = Regex.Replace(value, @"\s", ""); + if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) + { + query.Append(key).Append("=").Append(value).Append("&"); + } + } + string content = query.ToString().Substring(0, query.Length - 1); + + return content; + } + } } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java index 34d3d761..61aec6aa 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java @@ -5,11 +5,15 @@ import com.alibaba.fastjson.JSONObject; import com.gitee.sop.sdk.common.DataNameBuilder; import com.gitee.sop.sdk.common.OpenConfig; import com.gitee.sop.sdk.common.RequestForm; +import com.gitee.sop.sdk.common.SopSdkConstants; +import com.gitee.sop.sdk.common.SopSdkErrors; import com.gitee.sop.sdk.exception.SdkException; import com.gitee.sop.sdk.request.BaseRequest; import com.gitee.sop.sdk.response.BaseResponse; +import com.gitee.sop.sdk.response.ErrorResponse; import com.gitee.sop.sdk.sign.SopSignException; import com.gitee.sop.sdk.sign.SopSignature; +import com.gitee.sop.sdk.sign.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -25,33 +29,46 @@ public class OpenClient { private static final Log log = LogFactory.getLog(OpenClient.class); private static final OpenConfig DEFAULT_CONFIG = new OpenConfig(); - private static final String ERROR_RESPONSE_KEY = "error_response"; private String url; private String appId; private String privateKey; + /** + * 开放平台提供的公钥 + */ + private String publicKeyPlatform; private OpenConfig openConfig; private OpenRequest openRequest; private DataNameBuilder dataNameBuilder; - public OpenClient(String url, String appId, String privateKey) { - this(url, appId, privateKey, DEFAULT_CONFIG); + public OpenClient(String url, String appId, String privateKeyIsv) { + this(url, appId, privateKeyIsv, DEFAULT_CONFIG); } - public OpenClient(String url, String appId, String privateKey, OpenConfig openConfig) { + public OpenClient(String url, String appId, String privateKeyIsv, String publicKeyPlatform) { + this(url, appId, privateKeyIsv); + this.publicKeyPlatform = publicKeyPlatform; + } + + public OpenClient(String url, String appId, String privateKeyIsv, OpenConfig openConfig) { if (openConfig == null) { throw new IllegalArgumentException("openConfig不能为null"); } this.url = url; this.appId = appId; - this.privateKey = privateKey; + this.privateKey = privateKeyIsv; this.openConfig = openConfig; this.openRequest = new OpenRequest(openConfig); this.dataNameBuilder = openConfig.getDataNameBuilder(); } + public OpenClient(String url, String appId, String privateKeyIsv, String publicKeyPlatform, OpenConfig openConfig) { + this(url, appId, privateKeyIsv, openConfig); + this.publicKeyPlatform = publicKeyPlatform; + } + /** * 请求接口 * @@ -83,7 +100,7 @@ public class OpenClient { String content = SopSignature.getSignContent(form); String sign = null; try { - sign = SopSignature.rsa256Sign(content, privateKey, "utf-8"); + sign = SopSignature.rsaSign(content, privateKey, openConfig.getCharset(), openConfig.getSignType()); } catch (SopSignException e) { throw new SdkException("构建签名错误", e); } @@ -109,17 +126,61 @@ public class OpenClient { protected T parseResponse(String resp, BaseRequest request) { String method = request.getMethod(); - String dataName = dataNameBuilder.build(method); + String rootNodeName = dataNameBuilder.build(method); JSONObject jsonObject = JSON.parseObject(resp); - boolean errorResponse = jsonObject.containsKey(ERROR_RESPONSE_KEY); + String errorResponseName = this.openConfig.getErrorResponseName(); + boolean errorResponse = jsonObject.containsKey(errorResponseName); if (errorResponse) { - dataName = ERROR_RESPONSE_KEY; + rootNodeName = errorResponseName; + } + JSONObject data = jsonObject.getJSONObject(rootNodeName); + String sign = jsonObject.getString(openConfig.getSignName()); + // 是否要验证返回的sign + if (StringUtils.areNotEmpty(sign, publicKeyPlatform)) { + String signContent = buildBizJson(rootNodeName, resp); + if (!this.checkResponseSign(signContent, sign, publicKeyPlatform)) { + ErrorResponse error = SopSdkErrors.CHECK_RESPONSE_SIGN_ERROR.getErrorResponse(); + data = JSON.parseObject(JSON.toJSONString(error)); + } } - JSONObject data = jsonObject.getJSONObject(dataName); T t = data.toJavaObject(request.getResponseClass()); t.setBody(data.toJSONString()); return t; } + protected String buildBizJson(String rootNodeName, String body) { + int indexOfRootNode = body.indexOf(rootNodeName); + if (indexOfRootNode < 0) { + rootNodeName = SopSdkConstants.ERROR_RESPONSE_KEY; + indexOfRootNode = body.indexOf(rootNodeName); + } + String result = null; + if (indexOfRootNode > 0) { + result = buildJsonNodeData(body, rootNodeName, indexOfRootNode); + } + return result; + } + + protected String buildJsonNodeData(String body, String rootNodeName, int indexOfRootNode) { + int signDataStartIndex = indexOfRootNode + rootNodeName.length() + 2; + int indexOfSign = body.indexOf("\"" + openConfig.getSignName() + "\""); + if (indexOfSign < 0) { + return null; + } + int length = indexOfSign - 1; + return body.substring(signDataStartIndex, length); + } + + protected boolean checkResponseSign(String signContent, String sign, String publicKeyPlatform) { + try { + String charset = this.openConfig.getCharset(); + String signType = this.openConfig.getSignType(); + return SopSignature.rsaCheck(signContent, sign, publicKeyPlatform, charset, signType); + } catch (SopSignException e) { + log.error("验证服务端sign出错,signContent:" + signContent, e); + return false; + } + } + } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java index b3556566..3327e2c6 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenRequest.java @@ -4,8 +4,9 @@ import com.alibaba.fastjson.JSON; import com.gitee.sop.sdk.common.OpenConfig; import com.gitee.sop.sdk.common.RequestForm; import com.gitee.sop.sdk.common.RequestMethod; +import com.gitee.sop.sdk.common.SopSdkErrors; import com.gitee.sop.sdk.common.UploadFile; -import com.gitee.sop.sdk.response.BaseResponse; +import com.gitee.sop.sdk.response.ErrorResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -20,8 +21,6 @@ import java.util.Map; */ public class OpenRequest { - private static final String HTTP_ERROR_CODE = "-400"; - private OpenHttp openHttp; public OpenRequest(OpenConfig openConfig) { @@ -69,14 +68,7 @@ public class OpenRequest { } protected String causeException(Exception e) { - ErrorResponse result = new ErrorResponse(); - result.setCode(HTTP_ERROR_CODE); - result.setSubCode(HTTP_ERROR_CODE); - result.setSubMsg(e.getMessage()); - result.setMsg(e.getMessage()); + ErrorResponse result = SopSdkErrors.HTTP_ERROR.getErrorResponse(); return JSON.toJSONString(result); } - - static class ErrorResponse extends BaseResponse { - } } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java index 72cdaeb0..31f97fa8 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/DefaultDataNameBuilder.java @@ -19,7 +19,7 @@ package com.gitee.sop.sdk.common; public class DefaultDataNameBuilder implements DataNameBuilder { private static final char DOT = '.'; private static final char UNDERLINE = '_'; - private static final String DATA_SUFFIX = "_response"; + private static final String DATA_SUFFIX = SopSdkConstants.DATA_SUFFIX; @Override public String build(String method) { diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/OpenConfig.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/OpenConfig.java index 3b49bac8..4d47c629 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/OpenConfig.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/OpenConfig.java @@ -7,10 +7,21 @@ import lombok.Data; */ @Data public class OpenConfig { + public static DataNameBuilder DATA_NAME_BUILDER = new DefaultDataNameBuilder(); + /** 成功返回码值 */ - private String successCode = SdkConfig.SUCCESS_CODE; + private String successCode = "10000"; /** 默认版本号 */ - private String defaultVersion = SdkConfig.DEFAULT_VERSION; + private String defaultVersion = "1.0"; + /** 字符编码 */ + private String charset = "UTF-8"; + /** 签名方式 */ + private String signType = "RSA2"; + /** 格式类型名称 */ + private String formatType = "json"; + /** 时间戳格式 */ + private String timestampPattern = "yyyy-MM-dd HH:mm:ss"; + /** 接口属性名 */ private String methodName = "method"; /** 版本号名称 */ @@ -23,22 +34,21 @@ public class OpenConfig { private String dataName = "biz_content"; /** 时间戳名称 */ private String timestampName = "timestamp"; - /** 时间戳格式 */ - private String timestampPattern = "yyyy-MM-dd HH:mm:ss"; /** 签名串名称 */ private String signName = "sign"; /** 签名类型名称 */ private String signTypeName = "sign_type"; /** 格式化名称 */ private String formatName = "format"; - /** 格式类型名称 */ - private String formatType = "json"; /** accessToken名称 */ private String accessTokenName = "app_auth_token"; /** 国际化语言 */ private String locale = "zh-CN"; /** 响应code名称 */ private String responseCodeName = "code"; + /** 错误响应节点 */ + private String errorResponseName = "error_response"; + /** 请求超时时间 */ private int connectTimeoutSeconds = 10; /** http读取超时时间 */ @@ -49,5 +59,5 @@ public class OpenConfig { /** * 构建数据节点名称 */ - private DataNameBuilder dataNameBuilder = SdkConfig.dataNameBuilder; + private DataNameBuilder dataNameBuilder = DATA_NAME_BUILDER; } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SdkConfig.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SdkConfig.java index 2bcd89b0..253d1df4 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SdkConfig.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SdkConfig.java @@ -1,5 +1,9 @@ package com.gitee.sop.sdk.common; +/** + * @deprecated 已废弃,使用com.gitee.sop.sdk.common.OpenConfig + */ +@Deprecated public class SdkConfig { public static String SUCCESS_CODE = "10000"; diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkConstants.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkConstants.java new file mode 100644 index 00000000..91f87618 --- /dev/null +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkConstants.java @@ -0,0 +1,7 @@ +package com.gitee.sop.sdk.common; + +public class SopSdkConstants { + public static String DATA_SUFFIX = "_response"; + + public static String ERROR_RESPONSE_KEY = "error_response"; +} \ No newline at end of file diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkErrors.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkErrors.java new file mode 100644 index 00000000..50e62035 --- /dev/null +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/common/SopSdkErrors.java @@ -0,0 +1,56 @@ +package com.gitee.sop.sdk.common; + +import com.gitee.sop.sdk.response.ErrorResponse; + +/** + * @author tanghc + */ +public enum SopSdkErrors { + /** + * 网络错误 + */ + HTTP_ERROR("836875001", "网络错误"), + /** + * 验证返回sign错误 + */ + CHECK_RESPONSE_SIGN_ERROR("836875002", "验证服务端sign出错") + ; + + SopSdkErrors(String code, String msg) { + this.code = code; + this.msg = msg; + this.subCode = code; + this.subMsg = msg; + } + + public ErrorResponse getErrorResponse() { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setSubCode(subCode); + errorResponse.setSubMsg(subMsg); + errorResponse.setMsg(msg); + return errorResponse; + } + + private String code; + private String msg; + private String subCode; + private String subMsg; + + public String getCode() { + return code; + } + + public String getMsg() { + return msg; + } + + public String getSubCode() { + return subCode; + } + + public String getSubMsg() { + return subMsg; + } + +} diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java index 59a00b2a..7b975036 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON; import com.gitee.sop.sdk.common.OpenConfig; import com.gitee.sop.sdk.common.RequestForm; import com.gitee.sop.sdk.common.RequestMethod; -import com.gitee.sop.sdk.common.SdkConfig; import com.gitee.sop.sdk.common.UploadFile; import com.gitee.sop.sdk.response.BaseResponse; import com.gitee.sop.sdk.util.ClassUtil; @@ -36,10 +35,6 @@ import java.util.Map; public abstract class BaseRequest { private String method; - private String format = SdkConfig.FORMAT_TYPE; - private String charset = SdkConfig.CHARSET; - private String signType = SdkConfig.SIGN_TYPE; - private String timestamp = new SimpleDateFormat(SdkConfig.TIMESTAMP_PATTERN).format(new Date()); private String version; private String bizContent; @@ -50,11 +45,10 @@ public abstract class BaseRequest { */ private List files; - private Class responseClass; + private Class responseClass = (Class) ClassUtil.getSuperClassGenricType(this.getClass(), 0);; protected abstract String method(); - @SuppressWarnings("unchecked") public BaseRequest() { this.setMethodVersion(this.method(), this.version()); } @@ -65,16 +59,16 @@ public abstract class BaseRequest { private void setMethodVersion(String method, String version) { this.method = method; - this.version = version == null ? SdkConfig.DEFAULT_VERSION : version; - this.responseClass = (Class) ClassUtil.getSuperClassGenricType(this.getClass(), 0); + this.version = version; } protected String version() { - return SdkConfig.DEFAULT_VERSION; + return null; } /** * 添加上传文件 + * * @param file */ public void addFile(UploadFile file) { @@ -88,11 +82,13 @@ public abstract class BaseRequest { // 公共请求参数 Map params = new HashMap(); params.put(openConfig.getMethodName(), this.method); - params.put(openConfig.getFormatName(), this.format); - params.put(openConfig.getCharsetName(), this.charset); - params.put(openConfig.getSignTypeName(), this.signType); - params.put(openConfig.getTimestampName(), this.timestamp); - params.put(openConfig.getVersionName(), this.version); + params.put(openConfig.getFormatName(), openConfig.getFormatType()); + params.put(openConfig.getCharsetName(), openConfig.getCharset()); + params.put(openConfig.getSignTypeName(), openConfig.getSignType()); + String timestamp = new SimpleDateFormat(openConfig.getTimestampPattern()).format(new Date()); + params.put(openConfig.getTimestampName(), timestamp); + String v = this.version == null ? openConfig.getDefaultVersion() : this.version; + params.put(openConfig.getVersionName(), v); // 业务参数 String biz_content = buildBizContent(); @@ -101,7 +97,7 @@ public abstract class BaseRequest { RequestForm requestForm = new RequestForm(params); requestForm.setRequestMethod(getRequestMethod()); - requestForm.setCharset(this.charset); + requestForm.setCharset(openConfig.getCharset()); requestForm.setFiles(this.files); return requestForm; } @@ -120,6 +116,7 @@ public abstract class BaseRequest { /** * 指定版本号 + * * @param version */ public void setVersion(String version) { @@ -144,9 +141,11 @@ public abstract class BaseRequest { /** * 指定HTTP请求method,默认POST + * * @return */ protected RequestMethod getRequestMethod() { return RequestMethod.POST; } + } diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/ErrorResponse.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/ErrorResponse.java new file mode 100644 index 00000000..0e6b4a93 --- /dev/null +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/ErrorResponse.java @@ -0,0 +1,7 @@ +package com.gitee.sop.sdk.response; + +/** + * @author tanghc + */ +public class ErrorResponse extends BaseResponse { +} diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/sign/SopSignature.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/sign/SopSignature.java index c1c0fb72..811ae669 100644 --- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/sign/SopSignature.java +++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/sign/SopSignature.java @@ -53,14 +53,14 @@ public class SopSignature { * @param sortedParams * @return */ - public static String getSignContent(Map sortedParams) { + public static String getSignContent(Map sortedParams) { StringBuffer content = new StringBuffer(); List keys = new ArrayList(sortedParams.keySet()); Collections.sort(keys); int index = 0; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); - String value = sortedParams.get(key); + String value = String.valueOf(sortedParams.get(key)); if (StringUtils.areNotEmpty(key, value)) { content.append((index == 0 ? "" : "&") + key + "=" + value); index++; @@ -210,7 +210,7 @@ public class SopSignature { return content.toString(); } - public static String getSignCheckContentV2(Map params) { + public static String getSignCheckContentV2(Map params) { if (params == null) { return null; } @@ -223,7 +223,7 @@ public class SopSignature { for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); - String value = params.get(key); + String value = String.valueOf(params.get(key)); content.append((i == 0 ? "" : "&") + key + "=" + value); } @@ -254,9 +254,9 @@ public class SopSignature { return rsaCheckContent(content, sign, publicKey, charset); } - public static boolean rsaCheckV2(Map params, String publicKey, + public static boolean rsaCheckV2(Map params, String publicKey, String charset,String signType) throws SopSignException { - String sign = params.get("sign"); + String sign = String.valueOf(params.get("sign")); String content = getSignCheckContentV2(params); return rsaCheck(content, sign, publicKey, charset,signType); diff --git a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java index cc2daf37..16a2b18c 100644 --- a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java +++ b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java @@ -24,12 +24,14 @@ import java.util.Map; public class SdkTest extends TestCase { String url = "http://localhost:8081/api"; // zuul String appId = "2019032617262200001"; - // 支付宝私钥 - String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; - + /** 开发者私钥 */ + String privateKeyIsv = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; + /** 开放平台提供的公钥 + * 前往SOP-ADMIN,ISV管理--秘钥管理,生成平台提供的公私钥,然后把【平台公钥】放到这里 */ + String publicKeyPlatform = ""; // 声明一个就行 - OpenClient client = new OpenClient(url, appId, privateKey); + OpenClient client = new OpenClient(url, appId, privateKeyIsv, publicKeyPlatform); // 标准用法 @Test