private static XmlDocument SignSamlRequest(AuthnRequestType request, string signatureNsPrefix, bool includePublicKey, string sslCertificateThumbprint)
        {
            X509Certificate2 cert = SignUtil.LoadCertificate(StoreName.My, StoreLocation.LocalMachine, sslCertificateThumbprint);

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("samlp", _samlProtocolNs);
            if (!string.IsNullOrEmpty(signatureNsPrefix))
            {
                ns.Add(signatureNsPrefix, SignUtil.SignatureNamespace);
            }
            ns.Add("egovbga", _eauthExtNs);
            ns.Add("saml", _samlAssertionNs);
            XmlDocument doc = request.ToXmlDocument(ns);

            XmlElement signatureElement = SignUtil.Sign(doc, cert, signatureNsPrefix, includePublicKey);

            // Подписът вече е добавен в XML документа и по подразбиране е в края му. Според "saml-schema-protocol-2.0.xsd" обаче,
            // подписът трябва да бъде между елементите Issuer и Extensions. InsertAfter() го маха от старото място и го закача на новото.
            XmlNode issuerElement = doc.GetElementsByTagName(nameof(request.Issuer), _samlAssertionNs)[0];

            doc.DocumentElement.InsertAfter(signatureElement, issuerElement);

            return(doc);
        }
        //public static void Main(string[] args)
        //{
        //    //参数
        //    Dictionary<string, string> reqParams = new Dictionary<string, string>();
        //    reqParams.Add("stoneIds", "5d82faf131d5a71d1e379216,5d82ea3b31d5a71d1e35d16a");
        //    reqParams.Add("brandName","品牌商test");
        //    reqParams.Add("storeName","店铺名称test");
        //    reqParams.Add("storeAddr","店铺地址test");
        //    reqParams.Add("storeType","2");//直营(1)加盟(2)
        //    reqParams.Add("customName","客户姓名test");
        //    reqParams.Add("brandOrder","NO201909010001");
        //    reqParams.Add("deliverDate", "2019-09-01");
        //    reqParams.Add("contactName", "某某某");
        //    reqParams.Add("contactPhone", "13666666666");
        //
        //    Submit(Configuration.API_KEY, Configuration.API_SECRET, reqParams);
        //}

        public static void Submit(string apiKey, string apiSecret, Dictionary <string, string> param)
        {
            //API Secret 进行SHA1加密
            string secret = SignUtil.SHA1_Encrypt(apiSecret);
            //API请求方式(大写)
            string reqMethod = "POST";
            //API请求地址(domain + uri)
            string reqUrl = Configuration.API_ENDPOINT + Configuration.URI_STOCK_SUBMIT;
            //POST参数key排序及URL参数化
            Dictionary <string, string> reqParamsAsc = SignUtil.AsciiDictionary(param);
            //URL参数化
            string postParams = SignUtil.ToRequestParam(reqParamsAsc);
            //unix时间戳(13位)
            string timestamp = SignUtil.GetTimeStamp();
            //一次性随机字符串
            string nonce = System.Guid.NewGuid().ToString("N");
            //API请求Headers
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("X-CA-ACCESSKEY", apiKey);
            headers.Add("X-CA-TIMESTAMP", timestamp);
            headers.Add("X-CA-NONCE", nonce);
            //API请求签名
            string signStr = SignUtil.Sign(reqMethod + reqUrl + nonce + timestamp + postParams, secret);

            Console.WriteLine("signStr:" + signStr);
            headers.Add("X-CA-SIGNATURE", signStr);
            //post请求并调用
            string result = HttpUtil.Post(reqUrl, param, headers);

            Console.WriteLine("result:" + result);
            Console.ReadKey();
        }
Beispiel #3
0
        //static string HttpPost(string url, Dictionary<string, string> headers, Dictionary<string, string> bodys, string appKey, string appSecret, int timeout, List<string> signHeaderPrefixList)
        //{
        //    Dictionary <string, string> formParam = new Dictionary<string, string>();
        //    headers = initialBasicHeader(headers, appKey, appSecret, "POST", url, formParam, signHeaderPrefixList);

        //    SimpleHttpClient httpClient("POST", url.c_str(), timeout);
        //    for (map<string, string>::iterator it = headers.begin(); it != headers.end(); it++)
        //    {
        //        httpClient.setHttpHeader(it->first, it->second);
        //    }
        //    httpClient.setHttpMultipartForm(bodys);
        //    httpClient.sendHttpRequest();
        //    return httpClient.getHttpResponseBody();
        //}

        //string HttpUtil::HttpPost(string url, map<string, string> headers, string body, string appKey, string appSecret, int timeout, list<string> signHeaderPrefixList)
        //{
        //    map<string, string> formParam;
        //    headers = initialBasicHeader(headers, appKey, appSecret, "POST", url, formParam, signHeaderPrefixList);

        //    SimpleHttpClient httpClient("POST", url.c_str(), timeout);
        //    for (map<string, string>::iterator it = headers.begin(); it != headers.end(); it++)
        //    {
        //        httpClient.setHttpHeader(it->first, it->second);
        //    }
        //    httpClient.setHttpContent(body);
        //    httpClient.sendHttpRequest();
        //    return httpClient.getHttpResponseBody();
        //}



        /// <summary>
        /// 初始化头部
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="appKey"></param>
        /// <param name="appSecret"></param>
        /// <param name="method"></param>
        /// <param name="requestAddress"></param>
        /// <param name="formParam"></param>
        /// <param name="signHeaderPrefixList"></param>
        /// <returns></returns>
        static Dictionary <string, string> initialBasicHeader(Dictionary <string, string> headers, string appKey, string appSecret, string method, string requestAddress, Dictionary <string, string> formParam, List <string> signHeaderPrefixList)
        {
            headers.Add(X_CA_TIMESTAMP, DateTimeHelper.DateTimeToCTime(DateTime.Now).ToString());
            headers.Add(X_CA_NONCE, Guid.NewGuid().ToString());
            headers.Add(X_CA_KEY, appKey);
            headers.Add(X_CA_SIGNATURE, SignUtil.Sign(method, requestAddress, headers, formParam, appSecret, signHeaderPrefixList));

            return(headers);
        }
Beispiel #4
0
        public string Request(object requestContent, string ak, string sk, string region, string projectId)
        {
            BeforeRequest(requestContent, region, projectId);

            requestObs = SignUtil.Sign(requestObs, ak, sk, region);

            string result = DoRequest <string>(requestContent);

            return(result);
        }
        public T Request <T>(object requestContent, string ak, string sk, string region, string projectId, InterfaceType interfaceName = InterfaceType.DISInterfaceNone)
        {
            BeforeRequest(requestContent, region, projectId);

            requestObs = SignUtil.Sign(requestObs, ak, sk, region);

            T result = DoRequest <T>(requestContent, interfaceName);

            return(result);
        }
        public async Task <string> RequestAsync(object requestContent, string ak, string sk, string region, string projectId)
        {
            this.BeforeRequest(requestContent, region, projectId);

            requestObs = SignUtil.Sign(requestObs, ak, sk, region);

            var result = await DoRequestAsync <string>(requestContent);

            return(result);
        }
Beispiel #7
0
        public string GetRequestUrl(string returnUrl, string notifyUrl, string orderId, decimal totalFee, string productInfo, string openId = null)
        {
            string resultUrl = string.Empty;

            if (CUConfig == null)
            {
                CUConfig = Utility <ChinaUnionConfig> .GetConfig(WorkDirectory);
            }
            if (string.IsNullOrEmpty(CUConfig.merId))
            {
                throw new PluginException("未设置商户编码!");
            }
            if (string.IsNullOrEmpty(CUConfig.signCertpath))
            {
                throw new PluginException("未设置商户私钥证书!");
            }

            Dictionary <string, string> dictParams = new Dictionary <string, string>();

            dictParams.Add("merId", CUConfig.merId);
            dictParams.Add("version", CUConfig.version);
            dictParams.Add("encoding", CUConfig.encoding);
            dictParams.Add("signMethod", CUConfig.signMethod);
            dictParams.Add("txnType", CUConfig.txnType);
            dictParams.Add("txnSubType", CUConfig.txnSubType);
            dictParams.Add("bizType", CUConfig.bizType);
            dictParams.Add("channelType", CUConfig.channelType);
            dictParams.Add("accessType", CUConfig.accessType);
            dictParams.Add("currencyCode", CUConfig.currencyCode);
            dictParams.Add("frontUrl", returnUrl);
            dictParams.Add("backUrl", notifyUrl);
            dictParams.Add("orderId", orderId);
            dictParams.Add("txnTime", DateTime.Now.ToString("yyyyMMddHHmmss"));
            dictParams.Add("txnAmt", ((int)(totalFee * 100)).ToString());
            string signCertpath = WorkDirectory + "\\Cert\\" + CUConfig.signCertpath;

            try
            {
                //string signCertpath = WorkDirectory + "\\Cert\\" + CUConfig.signCertpath;
                bool isSign = SignUtil.Sign(dictParams, System.Text.ASCIIEncoding.GetEncoding(CUConfig.encoding), signCertpath, CUConfig.signCertpwd);
                if (!isSign)
                {
                    throw new PluginException("签名失败!");
                }
            }
            catch (Exception ex)
            {
                throw new PluginException(ex.Message);
            }
            resultUrl = CUConfig.frontTransUrl + "?" + SignUtil.CoverDictionaryToString(dictParams);
            return(resultUrl);
        }
Beispiel #8
0
        public string GetRequestUrl(string returnUrl, string notifyUrl, string orderId, decimal totalFee, string productInfo, string openId = null)
        {
            string empty = string.Empty;

            if (ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig == null)
            {
                ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig = Utility <ChinaUnionConfig> .GetConfig(base.WorkDirectory);
            }
            if (string.IsNullOrEmpty(ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.merId))
            {
                throw new PluginException("未设置商户编码!");
            }
            if (string.IsNullOrEmpty(ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.signCertpath))
            {
                throw new PluginException("未设置商户私钥证书!");
            }
            Dictionary <string, string> strs = new Dictionary <string, string>()
            {
                { "merId", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.merId },
                { "version", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.version },
                { "encoding", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.encoding },
                { "signMethod", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.signMethod },
                { "txnType", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.txnType },
                { "txnSubType", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.txnSubType },
                { "bizType", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.bizType },
                { "channelType", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.channelType },
                { "accessType", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.accessType },
                { "currencyCode", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.currencyCode },
                { "frontUrl", returnUrl },
                { "backUrl", notifyUrl },
                { "orderId", orderId },
                { "txnTime", DateTime.Now.ToString("yyyyMMddHHmmss") }
            };
            int num = (int)(totalFee * new decimal(100));

            strs.Add("txnAmt", num.ToString());
            string str = string.Concat(base.WorkDirectory, "\\Cert\\", ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.signCertpath);

            try
            {
                if (!SignUtil.Sign(strs, Encoding.GetEncoding(ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.encoding), str, ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.signCertpwd))
                {
                    throw new PluginException("签名失败!");
                }
            }
            catch (Exception exception)
            {
                throw new PluginException(exception.Message);
            }
            empty = string.Concat(ChemCloud.Plugin.Payment.UnionPay.UnionPay.CUConfig.frontTransUrl, "?", SignUtil.CoverDictionaryToString(strs));
            return(empty);
        }
        private async Task <T> DoRequestAsync <T>(object requestContent)
        {
            int retryCount             = -1;
            ExponentialBackOff backOff = null;

            do
            {
                retryCount++;
                if (retryCount > 0)
                {
                    // 等待一段时间再发起重试
                    if (backOff == null)
                    {
                        backOff = new ExponentialBackOff(250, 2.0, disConfig.GetBackOffMaxIntervalMs(),
                                                         ExponentialBackOff.DEFAULT_MAX_ELAPSED_TIME);
                    }
                    backOff.backOff(backOff.getNextBackOff());
                }

                try
                {
                    requestObs.Headers.Remove(HttpHeaderKeys.Authorization);
                    requestObs.Headers.Remove(HttpHeaderKeys.SdkData);
                    requestObs.Headers.Remove(HttpHeaderKeys.SdkShaContent);
                    requestObs.Headers.Remove(HttpHeaderKeys.HostHeader);
                    // 每次重传需要重新签名
                    requestObs = SignUtil.Sign(requestObs, disConfig.GetAK(), disConfig.GetSK(), disConfig.GetRegion());
                    return(await DoRequestAsync <T>(requestObs, requestContent));
                }
                catch (Exception t)
                {
                    String errorMsg   = t.Message;
                    int    statusCode = int.Parse(errorMsg.Split('\n')[0]);
                    // 如果不是可以重试的异常 或者 已达到重试次数,则直接抛出异常
                    if (!Utils.IsRetriableSendException(statusCode) || retryCount >= disConfig.GetExceptionRetries())
                    {
                        throw new Exception(errorMsg.Substring(statusCode.ToString().Length + 1), t);
                    }

                    logger.WarnFormat("Find Retriable Exception {0}, url [{1} {2}], currRetryCount is {3}",
                                      errorMsg.Replace("\r\n", ""), requestObs.HttpMethod, requestObs.Endpoint.Host.Trim('/') + requestObs.ResourcePath, retryCount);
                }
            } while (retryCount < disConfig.GetExceptionRetries());

            return(default(T));

            //return await DoRequestAsync<T>(requestObs, requestContent);
        }
