|
@@ -0,0 +1,97 @@
|
|
|
+using System.Security.Cryptography;
|
|
|
+using System.Text;
|
|
|
+
|
|
|
+public class BytePlusAuthUtils
|
|
|
+{
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param ak: AccessKey
|
|
|
+ * @param sk: SecretKey
|
|
|
+ * @param expirationSeconds: The expiration time. Units are in seconds
|
|
|
+ * @param method: GET, POST, PUT
|
|
|
+ * @param uriPath: The requestd path. Not a complete URL
|
|
|
+ * @param params: The requested parameters
|
|
|
+ * @param body: The requested json body
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static string Sign(string ak, string sk, int expirationSeconds, string method, string uriPath, Dictionary<string, string> parameters, string body)
|
|
|
+ {
|
|
|
+ string cm = CanonicalMethod(method);
|
|
|
+ string cu = CanonicalUrl(uriPath);
|
|
|
+ string cp = CanonicalParam(parameters);
|
|
|
+ string cb = CanonicalBody(body);
|
|
|
+ string text = cm + "\n" + cu + "\n" + cp + "\n" + cb;
|
|
|
+ return DoSign(ak, sk, expirationSeconds, text);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string CanonicalMethod(string method)
|
|
|
+ {
|
|
|
+ return "HTTPMethod:" + method;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string CanonicalUrl(string url)
|
|
|
+ {
|
|
|
+ return "CanonicalURI:" + url;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string CanonicalParam(Dictionary<string, string> parameters)
|
|
|
+ {
|
|
|
+ string res = "CanonicalQueryString:";
|
|
|
+ if (parameters == null || parameters.Count == 0)
|
|
|
+ {
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+ foreach (var key in parameters.Keys)
|
|
|
+ {
|
|
|
+ res += FormatKeyValue(key, parameters[key]) + "&";
|
|
|
+ }
|
|
|
+ return res.Substring(0, res.Length - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string FormatKeyValue(string key, string value)
|
|
|
+ {
|
|
|
+ return key + "=" + value;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string CanonicalBody(string body)
|
|
|
+ {
|
|
|
+ string res = "CanonicalBody:";
|
|
|
+ if (body == null)
|
|
|
+ {
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return res + body;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string DoSign(string ak, string sk, int expiration, string text)
|
|
|
+ {
|
|
|
+ string signKeyInfo = "ak-v1/" + ak + "/" + (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds + "/" + expiration;
|
|
|
+ string signKey = Sha256Hmac(signKeyInfo, sk);
|
|
|
+ string signResult = Sha256Hmac(text, signKey);
|
|
|
+ return signKeyInfo + "/" + signResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string Sha256Hmac(string message, string secret)
|
|
|
+ {
|
|
|
+ string hash = "";
|
|
|
+ using (var hmacsha256 = new HMACSHA256(Convert.FromBase64String(secret)))
|
|
|
+ {
|
|
|
+ var bytes = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(message));
|
|
|
+ hash = ByteArrayToHexString(bytes);
|
|
|
+ }
|
|
|
+ return hash;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string ByteArrayToHexString(byte[] b)
|
|
|
+ {
|
|
|
+ StringBuilder hs = new StringBuilder();
|
|
|
+ foreach (byte c in b)
|
|
|
+ {
|
|
|
+ hs.Append(c.ToString("x2"));
|
|
|
+ }
|
|
|
+ return hs.ToString().ToLower();
|
|
|
+ }
|
|
|
+}
|