2017-10-07 4 views
0

こちらの手順に従ってCosmosDb認証トークンを生成しようとしています: https://docs.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resourcesです。GoLangでCosmosDB認証トークンを生成する

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#の例を取り、走っ:

ここGoLangの私の実装では、(私は上記のドキュメントから「例のエンコーディング」セクションにリテラル値を持つすべてのパラメータが置き換え)ですこれは参照と同じパラメータで行われます。

これは私がC#実装(参照)から取得されるものです:

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

そして、これは私が私のGoLang実装から得るものです:

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

は明らかにI」 2つは同じではないので、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

は、これは私が期待していたよりも、見つけるために私の時間がかかりました。 1つの明白な問題があり、あなたがこの行に

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

をキーをデコードするbase64ではありませんあなたはそれを修正しませんでした

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形式を除く)。

関連する問題