目录
使用 RFC 2104 中定义的 HMAC-SHA1 方法生成带有密钥的哈希值:
- private static string CalculateSignature(string secret, string data)
- {
- byte[] keyBytes = Encoding.UTF8.GetBytes(secret);
- byte[] dataBytes = Encoding.UTF8.GetBytes(data);
-
- using (var hmacsha1 = new HMACSHA1(keyBytes))
- {
- byte[] hashBytes = hmacsha1.ComputeHash(dataBytes);
-
- // 将哈希值转换为十六进制字符串
- StringBuilder hexString = new StringBuilder(hashBytes.Length * 2);
- foreach (byte b in hashBytes)
- {
- hexString.AppendFormat("{0:x2}", b);
- }
- return hexString.ToString();
- }
- }
- private static string Rfc3986Encode(string value)
- {
- // 使用 Uri.EscapeDataString 进行初步编码
- var encoded = Uri.EscapeDataString(value);
-
- // 根据 RFC 3986 的要求替换字符
- encoded = encoded.Replace("%20", "+");
- encoded = encoded.Replace("%21", "!");
- encoded = encoded.Replace("%27", "'");
- encoded = encoded.Replace("%28", "(");
- encoded = encoded.Replace("%29", ")");
- encoded = encoded.Replace("%7E", "~ ");
-
- return encoded;
- }
当前 UTC 时间,以 ISO 8601 yyyyMMddTHHmmssZ 格式表示:
string date = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");
HTTP 1.1 协议中规定的 GMT 时间:(示例:Wed, 01 Mar 2006 12:00:00 GMT )
- public static string GetCurrentDateTimeInStandardFormat()
- {
- // 获取当前时间并转换到指定时区
- var dateTimeOffset = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(8));
-
- // 将日期时间格式化为字符串
- var formattedDateTime = dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:sszzz");
-
- // 替换时区部分的冒号
- return formattedDateTime.Substring(0, 22) + formattedDateTime.Substring(23);
- }
RFC 1864 定义的请求体(Body) md5 摘要(128 位二进制表示,并使用 base64 编码):
- private static string CalculateMD5(byte[] data)
- {
- using (var md5 = MD5.Create())
- {
- byte[] hashBytes = md5.ComputeHash(data);
- return Convert.ToBase64String(hashBytes);
- }
- }
对 URL 中所有参数名、参数值单独 UriEncode,按参数名字母升序的顺序,依次将参数名、参数值用 = 及 & 拼接:
- private static string ConstructCanonicalQueryString(Dictionary<string, string> queryParams)
- {
- if (queryParams == null || queryParams.Count == 0)
- return "";
-
- var sortedQueryParams = queryParams.OrderBy(kvp => kvp.Key);
- var encodedQueryParams = sortedQueryParams.Select(kvp => $"{Rfc3986Encode(kvp.Key)}={Rfc3986Encode(kvp.Value)}");
-
- return string.Join("&", encodedQueryParams);
- }
下方是阿里云上传文件API鉴权及请求示例(其实接入SDK更方便一些)。(阿里云上传文件后路径为https://桶名称.oss-cn-beijing.aliyuncs.com/文件夹/文件)
- using UnityEngine;
- using System.Collections;
- using System.Security.Cryptography;
- using System.Text;
- using System;
- using System.IO;
- using UnityEngine.Networking;
-
-
- public class AliYunManager : MonoBehaviour
- {
- private const string OSS_HOST = "oss-cn-beijing.aliyuncs.com";//域名
- private const string BUCKET_NAME = "*****";//bucket名称
- private const string ACCESS_KEY_ID = "************";
- private const string ACCESS_KEY_SECRET = "**************";
-
- // Use this for initialization
- void Start()
- {
- UploadFileAsync("D:\\FCJProject\\YiDongYanFaBu\\StudentPartner\\StudentPartner\\Bundles\\StandaloneWindows\\DefaultPackage\\5.0.0\\1ba6bb9f41d66f71f7deb9d2d63b29e4.bundle", "/debug/PC/9.92.0");
- }
-
- ///
- ///
- ///
- /// 本地文件绝对路径
- /// 需要保存的文件在bucket上的相对路径,前后不需要加'/',也不需要加文件名
- public void UploadFileAsync(string filePath, string bucketPath)
- {
- StartCoroutine(UploadFile(filePath, bucketPath));
- }
-
- IEnumerator UploadFile(string filePath, string bucketPath)
- {
- // Load the image from file
- byte[] imageBytes = File.ReadAllBytes(filePath);
-
- string fileName = Path.GetFileName(filePath);
- string bucketFilePath = "/" + bucketPath + "/" + fileName;
- string url = "https://" + BUCKET_NAME + "." + OSS_HOST + bucketFilePath;
- string contentMD5 = "";// ToMD5(imageBytes);
- string contentType = "application/octet-stream";
- string utcGMT = DateTime.UtcNow.ToString("r");
- string canonicalizedOSSHeaders = "";
- string canonicalizedResource = "/" + BUCKET_NAME +bucketFilePath;
- string authorization = GetAuthorization("PUT", contentMD5, contentType, utcGMT, canonicalizedOSSHeaders, canonicalizedResource);
- Debug.Log("Authorization: " + authorization);
- Debug.Log("url: " + url);
- //Debug.Log("contentMD5: " + contentMD5);
- // Create UnityWebRequest
- UnityWebRequest request = new UnityWebRequest(url, "PUT");
- //request.uploadHandler = new UploadHandlerRaw(imageData);
- request.downloadHandler = new DownloadHandlerBuffer();
- // Set headers
- request.SetRequestHeader("Content-Length", imageBytes.Length.ToString());
- request.SetRequestHeader("Content-Type", contentType);
- request.SetRequestHeader("Host", BUCKET_NAME + "." + OSS_HOST);
- request.SetRequestHeader("Date", utcGMT);
- request.SetRequestHeader("Authorization", authorization);
-
- // Set the body of the request
- UploadHandlerRaw uploadHandler = new UploadHandlerRaw(imageBytes);
- uploadHandler.contentType = contentType;
-
- request.uploadHandler = uploadHandler;
-
- // Send the request and wait for a response
- yield return request.SendWebRequest();
-
- if (request.result != UnityWebRequest.Result.Success)
- {
- Debug.LogError($"Error: {request.error}");
- Debug.LogError($"Response Code: {request.responseCode}");
- Debug.LogError($"Response Text: {request.downloadHandler.text}");
-
- }
- else
- Debug.Log(request.downloadHandler.text);
- }
-
- private string GetAuthorization(
- string method, string contentMD5, string contentType,
- string utcGMT, string canonicalizedOSSHeaders, string canonicalizedResource)
- {
- string data = method + "\n"
- + contentMD5 + "\n"
- + contentType + "\n"
- + utcGMT + "\n"
- + canonicalizedOSSHeaders
- + canonicalizedResource;
-
- Debug.Log("data:"+ data);
- string signature = ToHMACSHA1_Base64(ACCESS_KEY_SECRET, data);
- string authorization = "OSS " + ACCESS_KEY_ID + ":" + signature;
-
- return authorization;
- }
-
- private static string ToHMACSHA1_Base64(string key, string data)
- {
- using (HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key)))
- {
- byte[] dataBuffer = Encoding.UTF8.GetBytes(data);
- byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
-
- string result = Convert.ToBase64String(hashBytes);
- return result;
- }
- }
-
- private static string ToMD5(byte[] data)
- {
- using (MD5 md5Hash = MD5.Create())
- {
- byte[] hashBytes = md5Hash.ComputeHash(data);
- Debug.Log(hashBytes.Length);
-
- return Convert.ToBase64String(hashBytes);
- }
- }
- }