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
CodePudding user response:
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
}
