騰訊雲COS請求簽名C#版


 

網上沒有找到C#版 的簽名代碼,只好去一字一字的讀SDK文檔,自己寫了一個,沒有在CSDN搞什么積分下載,寫的不好勿噴,能用點個贊再走.

空參和空的請求頭是通過了與官方網的驗證了,沒有問題,可以直接下載COS中的文件.如果要帶參,帶頭就自己試一下,如有有錯告訴我一下再走.

文件名沒有做過中文名的,我沒有打算存中文的文件名,所以沒有字符串特殊處理,用最簡單的方式達到目的.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

/// <summary>
/// CosSignature 的摘要說明  生成騰訊雲COS簽名類
/// ======作者:rovedog
/// ======日期:2020.2.24
/// </summary>
public class CosSignature
{

    /// <summary>
    /// 密碼ID
    /// </summary>
    public string SecretId { get; set; }

    /// <summary>
    /// 密碼內容
    /// </summary>
    public string SecretKey { get; set; }

    /// <summary>
    /// 開始時間
    /// </summary>
    public DateTime StartTimestamp { get; set; } = DateTime.Now;

    /// <summary>
    /// 簽名有效期,單位秒,默認10分鍾
    /// </summary>
    public int ExpiredTime { get; set; } = 600;

    /// <summary>
    /// 請求參數
    /// </summary>
    public NameValueCollection NVC;

    /// <summary>
    /// 請求頭
    /// </summary>
    public WebHeaderCollection   RequestHeader;

    /// <summary>
    /// 請求方法
    /// </summary>
    public string HttpMethod { get; set; } = "get";

    /// <summary>
    /// 請求的url
    /// 若需驗證url參數則填寫,key小寫,value需要進行URLEncode,多個key以字典排序,如:max-keys=20&amp;prefix=abc
    /// </summary>
    ///<example>簽名中的請求路徑以 / 開頭,無需URLEncode,如:/ 、 /a/b 或 /測試.jpg</example>
    public string HttpURI { get; set; }

    /// <summary>
    /// 實例初始化對象
    /// </summary>
    /// <param name="secretId"></param>
    /// <param name="secretKey"></param>
    /// <param name="HttpUri"></param>
    public CosSignature(string secretId, string secretKey, string HttpUri = "/")
    {
        HttpURI = HttpUri;
        SecretId = secretId;
        SecretKey = secretKey;
    }

