我正在尝试按照此处的说明生成 CosmosDb 身份验证 token : https://learn.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resources .
这是我在 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"
很明显,我在 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));
}
最佳答案
这比我希望的要花更长的时间才找到。有一个明显的问题,你没有对这一行的 key 进行 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
因此,Go 版本几乎正确( key 除外),C# 部分几乎正确(非 RFC1123 格式除外)。
关于go - 在 GoLang 中生成 CosmosDB 身份验证 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46625098/