///<summary>生成签名</summary> ///<param name="signStr">被加密串</param> ///<param name="secret">加密密钥</param> ///<returns>签名</returns> ///<seealso cref="https://cloud.tencent.com/document/product/614/12445"/> public string Signature(Uri uri, string method, string qkeytime, IDictionary <string, string> headers, SignatureMethod signatureMethod = SignatureMethod.sha1) { //1.按照一定格式拼接Http请求的相关信息为字符串 HttpRequestInfo。 //不能使用HttpUtility.UrlEncode! 存在大小写转换问题 var headersString = string.Join("&", headers.Select(h => $"{h.Key.ToLower()}={WebUtility.UrlEncode(h.Value)}").OrderBy(h => h, StringComparer.Ordinal)); var HttpRequestInfo = $"{method.ToLower()}\n{uri.LocalPath}\n{uri.Query.Replace("?", "")}\n{headersString}\n"; //2.对 HttpRequestInfo 使用 sha1 算法计算哈希值,与其他指定参数按照一定格式组成签名原串 StringToSign。 string hashReqInfo; switch (signatureMethod) { case SignatureMethod.sha1: using (var sha1 = new SHA1Managed()) { var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(HttpRequestInfo)); hashReqInfo = BitConverter.ToString(hash).Replace("-", "").ToLower(); } break; default: throw new ArgumentException($"未知的签名加密类型{signatureMethod.ToString()}"); } var StringToSign = $"{signatureMethod}\n{qkeytime}\n{hashReqInfo}\n"; //3.使用 SecretKey 对 q-key-time 进行加密,得到 SignKey。 var SignKey = SecretString(qkeytime, SecretKey); //4.使用 SignKey 对 StringToSign 进行加密,生成 Signature。 var Signature = SecretString(StringToSign, SignKey); return($"q-sign-algorithm={signatureMethod}&q-ak={SecretId}&q-sign-time={qkeytime}&q-key-time={qkeytime}&q-header-list={string.Join(";", headers.Select(v => v.Key.ToLower()).OrderBy(v => v, StringComparer.Ordinal))}&q-url-param-list={string.Join(";", uri.Query.Replace("?", "").Split('&').Select(kv => kv.Split('=').First()).OrderBy(v => v, StringComparer.Ordinal))}&q-signature={Signature}"); }
///<summary>生成签名</summary> ///<param name="signStr">被加密串</param> ///<param name="secret">加密密钥</param> ///<returns>签名</returns> private static string SecretString(string signStr, string secret, SignatureMethod signatureMethod = SignatureMethod.sha1) { switch (signatureMethod) { case SignatureMethod.sha1: using (HMACSHA1 mac = new HMACSHA1(Encoding.UTF8.GetBytes(secret))) { byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(signStr)); return(BitConverter.ToString(hash).Replace("-", "").ToLower()); } default: throw new ArgumentException($"未知的签名加密类型{signatureMethod.ToString()}"); } }
public static String Token( string realm , string authPrefix , HttpMethod httpMethod , Uri urlPath , string appId , string secret = null , ApiList formList = null , RSA privateKey = null , string nonce = null , string timestamp = null , string version = "1.0") { Logger.LogEnter(LoggerBase.Args(realm, authPrefix, httpMethod, urlPath, appId, secret, formList == null ? null : formList.ToFormData(), privateKey, nonce, timestamp, version)); Logger.LogDebug("URL:: {0}", urlPath); authPrefix = authPrefix.ToLower(); // Generate the nonce value nonce = nonce ?? ApiAuthorization.NewNonce().ToString(); timestamp = timestamp ?? ApiAuthorization.NewTimestamp().ToString(); SignatureMethod signatureMethod = SignatureMethod.HMACSHA256; if (secret == null) { signatureMethod = SignatureMethod.SHA256withRSA; } String baseString = BaseString(authPrefix, signatureMethod , appId, urlPath, httpMethod , formList, nonce, timestamp, version); String base64Token = ""; if (secret != null) { base64Token = baseString.L1Signature(secret); } else { base64Token = baseString.L2Signature(privateKey); } var tokenList = new ApiList(); tokenList.Add("realm", realm); tokenList.Add(authPrefix + "_timestamp", timestamp); tokenList.Add(authPrefix + "_nonce", nonce); tokenList.Add(authPrefix + "_app_id", appId); tokenList.Add(authPrefix + "_signature_method", signatureMethod.ToString()); tokenList.Add(authPrefix + "_version", version); tokenList.Add(authPrefix + "_signature", base64Token); string authorizationToken = string.Format("{0} {1}", authPrefix.Substring(0, 1).ToUpperInvariant() + authPrefix.Substring(1), tokenList.ToString(",", false, true)); Logger.LogDebug("Token :: {0}", authorizationToken); Logger.LogExit(LoggerBase.Args(authorizationToken)); return(authorizationToken); }
public static string BaseString( string authPrefix , SignatureMethod signatureMethod , string appId , Uri siteUri , HttpMethod httpMethod , ApiList formList , string nonce , string timestamp , string version) { Logger.LogEnter(LoggerBase.Args(authPrefix, signatureMethod, appId, siteUri, httpMethod, formList, nonce, timestamp)); authPrefix = authPrefix.ToLower(); // make sure that the url are valid if (siteUri.Scheme != "http" && siteUri.Scheme != "https") { throw new System.NotSupportedException("Support http and https protocol only."); } // make sure that the port no and querystring are remove from url var url = string.Format("{0}://{1}{2}", siteUri.Scheme, siteUri.Host, siteUri.AbsolutePath); Logger.LogInformation("url:: {0}", url); // helper calss that handle parameters and form fields ApiList paramList = new ApiList(); // process QueryString from url by transfering it to paramList if (siteUri.Query.Length > 1) { var queryString = siteUri.Query.Substring(1); // remove the ? from first character Logger.LogInformation("queryString:: {0}", queryString); var paramArr = queryString.Split('&'); foreach (string item in paramArr) { var itemArr = item.Split('='); paramList.Add(itemArr[0], System.Net.WebUtility.UrlDecode(itemArr[1])); } Logger.LogInformation("paramList:: {0}", paramList); } // add the form fields to paramList if (formList != null && formList.Count > 0) { paramList.AddRange(formList); } paramList.Add(authPrefix + "_timestamp", timestamp); paramList.Add(authPrefix + "_nonce", nonce); paramList.Add(authPrefix + "_app_id", appId); paramList.Add(authPrefix + "_signature_method", signatureMethod.ToString()); paramList.Add(authPrefix + "_version", version); string baseString = httpMethod.ToString() + "&" + url + "&" + paramList.ToString(); Logger.LogDebug("BaseString:: {0}", baseString); Logger.LogExit(LoggerBase.Args(baseString)); return(baseString); }