# SSO 的哈希密钥 + 载荷

**URL:** <https://meta.discourse.org/t/hashing-secret-payload-for-sso/169284>\
**Category:** SSO\
**Created:** [2020年十一月4日 22:01 UTC](https://meta.discourse.org/t/hashing-secret-payload-for-sso/169284 "2020-11-04T22:01:14Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![nategoethel](https://avatars.discourse-cdn.com/v4/letter/n/90ced4/32.png) [@nategoethel](https://meta.discourse.org/u/nategoethel)\
**Post date:** [2020年十一月4日 22:17 UTC](https://meta.discourse.org/t/hashing-secret-payload-for-sso/169284/3 "2020-11-04T22:17:09Z")

</div>

解析 `payload` 后发现，默认情况下它是 base64 编码的，但对该 base64 编码后的 payload 进行 256SHA 哈希计算的结果不正确。我使用的是原始帖子中的示例密钥和 URL。

以下代码产生的输出如下：

```
 payloadURL = bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI=

sig = 2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56
payloadRaw = nonce=cb68251eefb5211e58c00ff1395f0c0b
payload256 = KCiqKYmXIrNaLxkdNO+bPOaV4Obu7EfetG1YjXDHy1Y=

```

我的代码：

```
testURL := "http://www.example.com/discourse/sso?sso=bm9uY2U9Y2I2ODI1MWVlZmI1MjExZTU4YzAwZmYxMzk1ZjBjMGI%3D%0A\u0026sig=2828aa29899722b35a2f191d34ef9b3ce695e0e6eeec47deb46d588d70c7cb56"

ssoSecret := "d836444a9e4084d5b224a60c208dce14"

// 从 URL 查询参数中获取 payload 和 sig
u, err := url.Parse(testURL)
if err != nil {
    log.Fatal(err)
}

q := u.Query()
payloadURL := strings.Trim(fmt.Sprint(q["sso"]), "=[]")
sig := strings.Trim(fmt.Sprint(q["sig"]), "[]")

fmt.Printf("payloadURL = %s\n", payloadURL)
fmt.Printf("sig = %s\n", sig)

// 从 base64 版本中获取原始 payload
payloadRaw, err := base64.StdEncoding.DecodeString(payloadURL)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("payloadRaw = %s\n", payloadRaw)

key := []byte(ssoSecret)
message := []byte(payloadURL)
hash := hmac.New(sha256.New, key)
hash.Write(message)
payload256 := base64.StdEncoding.EncodeToString(hash.Sum(nil))
if err != nil {
    log.Fatal(err)
}

fmt.Printf("payload256 = %s\n", payload256)

// sig 是十六进制编码的，因此将哈希后的 payload 也进行十六进制编码以便比较。
//hashAsString := hex.EncodeToString(hash.Sum(nil))

// 将 payload 的十六进制编码哈希值与十六进制编码的 sig 进行比较
if strings.Compare(payload256, sig) != 0 {
    log.Fatal(err)
}

```

更新：我在将生成的 HMAC-SHA256 哈希值编码为十六进制后修复了此问题（签名也是十六进制编码的）。另请参阅 [这篇帖子](https://meta.discourse.org/t/hmac-256-example-on-official-sso-page/92546/2)，其中指出 SSO 指南中的示例有误。因此，我修改了以下代码：

```
key := []byte(ssoSecret)
message := []byte(payloadURL)
hash := hmac.New(sha256.New, key)
hash.Write(message)
payload256 := hex.EncodeToString(hash.Sum(nil))
if err != nil {
    log.Fatal(err)
}

```

---

_[View the full topic](https://meta.discourse.org/t/hashing-secret-payload-for-sso/169284)._
