2017-10-07 123 views
0

我試圖按照此處的說明生成CosmosDb身份驗證令牌: https://docs.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resources在GoLang中生成CosmosDB身份驗證令牌

這是我在GoLang實現(我更換了所有從上面的文檔「示例編碼」一節中找到的文字值參數):

import(
    "crypto/hmac" 
    "crypto/sha256" 
    "encoding/base64" 
    "net/url") 

func generateAuthToken(
    verb string, 
    resourceType string, 
    resourceId string, 
    date string, 
    base64Key string) string { 

    // Example Key 
    base64Key := "dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5JiwvW0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==" 
    msg := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", 
     "get",       //verb 
     "dbs",       //resourceId 
     "dbs/todolist",     //resourceLink 
     "thu, 27 apr 2017 00:51:12 gmt", //RFC1123 date 
     "") 

    hasher := hmac.New(sha256.New, []byte(base64Key)) 
    hasher.Write([]byte(msg)) 
    signature := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) 

    authHeader := fmt.Sprintf("type=master&ver=1.0&sig=%s", signature) 
    return url.QueryEscape(authHeader) 
} 

我也採取了從鏈接的C#示例就跑它具有與參考相同的參數。

這是我從C#實現獲得(參考):

"type%3Dmaster%26ver%3D1.0%26sig%3DSGWmGNFZlBH%2Bt9QCvuMy%2FVsbBAOKLbxsgy3Z7aG0PdA%3D" 

這是我從我的GoLang實現獲取:

"type%3Dmaster%26ver%3D1.0%26sig%3Dwst1NDxfOeoYMurn69DgZtJUQOrgxFz%2Bp6A2vKnXxEI%3D" 

顯然我m在GoLang實現中做了什麼錯誤,因爲兩者不相同(可能錯誤地使用散列庫?)

爲了便於參考,這裏的C#實現:

static void Main(string[] args) { 
     string token = GenerateAuthToken(
      "get", 
      "dbs", 
      "dbs/todolist", 
      "thu, 27 apri 2017 00:51:12 gmt", 
      "dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5JiwvW0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==", 
      "master", 
      "1.0"); 
} 

static string GenerateAuthToken(string verb, string resourceType, string resourceId, string date, string key, string keyType, string tokenVersion) 
{ 
     var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) }; 

     verb = verb ?? ""; 
     resourceType = resourceType ?? ""; 
     resourceId = resourceId ?? ""; 

     string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n", 
      verb.ToLowerInvariant(), 
      resourceType.ToLowerInvariant(), 
      resourceId, 
      date.ToLowerInvariant(), 
      ""); 

     byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad)); 
     string signature = Convert.ToBase64String(hashPayLoad); 

     return System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}", 
      keyType, 
      tokenVersion, 
      signature)); 
} 

回答

3

這花了我再找到比我本來希望。有一個明顯的問題,你是不是Base64編碼在這條線的解碼關鍵

hasher := hmac.New(sha256.New, []byte(base64Key)) 

你應該這樣做

hmacKey, _ := base64.StdEncoding.DecodeString(base64Key) 
// handle error 
hasher := hmac.New(sha256.New, hmacKey) 

但即使這樣,也沒有解決它。直到我終於想通了,這種差異

C# "thu, 27 apri 2017 00:51:12 gmt" 
Go "thu, 27 apr 2017 00:51:12 gmt" 

這工作

func generateAuthToken(
    verb string, 
    resourceType string, 
    resourceId string, 
    date string, 
    base64Key string) string { 

    msg := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", 
     verb, 
     resourceType, 
     resourceId, 
     date, 
     "") 

    hmacKey, _ := base64.StdEncoding.DecodeString(base64Key) 
    // handle error 
    hasher := hmac.New(sha256.New, hmacKey) 
    hasher.Write([]byte(msg)) 
    signature := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) 

    authHeader := fmt.Sprintf("type=master&ver=1.0&sig=%s", signature) 
    return url.QueryEscape(authHeader) 
} 

這裏是一個Go Playground Link

所以,圍棋版本幾乎是正確的(除了鍵)和C#部分幾乎是正確的(非RFC1123格式除外)。