    /// <summary>
    /// 創建一個簽名
    /// </summary>
    /// <returns></returns>
    public Return Create()
    {
        Return R = new Return();
        HttpMethod = HttpMethod.ToLower();
        List<string> M = new List<string> {"get", "post", "put", "delete", "head"};
        if (M.IndexOf(HttpMethod) == -1)
        {
            R.BOOL = false;
            R.Error = "未知請求方法!";
            return R;
        }

        if (string.IsNullOrEmpty(SecretId))
        {
            R.BOOL = false;
            R.Error = "密碼ID為空!";
            return R;
        }

        if (string.IsNullOrEmpty(SecretKey))
        {
            R.BOOL = false;
            R.Error = "密碼內容為空!";
            return R;
        }
        if (StartTimestamp > DateTime.Now) StartTimestamp = DateTime.Now;
        //步驟1:生成 KeyTime
        long startTimestamp = (StartTimestamp.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        long endTimestamp = startTimestamp + ExpiredTime;
        string keyTime = string.Format("{0};{1}", startTimestamp, endTimestamp);
        //步驟2:生成 SignKey
        string SignKey = HMACSHA1(SecretKey, keyTime);
        //步驟3:生成 UrlParamList 和 HttpParameters
        List<string> Key = new List<string>();
        List<string> KeyValue = new List<string>();
        Dictionary<string, string> Param = new Dictionary<string, string>();
        if (NVC != null)
        {
            foreach (var k in NVC.Keys)
            {
                string kk = HttpUtility.UrlEncode(k.ToString()).ToLower();
                Param.Add(kk, HttpUtility.UrlEncode(NVC[k.ToString()]));
                Key.Add(kk);
            }

            Key.Sort();
            foreach (var k in Key)
            {
                KeyValue.Add(string.Format("{0}={1}", k, Param[k]));
            }
        }
        string HttpParameters = NVC != null ? string.Join("&", KeyValue.ToArray()) : "";
        string UrlParamList = NVC != null ? string.Join(";", Key) : "";
        //步驟4:生成 HeaderList 和 HttpHeaders
        Key.Clear();
        Dictionary<string, string> Hearder = new Dictionary<string, string>();
        if (RequestHeader != null)
        {
            foreach (var k in RequestHeader.AllKeys)
            {
                string kk = HttpUtility.UrlEncode(k).ToLower();
                Hearder.Add(kk, HttpUtility.UrlEncode(RequestHeader[k]));
                Key.Add(kk);
            }

            Key.Sort();
            KeyValue.Clear();
            foreach (var k in Key)
            {
                KeyValue.Add(string.Format("{0}={1}", k, Hearder[k]));
            }
        }
        string HttpHeaders = RequestHeader != null ? string.Join("&", KeyValue.ToArray()) : "";
        string HeaderList = RequestHeader != null ? string.Join(";", Key) : "";
        //步驟5:生成 HttpString
        string HttpString = string.Format("{0}\n{1}\n{2}\n{3}\n", HttpMethod, HttpURI, HttpParameters, HttpHeaders);
        //步驟6:生成 StringToSign
        string StringToSign = string.Format("sha1\n{0}\n{1}\n", keyTime, SHA1(HttpString));
        //步驟7:生成 Signature
        string Signature = HMACSHA1(SignKey, StringToSign);
        //步驟8:生成簽名
        R.STRING = string.Format("q-sign-algorithm=sha1&q-ak={0}&q-sign-time={1}&q-key-time={1}&q-header-list={2}&q-url-param-list={3}&q-signature={4}", SecretId, keyTime, HeaderList, UrlParamList, Signature);
        //List<string> o = new List<string> {string.Format("SignKey={0}", SignKey), string.Format("HttpString={0}", HttpString), string.Format("StringToSign={0}", StringToSign)};
        //R.OBJECT = string.Join("<br/>", o);
        return R;
    }

    /// <summary>
    /// HMACSHA1加密方法
    /// </summary>
    /// <param name="content"></param>
    /// <param name="secretKey"></param>
    /// <returns></returns>
    public static string HMACSHA1(string secretKey, string content)
    {
        byte[] keyByte = Encoding.Default.GetBytes(secretKey);
        HMACSHA1 hmacsha1 = new HMACSHA1(keyByte);
        byte[] messageBytes = Encoding.Default.GetBytes(content);
        byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
        StringBuilder sb = new StringBuilder("");
        foreach (byte b in hashmessage)
        {
            sb.AppendFormat("{0:x2}", b);
        }
        return sb.ToString();
    }

    /// <summary>
    /// SHA1加密方法
    /// </summary>
    /// <param name="content"></param>
    /// <returns></returns>
    public static string SHA1(string content)
    {
        var sha1 = new SHA1CryptoServiceProvider();
        byte[] c = Encoding.Default.GetBytes(content);
        byte[] sc = sha1.ComputeHash(c);
        StringBuilder sb = new StringBuilder("");
        foreach (byte b in sc)
        {
            sb.AppendFormat("{0:x2}", b);
        }
        return sb.ToString();
    }
}

 

 

 

其中Return是自創了一個神奇的返回類型,想怎么返回就怎么返回,適用於不太講究性能和並發的應用,希望大佬指點迷津,不用的話改成自己的字符返回類型,

/// <summary>
/// 需要多個返值的值類型 2019.4.10
/// </summary>
[Serializable]
public class Return
{
    public Return()
    {
        BOOL = true;
        INT = 0;
        STRING = "";
        Error = "";
        Information = "";
        ExcuteTime = 0;
    }

    /// <summary>
    /// 布爾型返回結果,默認是true
    /// </summary>
    public bool BOOL { get; set; }

    /// <summary>
    /// 整型返回結果
    /// </summary>
    public int INT { get; set; }

    /// <summary>
    /// 字符串類型結果返回
    /// </summary>
    public string STRING { get; set; }

    /// <summary>
    /// 可序列化的object類型返回結果
    /// </summary>
    public object OBJECT { get; set; }
    /// <summary>
    /// 執行的相關信息
    /// </summary>
    public string Information { get; set; }

    /// <summary>
    /// 錯誤消息
    /// </summary>
    public string Error { get; set; }
    /// <summary>
    /// 執行時間
    /// </summary>
    public long ExcuteTime { get; set; }
}

 

 

補記:后台與官方客服聯系,有提供  :https://cloud.tencent.com/document/product/436/32873 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM