英文:
Some character disappear after decode base64 in golang
问题
我构建了一个简单的程序来生成Json Web Token (JWT),一切都正常运行,直到我进行了令牌验证来验证JWT,问题出现在我解码base64字符串以检查头部令牌之后。一些二进制的部分消失了,而字符串值是从编码的base64中获取的。这是我的代码和结果:
package auth
import "encoding/base64"
import "crypto/sha256"
import "encoding/json"
import "strings"
import "crypto/hmac"
import "encoding/hex"
import "fmt"
type Header struct{
Alg string
Typ string
}
type Payload struct{
id int
name string
userType bool
keepLogin bool
}
var key string = "12345678" //temporary
var payloadJson Payload
func GenerateToken(alg string, typ string, payload []byte)(string, error){
var headerEncoded, payloadEncoded, signature, mergedEncoded string
header := Header{Alg: alg,Typ: typ}
hmacDeclare := hmac.New(sha256.New, []byte(key))
headerJson, errHeader := json.Marshal(header)//struct -> byte
if errHeader != nil{
return "",errHeader
}
headerEncoded = encodeBase64(headerJson)//byte -> string
payloadEncoded = encodeBase64(payload)//byte -> string
mergedEncoded = headerEncoded+"."+payloadEncoded
if alg=="SHA256"{
hmacDeclare.Write([]byte(mergedEncoded))
signature = hex.EncodeToString(hmacDeclare.Sum(nil))
}
finalToken := headerEncoded+"."+payloadEncoded+"."+signature
//JUST SAMPLE TO TEST JWT RESULT
fmt.Println("Before encode (byte) => ", headerJson)
fmt.Println("Before encode (string) => ", string(headerJson))
fmt.Println("After encode (base64/string) => ", headerEncoded)
checkDecode,_ := decodeBase64(headerEncoded)//string -> byte
fmt.Println("After decode (byte) => ", checkDecode)
fmt.Println("After decode (string) => ", string(checkDecode))
// _, _ = VerifyToken(finalToken)
return finalToken, nil
}
func encodeBase64(data []byte) string {
formatString := strings.TrimRight(base64.StdEncoding.EncodeToString(data),"=")
return formatString
}
func decodeBase64(data string)([]byte, error){
result, err := base64.StdEncoding.DecodeString(data)
if err != nil{
return result, err
}
return result, nil
}
以下是结果:
Before encode (byte) => [123 34 65 108 103 34 58 34 83 72 65 50 53 54 34 44 34 84 121 112 34 58 34 74 87 84 34 125]
Before encode (string) => {"Alg":"SHA256","Typ":"JWT"}
After encode (base64/string) => eyJBbGciOiJTSEEyNTYiLCJUeXAiOiJKV1QifQ
After decode (byte) => [123 34 65 108 103 34 58 34 83 72 65 50 53 54 34 44 34 84 121 112 34 58 34 74 87 84 34]
After decode (string) => {"Alg":"SHA256","Typ":"JWT
有人遇到相同的问题吗?我尝试搜索,但没有找到相同的问题。
英文:
I built simple program to generate Json Web Token (JWT), everything ran normally until I made a token verification to verify the JWT, the problem came after I decode base64 string to check the header token. Some part of the binary is disappear, whereas the string value is from encoded base64. Here my code and the result
package auth
import "encoding/base64"
import "crypto/sha256"
import "encoding/json"
import "strings"
import "crypto/hmac"
import "encoding/hex"
import "fmt"
type Header struct{
Alg string
Typ string
}
type Payload struct{
id int
name string
userType bool
keepLogin bool
}
var key string = "12345678" //temporary
var payloadJson Payload
func GenerateToken(alg string, typ string, payload []byte)(string, error){
var headerEncoded, payloadEncoded, signature, mergedEncoded string
header := Header{Alg: alg,Typ: typ}
hmacDeclare := hmac.New(sha256.New, []byte(key))
headerJson, errHeader := json.Marshal(header)//struct -> byte
if errHeader != nil{
return "",errHeader
}
headerEncoded = encodeBase64(headerJson)//byte -> string
payloadEncoded = encodeBase64(payload)//byte -> string
mergedEncoded = headerEncoded+"."+payloadEncoded
if alg=="SHA256"{
hmacDeclare.Write([]byte(mergedEncoded))
signature = hex.EncodeToString(hmacDeclare.Sum(nil))
}
finalToken := headerEncoded+"."+payloadEncoded+"."+signature
//JUST SAMPLE TO TEST JWT RESULT
fmt.Println("Before encode (byte) => ", headerJson)
fmt.Println("Before encode (string) => ", string(headerJson))
fmt.Println("After encode (base64/string) => ", headerEncoded)
checkDecode,_ := decodeBase64(headerEncoded)//string -> byte
fmt.Println("After decode (byte) => ", checkDecode)
fmt.Println("After decode (string) => ", string(checkDecode))
// _, _ = VerifyToken(finalToken)
return finalToken, nil
}
func encodeBase64(data []byte) string {
formatString := strings.TrimRight(base64.StdEncoding.EncodeToString(data),"=")
return formatString
}
func decodeBase64(data string)([]byte, error){
result, err := base64.StdEncoding.DecodeString(data)
if err != nil{
return result, err
}
return result, nil
}
and here the result
Before encode (byte) => [123 34 65 108 103 34 58 34 83 72 65 50 53 54 34 44 34 84 121 112 34 58 34 74 87 84 34 125]
Before encode (string) => {"Alg":"SHA256","Typ":"JWT"}
After encode (base64/string) => eyJBbGciOiJTSEEyNTYiLCJUeXAiOiJKV1QifQ
After decode (byte) => [123 34 65 108 103 34 58 34 83 72 65 50 53 54 34 44 34 84 121 112 34 58 34 74 87 84 34]
After decode (string) => {"Alg":"SHA256","Typ":"JWT"
Does anyone have same issue? I've tried browsing for it but found no same issue
答案1
得分: 0
如果你不想要填充(padding),不要对其进行修剪,而是使用WithPadding
并传入NoPadding
。
func encodeBase64(data []byte) string {
e := base64.StdEncoding.WithPadding(base64.NoPadding)
return e.EncodeToString(data)
}
func decodeBase64(data string) ([]byte, error) {
e := base64.StdEncoding.WithPadding(base64.NoPadding)
result, err := e.DecodeString(data)
if err != nil {
return result, err
}
return result, nil
}
https://go.dev/play/p/bs6Wte-wHeD
英文:
If you don't want the padding don't trim it, instead use WithPadding
and pass in NoPadding
.
func encodeBase64(data []byte) string {
e := base64.StdEncoding.WithPadding(base64.NoPadding)
return e.EncodeToString(data)
}
func decodeBase64(data string) ([]byte, error) {
e := base64.StdEncoding.WithPadding(base64.NoPadding)
result, err := e.DecodeString(data)
if err != nil {
return result, err
}
return result, nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论