Beispiel #10
0
        public static void Query(string apiKey, string apiSecret, Dictionary <string, string> param)
        {
            //API Secret 进行SHA1加密
            string secret = SignUtil.SHA1_Encrypt(apiSecret);
            //API请求方式
            string reqMethod = "GET";
            //API请求地址(domain + uri)
            StringBuilder urlBuilder = new StringBuilder();

            urlBuilder.Append(Configuration.API_ENDPOINT).Append(Configuration.URI_STOCK_QUERY);
            //参数key排序
            Dictionary <string, string> reqParamsAsc = SignUtil.AsciiDictionary(param);
            //GET参数URL参数化
            string getParam  = SignUtil.ToRequestParam(reqParamsAsc);
            string bodyParam = "";//无
            string url       = urlBuilder.Append("?").Append(getParam).ToString();
            //unix时间戳(13位)
            string timestamp = SignUtil.GetTimeStamp();
            //一次性随机字符串
            string nonce = System.Guid.NewGuid().ToString("N");
            //API请求Headers
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("X-CA-ACCESSKEY", apiKey);
            headers.Add("X-CA-TIMESTAMP", timestamp);
            headers.Add("X-CA-NONCE", nonce);
            //API请求签名
            string signStr = SignUtil.Sign(reqMethod + url + nonce + timestamp + bodyParam, secret);

            Console.WriteLine("signStr:" + signStr);
            headers.Add("X-CA-SIGNATURE", signStr);
            //post请求并调用
            string result = HttpUtil.Get(url, headers);

            Console.WriteLine("result:" + result);
            Console.ReadKey();
        }
