• Unity | API鉴权用到的函数汇总


    目录

    一、HMAC-SHA1

    二、UriEncode

    三、Date

    四、Content-MD5

    五、参数操作

    六、阿里云API鉴权


    一、HMAC-SHA1

            使用 RFC 2104 中定义的 HMAC-SHA1 方法生成带有密钥的哈希值:

    1. private static string CalculateSignature(string secret, string data)
    2. {
    3. byte[] keyBytes = Encoding.UTF8.GetBytes(secret);
    4. byte[] dataBytes = Encoding.UTF8.GetBytes(data);
    5. using (var hmacsha1 = new HMACSHA1(keyBytes))
    6. {
    7. byte[] hashBytes = hmacsha1.ComputeHash(dataBytes);
    8. // 将哈希值转换为十六进制字符串
    9. StringBuilder hexString = new StringBuilder(hashBytes.Length * 2);
    10. foreach (byte b in hashBytes)
    11. {
    12. hexString.AppendFormat("{0:x2}", b);
    13. }
    14. return hexString.ToString();
    15. }
    16. }

    二、UriEncode

            按照RFC 3986进行 URI 编码:

    1. private static string Rfc3986Encode(string value)
    2. {
    3. // 使用 Uri.EscapeDataString 进行初步编码
    4. var encoded = Uri.EscapeDataString(value);
    5. // 根据 RFC 3986 的要求替换字符
    6. encoded = encoded.Replace("%20", "+");
    7. encoded = encoded.Replace("%21", "!");
    8. encoded = encoded.Replace("%27", "'");
    9. encoded = encoded.Replace("%28", "(");
    10. encoded = encoded.Replace("%29", ")");
    11. encoded = encoded.Replace("%7E", "~ ");
    12. return encoded;
    13. }

    三、Date

            当前 UTC 时间,以 ISO 8601 yyyyMMddTHHmmssZ 格式表示:

    string date = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");

            HTTP 1.1 协议中规定的 GMT 时间:(示例:Wed, 01 Mar 2006 12:00:00 GMT )

    1. public static string GetCurrentDateTimeInStandardFormat()
    2. {
    3. // 获取当前时间并转换到指定时区
    4. var dateTimeOffset = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(8));
    5. // 将日期时间格式化为字符串
    6. var formattedDateTime = dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:sszzz");
    7. // 替换时区部分的冒号
    8. return formattedDateTime.Substring(0, 22) + formattedDateTime.Substring(23);
    9. }

    四、Content-MD5

            RFC 1864 定义的请求体(Body) md5 摘要(128 位二进制表示,并使用 base64 编码):

    1. private static string CalculateMD5(byte[] data)
    2. {
    3. using (var md5 = MD5.Create())
    4. {
    5. byte[] hashBytes = md5.ComputeHash(data);
    6. return Convert.ToBase64String(hashBytes);
    7. }
    8. }

    五、参数操作

            对 URL 中所有参数名、参数值单独 UriEncode,按参数名字母升序的顺序,依次将参数名、参数值用 = 及 & 拼接:

    1. private static string ConstructCanonicalQueryString(Dictionary<string, string> queryParams)
    2. {
    3. if (queryParams == null || queryParams.Count == 0)
    4. return "";
    5. var sortedQueryParams = queryParams.OrderBy(kvp => kvp.Key);
    6. var encodedQueryParams = sortedQueryParams.Select(kvp => $"{Rfc3986Encode(kvp.Key)}={Rfc3986Encode(kvp.Value)}");
    7. return string.Join("&", encodedQueryParams);
    8. }

    六、阿里云API鉴权

            下方是阿里云上传文件API鉴权及请求示例(其实接入SDK更方便一些)。(阿里云上传文件后路径为https://桶名称.oss-cn-beijing.aliyuncs.com/文件夹/文件

    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Security.Cryptography;
    4. using System.Text;
    5. using System;
    6. using System.IO;
    7. using UnityEngine.Networking;
    8. public class AliYunManager : MonoBehaviour
    9. {
    10. private const string OSS_HOST = "oss-cn-beijing.aliyuncs.com";//域名
    11. private const string BUCKET_NAME = "*****";//bucket名称
    12. private const string ACCESS_KEY_ID = "************";
    13. private const string ACCESS_KEY_SECRET = "**************";
    14. // Use this for initialization
    15. void Start()
    16. {
    17. UploadFileAsync("D:\\FCJProject\\YiDongYanFaBu\\StudentPartner\\StudentPartner\\Bundles\\StandaloneWindows\\DefaultPackage\\5.0.0\\1ba6bb9f41d66f71f7deb9d2d63b29e4.bundle", "/debug/PC/9.92.0");
    18. }
    19. ///
    20. ///
    21. ///
    22. /// 本地文件绝对路径
    23. /// 需要保存的文件在bucket上的相对路径,前后不需要加'/',也不需要加文件名
    24. public void UploadFileAsync(string filePath, string bucketPath)
    25. {
    26. StartCoroutine(UploadFile(filePath, bucketPath));
    27. }
    28. IEnumerator UploadFile(string filePath, string bucketPath)
    29. {
    30. // Load the image from file
    31. byte[] imageBytes = File.ReadAllBytes(filePath);
    32. string fileName = Path.GetFileName(filePath);
    33. string bucketFilePath = "/" + bucketPath + "/" + fileName;
    34. string url = "https://" + BUCKET_NAME + "." + OSS_HOST + bucketFilePath;
    35. string contentMD5 = "";// ToMD5(imageBytes);
    36. string contentType = "application/octet-stream";
    37. string utcGMT = DateTime.UtcNow.ToString("r");
    38. string canonicalizedOSSHeaders = "";
    39. string canonicalizedResource = "/" + BUCKET_NAME +bucketFilePath;
    40. string authorization = GetAuthorization("PUT", contentMD5, contentType, utcGMT, canonicalizedOSSHeaders, canonicalizedResource);
    41. Debug.Log("Authorization: " + authorization);
    42. Debug.Log("url: " + url);
    43. //Debug.Log("contentMD5: " + contentMD5);
    44. // Create UnityWebRequest
    45. UnityWebRequest request = new UnityWebRequest(url, "PUT");
    46. //request.uploadHandler = new UploadHandlerRaw(imageData);
    47. request.downloadHandler = new DownloadHandlerBuffer();
    48. // Set headers
    49. request.SetRequestHeader("Content-Length", imageBytes.Length.ToString());
    50. request.SetRequestHeader("Content-Type", contentType);
    51. request.SetRequestHeader("Host", BUCKET_NAME + "." + OSS_HOST);
    52. request.SetRequestHeader("Date", utcGMT);
    53. request.SetRequestHeader("Authorization", authorization);
    54. // Set the body of the request
    55. UploadHandlerRaw uploadHandler = new UploadHandlerRaw(imageBytes);
    56. uploadHandler.contentType = contentType;
    57. request.uploadHandler = uploadHandler;
    58. // Send the request and wait for a response
    59. yield return request.SendWebRequest();
    60. if (request.result != UnityWebRequest.Result.Success)
    61. {
    62. Debug.LogError($"Error: {request.error}");
    63. Debug.LogError($"Response Code: {request.responseCode}");
    64. Debug.LogError($"Response Text: {request.downloadHandler.text}");
    65. }
    66. else
    67. Debug.Log(request.downloadHandler.text);
    68. }
    69. private string GetAuthorization(
    70. string method, string contentMD5, string contentType,
    71. string utcGMT, string canonicalizedOSSHeaders, string canonicalizedResource)
    72. {
    73. string data = method + "\n"
    74. + contentMD5 + "\n"
    75. + contentType + "\n"
    76. + utcGMT + "\n"
    77. + canonicalizedOSSHeaders
    78. + canonicalizedResource;
    79. Debug.Log("data:"+ data);
    80. string signature = ToHMACSHA1_Base64(ACCESS_KEY_SECRET, data);
    81. string authorization = "OSS " + ACCESS_KEY_ID + ":" + signature;
    82. return authorization;
    83. }
    84. private static string ToHMACSHA1_Base64(string key, string data)
    85. {
    86. using (HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key)))
    87. {
    88. byte[] dataBuffer = Encoding.UTF8.GetBytes(data);
    89. byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
    90. string result = Convert.ToBase64String(hashBytes);
    91. return result;
    92. }
    93. }
    94. private static string ToMD5(byte[] data)
    95. {
    96. using (MD5 md5Hash = MD5.Create())
    97. {
    98. byte[] hashBytes = md5Hash.ComputeHash(data);
    99. Debug.Log(hashBytes.Length);
    100. return Convert.ToBase64String(hashBytes);
    101. }
    102. }
    103. }

  • 相关阅读:
    华为昇腾云平台适配Baichuan2大模型记录
    【数据结构】二叉树链式存储及遍历
    为什么函数极值点的导数为零
    python多线程是如何工作
    学完基础的verilog语言后如何进一步学习fpga
    SpringCach
    steam搬砖到底能不能做?
    Pico Neo3使用Unity开发简明教程
    使用 message buffer 传递数据
    PTrade和QMT对比那个更好用?
  • 原文地址:https://blog.csdn.net/weixin_39766005/article/details/140044110