Golang令牌验证错误

huangapple go评论110阅读模式
英文:

Golang token validation error

问题

我需要验证一个 Google id_token,其中一步是检查令牌的签名。

首先,我从以下网址获取证书:https://www.googleapis.com/oauth2/v2/certs,并从证书中提取模数(n)和指数(e)部分,并生成一个公钥。然后,我拆分令牌(头部、有效载荷和摘要),然后将解码后的header.payload与 Google 公钥和摘要一起发送到 rsa 函数rsa.VerifyPKCS1v15

我在验证过程中遇到了这个错误:crypto/rsa: verification error

以下是代码(我已经用// validation here fails注释了验证失败的部分):

  1. func ValidateIDToken(auth_token string) (err error){
  2. res, err := http.Get("https://www.googleapis.com/oauth2/v2/certs")
  3. if err != nil {
  4. log.Fatal(err)
  5. return err
  6. }
  7. certs, err := ioutil.ReadAll(res.Body)
  8. res.Body.Close()
  9. if err != nil {
  10. log.Fatal(err)
  11. return err
  12. }
  13. //get modulus and exponent from the cert
  14. var goCertificate interface{}
  15. err = json.Unmarshal(certs, &goCertificate)
  16. k := goCertificate.(map[string]interface{})["keys"]
  17. j := k.([]interface{})
  18. x := j[1]
  19. h := x.(map[string]interface{})["n"]
  20. g := x.(map[string]interface{})["e"]
  21. e64 := base64.StdEncoding
  22. //build the google pub key
  23. nStr := h.(string)
  24. decN, err := base64.StdEncoding.DecodeString(nStr)
  25. if err != nil {
  26. log.Println(err)
  27. return
  28. }
  29. n := big.NewInt(0)
  30. n.SetBytes(decN)
  31. eStr := g.(string)
  32. decE, err := base64.StdEncoding.DecodeString(eStr)
  33. if err != nil {
  34. log.Println(err)
  35. return
  36. }
  37. var eBytes []byte
  38. if len(decE) < 8 {
  39. eBytes = make([]byte, 8-len(decE), 8)
  40. eBytes = append(eBytes, decE...)
  41. } else {
  42. eBytes = decE
  43. }
  44. eReader := bytes.NewReader(eBytes)
  45. var e uint64
  46. err = binary.Read(eReader, binary.BigEndian, &e)
  47. if err != nil {
  48. log.Println(err)
  49. return
  50. }
  51. pKey := rsa.PublicKey{N: n, E: int(e)}
  52. w := strings.SplitAfter(auth_token, ".")
  53. for i, val := range w {
  54. w[i] = strings.Trim(val, ".")
  55. }
  56. y := w[0:2]
  57. //Join just the first two parts, the header and the payload without the signature
  58. o := strings.Join(y, ".")
  59. headerOauth := DecodeB64(nil,[]byte(w[0]),e64)
  60. inblockOauth := DecodeB64(nil,[]byte(w[1]),e64)
  61. toHash := string(headerOauth) + "}.&" + string(inblockOauth)
  62. digestOauth := DecodeB64(nil, []byte(w[2]),e64)
  63. hasherOauth := sha256.New()
  64. hasherOauth.Write([]byte(toHash))
  65. // validation here fails
  66. err = rsa.VerifyPKCS1v15(&pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  67. if err != nil {
  68. log.Printf("Error verifying key %s",err.Error())
  69. return err
  70. }
  71. return err
  72. }

更新 1:
这是包含头部和有效载荷的 toHash 变量:

  1. {"alg":"RS256","kid":"d91c503452d0f8849200a321ffbf7dea76f9371d"}.{"iss":"accounts.google.com","sub":"104869993929250743503","azp":"client_email_till_@.apps.googleusercontent.com","email":"test@test.hr","at_hash":"KAm1M0g-ssMkdjds7jkbVQ","email_verified":true,"aud":client_email_till_@.apps.googleusercontent.com","hd":"test.hr","iat":1412246551,"exp":1412250451}

更新 2:
感谢 @Florent Morselli 的回复,我再次尝试了一下,但仍然失败了。这次我只对第三部分(签名)进行了 B64 解码,但错误仍然存在。请问有人可以使用他们的 auth_token 进行测试吗?只需将 ID 令牌放入下面代码中的 auth_token 变量中,然后告诉我是否成功,谢谢。

  1. package main
  2. import(
  3. "strings"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "log"
  8. "encoding/base64"
  9. "io/ioutil"
  10. "crypto"
  11. "crypto/sha256"
  12. "crypto/rsa"
  13. "bytes"
  14. "encoding/json"
  15. "net/http"
  16. "math/big"
  17. )
  18. func main() {
  19. auth_token := ""
  20. w := strings.SplitAfter(auth_token, ".")
  21. for i, val := range w {
  22. w[i] = strings.Trim(val, ".")
  23. }
  24. headerOauth, err := base64.URLEncoding.DecodeString(w[0])
  25. res, err := http.Get("https://www.googleapis.com/oauth2/v2/certs")
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. certs, err := ioutil.ReadAll(res.Body)
  30. res.Body.Close()
  31. if err != nil {
  32. fmt.Println(err)
  33. }
  34. //extract kid from token header
  35. var header interface{}
  36. err = json.Unmarshal([]byte(string(headerOauth)+"}"), &header)
  37. token_kid := header.(map[string]interface{})["kid"]
  38. fmt.Println("By 1")
  39. //get modulus and exponent from the cert
  40. var goCertificate interface{}
  41. err = json.Unmarshal(certs, &goCertificate)
  42. //k := goCertificate.(map[string]interface{})[token_kid.(string)]
  43. k := goCertificate.(map[string]interface{})["keys"]
  44. ///*mod & exp part
  45. j := k.([]interface{})
  46. x := j[0]
  47. if j[0].(map[string]interface{})["kid"] == token_kid {
  48. x = j[0]
  49. }else{
  50. if j[1].(map[string]interface{})["kid"] == token_kid {
  51. x = j[1]
  52. }else{
  53. errors.New("Token is not valid, kid from token and certificate don't match")
  54. }
  55. }
  56. h := x.(map[string]interface{})["n"]
  57. g := x.(map[string]interface{})["e"]
  58. //build the google pub key
  59. nStr := h.(string)
  60. decN, err := base64.URLEncoding.DecodeString(nStr)
  61. if err != nil {
  62. fmt.Println(err)
  63. return
  64. }
  65. n := big.NewInt(0)
  66. n.SetBytes(decN)
  67. eStr := g.(string)
  68. decE, err := base64.URLEncoding.DecodeString(eStr)
  69. if err != nil {
  70. fmt.Println(err)
  71. return
  72. }
  73. var eBytes []byte
  74. if len(decE) < 8 {
  75. eBytes = make([]byte, 8-len(decE), 8)
  76. eBytes = append(eBytes, decE...)
  77. } else {
  78. eBytes = decE
  79. }
  80. eReader := bytes.NewReader(eBytes)
  81. var e uint64
  82. err = binary.Read(eReader, binary.BigEndian, &e)
  83. if err != nil {
  84. log.Println(err)
  85. return
  86. }
  87. pKey := rsa.PublicKey{N: n, E: int(e)}
  88. //inblockOauth := base64.URLEncoding.DecodeString(w[1])
  89. toHash := w[0] + "." + w[1]
  90. digestOauth, err := base64.URLEncoding.DecodeString(w[2])
  91. hasherOauth := sha256.New()
  92. hasherOauth.Write([]byte(toHash))
  93. // verification here fails
  94. err = rsa.VerifyPKCS1v15(&pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  95. if err != nil {
  96. fmt.Printf("Error verifying key %s",err.Error())
  97. }
  98. }

希望对你有所帮助!

英文:

I need to validate a google id_token and one step involves to check the token signature.

First I obtain the certificate from: https://www.googleapis.com/oauth2/v2/certs and extract the modulus (n) and exponent (e) part from the certificate and generate a public key, then I take apart the token (header, payload and digest), after then I send the decoded header.payload together with the Google pKey + digest to the rsa function rsa.VerifyPKCS1v15.

I am stuck with this verification error: crypto/rsa: verification error

Here's the code (I commented part of code which fails with // validation here fails):

  1. func ValidateIDToken(auth_token string) (err error){
  2. res, err := http.Get(&quot;https://www.googleapis.com/oauth2/v2/certs&quot;)
  3. if err != nil {
  4. log.Fatal(err)
  5. return err
  6. }
  7. certs, err := ioutil.ReadAll(res.Body)
  8. res.Body.Close()
  9. if err != nil {
  10. log.Fatal(err)
  11. return err
  12. }
  13. //get modulus and exponent from the cert
  14. var goCertificate interface{}
  15. err = json.Unmarshal(certs, &amp;goCertificate)
  16. k := goCertificate.(map[string]interface{})[&quot;keys&quot;]
  17. j := k.([]interface{})
  18. x := j[1]
  19. h := x.(map[string]interface{})[&quot;n&quot;]
  20. g := x.(map[string]interface{})[&quot;e&quot;]
  21. e64 := base64.StdEncoding
  22. //build the google pub key
  23. nStr := h.(string)
  24. decN, err := base64.StdEncoding.DecodeString(nStr)
  25. if err != nil {
  26. log.Println(err)
  27. return
  28. }
  29. n := big.NewInt(0)
  30. n.SetBytes(decN)
  31. eStr := g.(string)
  32. decE, err := base64.StdEncoding.DecodeString(eStr)
  33. if err != nil {
  34. log.Println(err)
  35. return
  36. }
  37. var eBytes []byte
  38. if len(decE) &lt; 8 {
  39. eBytes = make([]byte, 8-len(decE), 8)
  40. eBytes = append(eBytes, decE...)
  41. } else {
  42. eBytes = decE
  43. }
  44. eReader := bytes.NewReader(eBytes)
  45. var e uint64
  46. err = binary.Read(eReader, binary.BigEndian, &amp;e)
  47. if err != nil {
  48. log.Println(err)
  49. return
  50. }
  51. pKey := rsa.PublicKey{N: n, E: int(e)}
  52. w := strings.SplitAfter(auth_token, &quot;.&quot;)
  53. for i, val := range w {
  54. w[i] = strings.Trim(val, &quot;.&quot;)
  55. }
  56. y := w[0:2]
  57. //Join just the first two parts, the header and the payload without the signature
  58. o := strings.Join(y, &quot;.&quot;)
  59. headerOauth := DecodeB64(nil,[]byte(w[0]),e64)
  60. inblockOauth := DecodeB64(nil,[]byte(w[1]),e64)
  61. toHash := string(headerOauth) + &quot;}.&quot; + string(inblockOauth)
  62. digestOauth := DecodeB64(nil, []byte(w[2]),e64)
  63. hasherOauth := sha256.New()
  64. hasherOauth.Write([]byte(toHash))
  65. // validation here fails
  66. err = rsa.VerifyPKCS1v15(&amp;pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  67. if err != nil {
  68. log.Printf(&quot;Error verifying key %s&quot;,err.Error())
  69. return err
  70. }
  71. return err
  72. }

UPDATE 1:
Here is toHash var which contains header and payload:

  1. {&quot;alg&quot;:&quot;RS256&quot;,&quot;kid&quot;:&quot;d91c503452d0f8849200a321ffbf7dea76f9371d&quot;}.{&quot;iss&quot;:&quot;accounts.google.com&quot;,&quot;sub&quot;:&quot;104869993929250743503&quot;,&quot;azp&quot;:&quot;client_email_till_@.apps.googleusercontent.com&quot;,&quot;email&quot;:&quot;test@test.hr&quot;,&quot;at_hash&quot;:&quot;KAm1M0g-ssMkdjds7jkbVQ&quot;,&quot;email_verified&quot;:true,&quot;aud&quot;:client_email_till_@.apps.googleusercontent.com&quot;,&quot;hd&quot;:&quot;test.hr&quot;,&quot;iat&quot;:1412246551,&quot;exp&quot;:1412250451}

UPDATE 2:
Thanks for the reply @Florent Morselli, I tried it again and it failed, I B64decoded this time only the third part (signature) but the error was still there, could someone test it with their
auth_token, just put the ID token in auth_token variable below in the code, and let me know if it worked, thank You.

  1. package main
  2. import(
  3. &quot;strings&quot;
  4. &quot;encoding/binary&quot;
  5. &quot;errors&quot;
  6. &quot;fmt&quot;
  7. &quot;log&quot;
  8. &quot;encoding/base64&quot;
  9. &quot;io/ioutil&quot;
  10. &quot;crypto&quot;
  11. &quot;crypto/sha256&quot;
  12. &quot;crypto/rsa&quot;
  13. &quot;bytes&quot;
  14. &quot;encoding/json&quot;
  15. &quot;net/http&quot;
  16. &quot;math/big&quot;
  17. )
  18. func main() {
  19. auth_token := &quot;&quot;
  20. w := strings.SplitAfter(auth_token, &quot;.&quot;)
  21. for i, val := range w {
  22. w[i] = strings.Trim(val, &quot;.&quot;)
  23. }
  24. headerOauth, err := base64.URLEncoding.DecodeString(w[0])
  25. res, err := http.Get(&quot;https://www.googleapis.com/oauth2/v2/certs&quot;)
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. certs, err := ioutil.ReadAll(res.Body)
  30. res.Body.Close()
  31. if err != nil {
  32. fmt.Println(err)
  33. }
  34. //extract kid from token header
  35. var header interface{}
  36. err = json.Unmarshal([]byte(string(headerOauth)+&quot;}&quot;), &amp;header)
  37. token_kid := header.(map[string]interface{})[&quot;kid&quot;]
  38. fmt.Println(&quot;By 1&quot;)
  39. //get modulus and exponent from the cert
  40. var goCertificate interface{}
  41. err = json.Unmarshal(certs, &amp;goCertificate)
  42. //k := goCertificate.(map[string]interface{})[token_kid.(string)]
  43. k := goCertificate.(map[string]interface{})[&quot;keys&quot;]
  44. ///*mod &amp; exp part
  45. j := k.([]interface{})
  46. x := j[0]
  47. if j[0].(map[string]interface{})[&quot;kid&quot;] == token_kid {
  48. x = j[0]
  49. }else{
  50. if j[1].(map[string]interface{})[&quot;kid&quot;] == token_kid {
  51. x = j[1]
  52. }else{
  53. errors.New(&quot;Token is not valid, kid from token and certificate don&#39;t match&quot;)
  54. }
  55. }
  56. h := x.(map[string]interface{})[&quot;n&quot;]
  57. g := x.(map[string]interface{})[&quot;e&quot;]
  58. //build the google pub key
  59. nStr := h.(string)
  60. decN, err := base64.URLEncoding.DecodeString(nStr)
  61. if err != nil {
  62. fmt.Println(err)
  63. return
  64. }
  65. n := big.NewInt(0)
  66. n.SetBytes(decN)
  67. eStr := g.(string)
  68. decE, err := base64.URLEncoding.DecodeString(eStr)
  69. if err != nil {
  70. fmt.Println(err)
  71. return
  72. }
  73. var eBytes []byte
  74. if len(decE) &lt; 8 {
  75. eBytes = make([]byte, 8-len(decE), 8)
  76. eBytes = append(eBytes, decE...)
  77. } else {
  78. eBytes = decE
  79. }
  80. eReader := bytes.NewReader(eBytes)
  81. var e uint64
  82. err = binary.Read(eReader, binary.BigEndian, &amp;e)
  83. if err != nil {
  84. log.Println(err)
  85. return
  86. }
  87. pKey := rsa.PublicKey{N: n, E: int(e)}
  88. //inblockOauth := base64.URLEncoding.DecodeString(w[1])
  89. toHash := w[0] + &quot;.&quot; + w[1]
  90. digestOauth, err := base64.URLEncoding.DecodeString(w[2])
  91. hasherOauth := sha256.New()
  92. hasherOauth.Write([]byte(toHash))
  93. // verification here fails
  94. err = rsa.VerifyPKCS1v15(&amp;pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  95. if err != nil {
  96. fmt.Printf(&quot;Error verifying key %s&quot;,err.Error())
  97. }
  98. }

答案1

得分: 5

根据聊天中的解释,问题在于如果头部和签名缺少"=",则Base64解码器无法解码它们。

你只需要使用以下代码添加它们:

  1. if m := len(h_) % 4; m != 0 {
  2. h_ += strings.Repeat("=", 4-m)
  3. }

以下是完整的代码:

  1. package main
  2. import(
  3. "strings"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "log"
  8. "encoding/base64"
  9. "io/ioutil"
  10. "crypto"
  11. "crypto/sha256"
  12. "crypto/rsa"
  13. "bytes"
  14. "encoding/json"
  15. "net/http"
  16. "math/big"
  17. )
  18. func main() {
  19. auth_token := ""
  20. w := strings.Split(auth_token, ".")
  21. h_, s_ := w[0], w[2]
  22. if m := len(h_) % 4; m != 0 {
  23. h_ += strings.Repeat("=", 4-m)
  24. }
  25. if m := len(s_) % 4; m != 0 {
  26. s_ += strings.Repeat("=", 4-m)
  27. }
  28. headerOauth, err := base64.URLEncoding.DecodeString(h_)
  29. res, err := http.Get("https://www.googleapis.com/oauth2/v2/certs")
  30. if err != nil {
  31. fmt.Println(err)
  32. }
  33. certs, err := ioutil.ReadAll(res.Body)
  34. res.Body.Close()
  35. if err != nil {
  36. fmt.Println(err)
  37. }
  38. //extract kid from token header
  39. var header interface{}
  40. err = json.Unmarshal([]byte(string(headerOauth)), &header)
  41. token_kid := header.(map[string]interface{})["kid"]
  42. fmt.Println("By 1")
  43. //get modulus and exponent from the cert
  44. var goCertificate interface{}
  45. err = json.Unmarshal(certs, &goCertificate)
  46. //k := goCertificate.(map[string]interface{})[token_kid.(string)]
  47. k := goCertificate.(map[string]interface{})["keys"]
  48. ///*mod & exp part
  49. j := k.([]interface{})
  50. x := j[0]
  51. if j[0].(map[string]interface{})["kid"] == token_kid {
  52. x = j[0]
  53. }else{
  54. if j[1].(map[string]interface{})["kid"] == token_kid {
  55. x = j[1]
  56. }else{
  57. errors.New("Token is not valid, kid from token and certificate don't match")
  58. }
  59. }
  60. h := x.(map[string]interface{})["n"]
  61. g := x.(map[string]interface{})["e"]
  62. //build the google pub key
  63. nStr := h.(string)
  64. decN, err := base64.URLEncoding.DecodeString(nStr)
  65. if err != nil {
  66. fmt.Println(err)
  67. return
  68. }
  69. n := big.NewInt(0)
  70. n.SetBytes(decN)
  71. eStr := g.(string)
  72. decE, err := base64.URLEncoding.DecodeString(eStr)
  73. if err != nil {
  74. fmt.Println(err)
  75. return
  76. }
  77. var eBytes []byte
  78. if len(decE) < 8 {
  79. eBytes = make([]byte, 8-len(decE), 8)
  80. eBytes = append(eBytes, decE...)
  81. } else {
  82. eBytes = decE
  83. }
  84. eReader := bytes.NewReader(eBytes)
  85. var e uint64
  86. err = binary.Read(eReader, binary.BigEndian, &e)
  87. if err != nil {
  88. log.Println(err)
  89. return
  90. }
  91. pKey := rsa.PublicKey{N: n, E: int(e)}
  92. //inblockOauth := base64.URLEncoding.DecodeString(w[1])
  93. toHash := w[0] + "." + w[1]
  94. digestOauth, err := base64.URLEncoding.DecodeString(s_)
  95. hasherOauth := sha256.New()
  96. hasherOauth.Write([]byte(toHash))
  97. // verification of the signature
  98. err = rsa.VerifyPKCS1v15(&pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  99. if err != nil {
  100. fmt.Printf("Error verifying key %s",err.Error())
  101. }
  102. fmt.Printf("OK!")
  103. }
英文:

As explained on the chat, the problem is that the Base64 decoder is unable to decode the header and the signature if they are missing "=".

You just have to add them with the following code:

  1. if m := len(h_) % 4; m != 0 {
  2. h_ += strings.Repeat(&quot;=&quot;, 4-m)
  3. }

Here is the complete code:

  1. package main
  2. import(
  3. &quot;strings&quot;
  4. &quot;encoding/binary&quot;
  5. &quot;errors&quot;
  6. &quot;fmt&quot;
  7. &quot;log&quot;
  8. &quot;encoding/base64&quot;
  9. &quot;io/ioutil&quot;
  10. &quot;crypto&quot;
  11. &quot;crypto/sha256&quot;
  12. &quot;crypto/rsa&quot;
  13. &quot;bytes&quot;
  14. &quot;encoding/json&quot;
  15. &quot;net/http&quot;
  16. &quot;math/big&quot;
  17. )
  18. func main() {
  19. auth_token := &quot;&quot;
  20. w := strings.Split(auth_token, &quot;.&quot;)
  21. h_, s_ := w[0], w[2]
  22. if m := len(h_) % 4; m != 0 {
  23. h_ += strings.Repeat(&quot;=&quot;, 4-m)
  24. }
  25. if m := len(s_) % 4; m != 0 {
  26. s_ += strings.Repeat(&quot;=&quot;, 4-m)
  27. }
  28. headerOauth, err := base64.URLEncoding.DecodeString(h_)
  29. res, err := http.Get(&quot;https://www.googleapis.com/oauth2/v2/certs&quot;)
  30. if err != nil {
  31. fmt.Println(err)
  32. }
  33. certs, err := ioutil.ReadAll(res.Body)
  34. res.Body.Close()
  35. if err != nil {
  36. fmt.Println(err)
  37. }
  38. //extract kid from token header
  39. var header interface{}
  40. err = json.Unmarshal([]byte(string(headerOauth)), &amp;header)
  41. token_kid := header.(map[string]interface{})[&quot;kid&quot;]
  42. fmt.Println(&quot;By 1&quot;)
  43. //get modulus and exponent from the cert
  44. var goCertificate interface{}
  45. err = json.Unmarshal(certs, &amp;goCertificate)
  46. //k := goCertificate.(map[string]interface{})[token_kid.(string)]
  47. k := goCertificate.(map[string]interface{})[&quot;keys&quot;]
  48. ///*mod &amp; exp part
  49. j := k.([]interface{})
  50. x := j[0]
  51. if j[0].(map[string]interface{})[&quot;kid&quot;] == token_kid {
  52. x = j[0]
  53. }else{
  54. if j[1].(map[string]interface{})[&quot;kid&quot;] == token_kid {
  55. x = j[1]
  56. }else{
  57. errors.New(&quot;Token is not valid, kid from token and certificate don&#39;t match&quot;)
  58. }
  59. }
  60. h := x.(map[string]interface{})[&quot;n&quot;]
  61. g := x.(map[string]interface{})[&quot;e&quot;]
  62. //build the google pub key
  63. nStr := h.(string)
  64. decN, err := base64.URLEncoding.DecodeString(nStr)
  65. if err != nil {
  66. fmt.Println(err)
  67. return
  68. }
  69. n := big.NewInt(0)
  70. n.SetBytes(decN)
  71. eStr := g.(string)
  72. decE, err := base64.URLEncoding.DecodeString(eStr)
  73. if err != nil {
  74. fmt.Println(err)
  75. return
  76. }
  77. var eBytes []byte
  78. if len(decE) &lt; 8 {
  79. eBytes = make([]byte, 8-len(decE), 8)
  80. eBytes = append(eBytes, decE...)
  81. } else {
  82. eBytes = decE
  83. }
  84. eReader := bytes.NewReader(eBytes)
  85. var e uint64
  86. err = binary.Read(eReader, binary.BigEndian, &amp;e)
  87. if err != nil {
  88. log.Println(err)
  89. return
  90. }
  91. pKey := rsa.PublicKey{N: n, E: int(e)}
  92. //inblockOauth := base64.URLEncoding.DecodeString(w[1])
  93. toHash := w[0] + &quot;.&quot; + w[1]
  94. digestOauth, err := base64.URLEncoding.DecodeString(s_)
  95. hasherOauth := sha256.New()
  96. hasherOauth.Write([]byte(toHash))
  97. // verification of the signature
  98. err = rsa.VerifyPKCS1v15(&amp;pKey,crypto.SHA256,hasherOauth.Sum(nil),digestOauth)
  99. if err != nil {
  100. fmt.Printf(&quot;Error verifying key %s&quot;,err.Error())
  101. }
  102. fmt.Printf(&quot;OK!&quot;)
  103. }

答案2

得分: 2

不要使用StdEncoding,它不符合规范要求的URL安全性。

请使用URLEncoding代替。更多信息请参考https://gobyexample.com/base64-encoding。

Base64 Url Safe与Base64相同,但不包含'/'和'+'(被'_'和'-'替代),并且移除了尾部的'='。

英文:

Do not use the StdEncoding, it is not URL-Safe as required by the specification.

Use URLEncoding instead. See https://gobyexample.com/base64-encoding for more informations.

The Base64 Url Safe is the same as Base64 but does not contain '/' and '+' (replaced by '_' and '-') and trailing '=' are removed.

答案3

得分: 2

我将“decoded”头部和负载与Google pKey +摘要一起发送到rsa.VerifyPKCS1v15函数中。

你在这部分是错误的。你必须将编码后的头部和负载发送给RSA函数rsa.VerifyPKCS1v15

换句话说:你检查了签名{&quot;alg&quot;:&quot;RS256&quot;,&quot;kid&quot;:&quot;d91c503452d0f8849200a321ffbf7dea76f9371d&quot;}.{&quot;iss&quot;:&quot;accounts.google.com&quot;,&quot;sub&quot;:&quot;104869993929250743503&quot;,&quot;azp&quot;:&quot;client_email_till_@.apps.googleusercontent.com&quot;,&quot;email&quot;:&quot;test@test.hr&quot;,&quot;at_hash&quot;:&quot;KAm1M0g-ssMkdjds7jkbVQ&quot;,&quot;email_verified&quot;:true,&quot;aud&quot;:client_email_till_@.apps.googleusercontent.com&quot;,&quot;hd&quot;:&quot;test.hr&quot;,&quot;iat&quot;:1412246551,&quot;exp&quot;:1412250451} 这是错误的

你必须检查签名eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ5MWM1MDM0NTJkMGY4ODQ5MjAwYTMyMWZmYmY3ZGVhNzZmOTM3MWQifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTA0ODY5OTkzOTI5MjUwNzQzNTAzIiwiYXpwIjoiY2xpZW50X2VtYWlsX3RpbGxfQC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoidGVzdEB0ZXN0LmhyIiwiYXRfaGFzaCI6IktBbTFNMGctc3NNa2RqZHM3amtiVlEiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXVkIjpjbGllbnRfZW1haWxfdGlsbF9ALmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiaGQiOiJ0ZXN0LmhyIiwiaWF0IjoxNDEyMjQ2NTUxLCJleHAiOjE0MTIyNTA0NTF9的签名。

英文:

I send the **decoded** header.payload together with the Google pKey + digest to the rsa function rsa.VerifyPKCS1v15.

You are wrong in this part. You must send to the RSA function rsa.VerifyPKCS1v15 the encoded header.payload

In another words: you checked the signature of {&quot;alg&quot;:&quot;RS256&quot;,&quot;kid&quot;:&quot;d91c503452d0f8849200a321ffbf7dea76f9371d&quot;}.{&quot;iss&quot;:&quot;accounts.google.com&quot;,&quot;sub&quot;:&quot;104869993929250743503&quot;,&quot;azp&quot;:&quot;client_email_till_@.apps.googleusercontent.com&quot;,&quot;email&quot;:&quot;test@test.hr&quot;,&quot;at_hash&quot;:&quot;KAm1M0g-ssMkdjds7jkbVQ&quot;,&quot;email_verified&quot;:true,&quot;aud&quot;:client_email_till_@.apps.googleusercontent.com&quot;,&quot;hd&quot;:&quot;test.hr&quot;,&quot;iat&quot;:1412246551,&quot;exp&quot;:1412250451} which is wrong.

You must check the signature of eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ5MWM1MDM0NTJkMGY4ODQ5MjAwYTMyMWZmYmY3ZGVhNzZmOTM3MWQifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTA0ODY5OTkzOTI5MjUwNzQzNTAzIiwiYXpwIjoiY2xpZW50X2VtYWlsX3RpbGxfQC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoidGVzdEB0ZXN0LmhyIiwiYXRfaGFzaCI6IktBbTFNMGctc3NNa2RqZHM3amtiVlEiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXVkIjpjbGllbnRfZW1haWxfdGlsbF9ALmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiaGQiOiJ0ZXN0LmhyIiwiaWF0IjoxNDEyMjQ2NTUxLCJleHAiOjE0MTIyNTA0NTF9.

答案4

得分: 1

要检查的输入应该是$base64_header.$base64_claim_set。
根据Google的文档

JSON Web Signature (JWS) 是指导为JWT生成签名的规范。签名的输入是以下内容的字节数组:<br/>
{Base64url编码的头}.{Base64url编码的声明集}

我认为你可能只是为了演示而硬编码了证书索引。在你的真实代码中,你应该根据头部中的"kid"字段选择正确的证书。

英文:

The input to be checked should be the $base64_header.$base64_claim_set.
From Google's documentation:

> JSON Web Signature (JWS) is the specification that guides the
> mechanics of generating the signature for the JWT. The input for the
> signature is the byte array of the following content: <br/>
> {Base64url encoded header}.{Base64url encoded claim set}

I think you probably just hardcoded the cert index for demonstrating. In your real code, you should choose the correct cert based on the "kid" field in the header.

huangapple
  • 本文由 发表于 2014年10月2日 19:18:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/26159658.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定