Beispiel #11
0
        /// <summary>
        /// 进行请求签名
        /// </summary>
        /// <param name="requestModel"></param>
        /// <param name="credentials"></param>
        /// <returns></returns>
        public SignedRequestModel Sign(RequestModel requestModel, Credential credentials)
        {
            string nonceId = "";

            if (!requestModel.NonceId.IsNullOrWhiteSpace())
            {
                nonceId = requestModel.NonceId;
            }
            else if (requestModel.Header != null &&
                     requestModel.Header.Count > 0 &&
                     requestModel.Header.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE))
            {
                List <string> headValues = requestModel.Header[ParameterConstant.X_JDCLOUD_NONCE];
                if (headValues != null && headValues.Count > 0)
                {
                    nonceId = headValues[0];
                }
                else
                {
                    nonceId = Guid.NewGuid().ToString().ToLower();
                }
            }
            else
            {
                nonceId = Guid.NewGuid().ToString().ToLower();
            }

            var    signDate = requestModel.OverrddenDate == null ? DateTime.Now:requestModel.OverrddenDate.Value;
            string formattedSigningDateTime = signDate.ToString(ParameterConstant.DATA_TIME_FORMAT);
            string formattedSigningDate     = signDate.ToString(ParameterConstant.HEADER_DATA_FORMAT);
            string scope         = SignUtil.GenerateScope(formattedSigningDate, requestModel.ServiceName, requestModel.RegionName, ParameterConstant.JDCLOUD_TERMINATOR);
            var    requestHeader = requestModel.Header;

            requestHeader.Add(ParameterConstant.X_JDCLOUD_DATE,
                              new List <string> {
                formattedSigningDateTime
            });
            if (!requestModel.Header.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE))
            {
                requestHeader.Add(ParameterConstant.X_JDCLOUD_NONCE,
                                  new List <string> {
                    nonceId
                });
            }

            var contentSHA256 = "";

            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_CONTENT_SHA256))
            {
                List <string> contentSha256Value = requestHeader[ParameterConstant.X_JDCLOUD_CONTENT_SHA256];
                if (contentSha256Value != null && contentSha256Value.Count > 0)
                {
                    contentSHA256 = contentSha256Value[0];
                }
            }
            if (contentSHA256.IsNullOrWhiteSpace())
            {
                contentSHA256 = SignUtil.CalculateContentHash(requestModel.Content);
            }
            var           requestParameters = OrderRequestParameters(requestModel.QueryParameters);
            string        path          = "";
            StringBuilder stringBuilder = new StringBuilder();

            if (!requestModel.ResourcePath.TrimStart().StartsWith("/"))
            {
                stringBuilder.Append("/");
            }
            stringBuilder.Append(requestModel.ResourcePath);
            path = stringBuilder.ToString();
            var canonicalRequest = SignUtil.CreateCanonicalRequest(requestParameters,
                                                                   GetCanonicalizedResourcePath(path, false),
                                                                   requestModel.HttpMethod.ToUpper()
                                                                   , GetCanonicalizedHeaderString(requestModel),
                                                                   GetSignedHeadersString(requestModel), contentSHA256);
            var stringToSign = SignUtil.CreateStringToSign(canonicalRequest, formattedSigningDateTime, scope, ParameterConstant.JDCLOUD2_SIGNING_ALGORITHM);

            byte[] kSecret    = System.Text.Encoding.UTF8.GetBytes($"JDCLOUD2{credentials.SecretAccessKey}");
            byte[] kDate      = SignUtil.Sign(formattedSigningDate, kSecret, ParameterConstant.SIGN_SHA256);
            byte[] kRegion    = SignUtil.Sign(requestModel.RegionName, kDate, ParameterConstant.SIGN_SHA256);
            byte[] kService   = SignUtil.Sign(requestModel.ServiceName, kRegion, ParameterConstant.SIGN_SHA256);
            byte[] signingKey = SignUtil.Sign(ParameterConstant.JDCLOUD_TERMINATOR, kService, ParameterConstant.SIGN_SHA256);
            byte[] signature  = SignUtil.ComputeSignature(stringToSign, signingKey);
            // Console.WriteLine($" kSecret={ BitConverter.ToString(kSecret).Replace("-", "")}");
            // Console.WriteLine($" kDate={ BitConverter.ToString(kDate).Replace("-", "")}");
            // Console.WriteLine($" kRegion={ BitConverter.ToString(kRegion).Replace("-", "")}");
            // Console.WriteLine($" kService={ BitConverter.ToString(kService).Replace("-", "")}");
            // Console.WriteLine($" signingKey={ BitConverter.ToString(signingKey).Replace("-", "")}");
            // Console.WriteLine($" signature={ BitConverter.ToString(signature).Replace("-", "")}");

            string signingCredentials = credentials.AccessKeyId + "/" + scope;
            string credential         = "Credential=" + signingCredentials;
            string signerHeaders      = "SignedHeaders=" + GetSignedHeadersString(requestModel);
            string signatureHeader    = "Signature=" + StringUtils.ByteToHex(signature, true);

            var signHeader = new StringBuilder().Append(ParameterConstant.JDCLOUD2_SIGNING_ALGORITHM)
                             .Append(" ")
                             .Append(credential)
                             .Append(", ")
                             .Append(signerHeaders)
                             .Append(", ")
                             .Append(signatureHeader)
                             .ToString();

            requestModel.AddHeader(ParameterConstant.AUTHORIZATION, signHeader);
            SignedRequestModel signedRequestModel = new SignedRequestModel();

            signedRequestModel.CanonicalRequest = canonicalRequest;
            signedRequestModel.ContentSHA256    = contentSHA256;
            foreach (var header in requestModel.Header)
            {
                signedRequestModel.RequestHead.Add(header.Key, string.Join(",", header.Value.ToArray()));
            }
            signedRequestModel.RequestNonceId  = nonceId;
            signedRequestModel.SignedHeaders   = signHeader;
            signedRequestModel.StringSignature = stringToSign;
            signedRequestModel.StringToSign    = stringToSign;

            return(signedRequestModel);
        }
        /// <summary>
        /// sign with RequestModel
        /// </summary>
        /// <param name="requestModel"></param>
        /// <param name="credentials"></param>
        /// <returns></returns>
        public SignedRequestModel Sign(RequestModel requestModel, Credential credentials)
        {
            string nonceId       = "";
            var    requestHeader = ProcessRequestHeaderKeyToLower(requestModel.Header);

            if (requestModel.NonceId.IsNullOrWhiteSpace())
            {
                nonceId = Guid.NewGuid().ToString().ToLower();
            }
            else if (requestHeader != null &&
                     requestHeader.Count > 0 &&
                     requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_NONCE.ToLower()))
            {
                List <string> headValues = requestHeader[ParameterConstant.X_JDCLOUD_NONCE.ToLower()];
                if (headValues != null && headValues.Count > 0)
                {
                    nonceId = headValues[0];
                }
                else
                {
                    nonceId = Guid.NewGuid().ToString().ToLower();
                }
            }
            else
            {
                nonceId = requestModel.NonceId;
            }

            DateTime?signDate = null;

            if (requestHeader != null &&
                requestHeader.Count > 0 &&
                requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_DATE.ToLower()))
            {
                List <string> headerValues = requestHeader[ParameterConstant.X_JDCLOUD_DATE.ToLower()];
                if (headerValues != null && headerValues.Count > 0)
                {
                    string dateString = headerValues[0];
                    if (!dateString.IsNullOrWhiteSpace())
                    {
                        var tryParseDate = DateTime.Now;
                        if (DateTime.TryParseExact(dateString, ParameterConstant.DATA_TIME_FORMAT,
                                                   CultureInfo.GetCultureInfo("en-US"), System.Globalization.DateTimeStyles.None,
                                                   out tryParseDate))
                        {
                            signDate = tryParseDate;
                        }
                    }
                }
            }
            else
            {
                if (requestModel.OverrddenDate != null && requestModel.OverrddenDate.HasValue)
                {
                    signDate = requestModel.OverrddenDate.Value;
                }
            }
            if (signDate == null || !signDate.HasValue)
            {
                signDate = DateTime.UtcNow;
            }
            string formattedSigningDateTime = signDate.Value.ToString(ParameterConstant.DATA_TIME_FORMAT);
            string formattedSigningDate     = signDate.Value.ToString(ParameterConstant.HEADER_DATA_FORMAT);
            string scope = SignUtil.GenerateScope(formattedSigningDate, requestModel.ServiceName, requestModel.RegionName, ParameterConstant.JDCLOUD_TERMINATOR_V3);

            requestHeader.Add(ParameterConstant.X_JDCLOUD_DATE,
                              new List <string> {
                formattedSigningDateTime
            });
            requestHeader.Add(ParameterConstant.X_JDCLOUD_NONCE,
                              new List <string> {
                nonceId
            });
            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower()))
            {
                requestHeader[ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower()] = new List <string> {
                    ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3
                };
            }
            else
            {
                requestHeader.Add(ParameterConstant.X_JDCLOUD_ALGORITHM.ToLower(), new List <string> {
                    ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3
                });
            }
            var contentSHA256 = "";

            if (requestHeader.ContainsKey(ParameterConstant.X_JDCLOUD_CONTENT_SHA256))
            {
                List <string> contentSha256Value = requestHeader[ParameterConstant.X_JDCLOUD_CONTENT_SHA256];
                if (contentSha256Value != null && contentSha256Value.Count > 0)
                {
                    contentSHA256 = contentSha256Value[0];
                }
            }
            if (contentSHA256.IsNullOrWhiteSpace())
            {
                contentSHA256 = SignUtil.CalculateContentHash(requestModel.Content);
            }
            string queryParams   = ProcessQueryString(requestModel.QueryParameters);
            string requestPath   = ProcessRequestPath(requestModel.ResourcePath);
            string requestMethod = ProcessRequestMethod(requestModel.HttpMethod);
            Dictionary <string, string> processHeader = ProcessRequstHeader(ProcessRequestHeaderWithMoreValue(requestModel.Header));
            string signHeaderString    = GetSignedHeadersString(processHeader);
            string signHeaderKeyString = GetSignedHeadersKeyString(processHeader);
            var    canonicalRequest    = SignUtil.CreateCanonicalRequest(queryParams, requestPath, requestMethod, signHeaderString, signHeaderKeyString, contentSHA256);
            var    stringToSign        = SignUtil.CreateStringToSign(canonicalRequest, formattedSigningDateTime, scope, ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3);

            byte[] kSecret    = System.Text.Encoding.UTF8.GetBytes($"JDCLOUD3{credentials.SecretAccessKey}");
            byte[] kDate      = SignUtil.Sign(formattedSigningDate, kSecret, ParameterConstant.SIGN_SHA256);
            byte[] kRegion    = SignUtil.Sign(requestModel.RegionName, kDate, ParameterConstant.SIGN_SHA256);
            byte[] kService   = SignUtil.Sign(requestModel.ServiceName, kRegion, ParameterConstant.SIGN_SHA256);
            byte[] signingKey = SignUtil.Sign(ParameterConstant.JDCLOUD_TERMINATOR_V3, kService, ParameterConstant.SIGN_SHA256);
            byte[] signature  = SignUtil.ComputeSignature(stringToSign, signingKey);
            // Console.WriteLine($" kSecret={ BitConverter.ToString(kSecret).Replace("-", "")}");
            // Console.WriteLine($" kDate={ BitConverter.ToString(kDate).Replace("-", "")}");
            // Console.WriteLine($" kRegion={ BitConverter.ToString(kRegion).Replace("-", "")}");
            // Console.WriteLine($" kService={ BitConverter.ToString(kService).Replace("-", "")}");
            // Console.WriteLine($" signingKey={ BitConverter.ToString(signingKey).Replace("-", "")}");
            // Console.WriteLine($" signature={ BitConverter.ToString(signature).Replace("-", "")}");

            string signingCredentials = credentials.AccessKeyId + "/" + scope;
            string credential         = "Credential=" + signingCredentials;
            string signerHeaders      = "SignedHeaders=" + signHeaderKeyString;
            string signatureHeader    = "Signature=" + StringUtils.ByteToHex(signature, true);

            var signHeader = new StringBuilder().Append(ParameterConstant.JDCLOUD3_SIGNING_ALGORITHM_V3)
                             .Append(" ")
                             .Append(credential)
                             .Append(", ")
                             .Append(signerHeaders)
                             .Append(", ")
                             .Append(signatureHeader)
                             .ToString();

            requestModel.AddHeader(ParameterConstant.AUTHORIZATION, signHeader);
            SignedRequestModel signedRequestModel = new SignedRequestModel();

            signedRequestModel.CanonicalRequest = canonicalRequest;
            signedRequestModel.ContentSHA256    = contentSHA256;
            foreach (var header in requestModel.Header)
            {
                signedRequestModel.RequestHead.Add(header.Key, string.Join(",", header.Value.ToArray()));
            }
            signedRequestModel.RequestNonceId  = nonceId;
            signedRequestModel.SignedHeaders   = signHeader;
            signedRequestModel.StringSignature = stringToSign;
            signedRequestModel.StringToSign    = stringToSign;

            return(signedRequestModel);
        }