0

I am trying to generate a hmac for API authentication, but the documentation is on Go, I need to convert it to php way, I need the result to be the same as Go result.

On the Docs said: To build the string to sign, combine the HTTP method, request content type, date time, request URI, and the payload hash with the newline in between each parameter.

Go Way:

func ComputeHMAC(date string) string
   request := []string{"POST","application/json",'Thu, 17 Jan 2019 02:45:06 
              GMT',"/ayden/init",'qz0HpayQzMDnBfJMfUB5zJGU62nX2Uef66m6YIpDAWA='}
   request1 := strings.Join(request, "\n")
   request2 := []string{request1,"\n"}
   stringToSign := strings.Join(request2, "")

   shaSignature := computeHmac256(stringToSign, "secret")
}

func computeHmac256(message string, secret string) string {
   key := []byte(secret)   
   h := hmac.New(sha256.New, key)
   h.Write([]byte(message))
   result := h.Sum(nil)
   return base64.StdEncoding.EncodeToString(result)
 }

Hmac in GO: 6k44vpeNqYSgFkM2sZsJH+Ijg5amftPnqO3v45pMWN0=

What i tried in PHP:

$stringToSign = [
        'POST',
        'application/json',
        'Thu, 17 Jan 2019 02:45:06 GMT',
        '/ayden/init',
        'qz0HpayQzMDnBfJMfUB5zJGU62nX2Uef66m6YIpDAWA='
    ];

$string = implode("/n", $stringToSign);
$hmac = base64_encode(hash_hmac('sha256', $string, 'secret', true)); 
echo $hmac;

Hmac in PHP: 9mt4Ojzr9uVGaB6/jt96bbuEd0gJNh6Cph3q+dY3X38=

I`m a bit lost here, already spent many hours to figure this out, please help.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
berusjamban
  • 323
  • 4
  • 12
  • Something to do with GMT on a newline? Could also be the new line is wrong in php – CGSmith105 Jul 08 '20 at 03:38
  • on the docs said: To build the string to sign, combine the HTTP method, request content type, date time, request URI, and the payload hash with the newline in between each parameter. @CGSmith105 – berusjamban Jul 08 '20 at 03:42
  • is there any other way to make newline in php? @CGSmith105 – berusjamban Jul 08 '20 at 03:45
  • 2
    The Go code is invalid. It's missing a curly brace and return statement, the date value has whitespace that would not be allowed in an HTTP header, and single quotes are not allowed for string literals. After fixing all that [the output is not 6k44vpeNq...](https://play.golang.org/p/hVZZvtzCpf6). In PHP you're using `/n` instead of `\n` and you're missing the trailing newline. After fixing that [the output is identical to Go's](https://3v4l.org/A2sTt). – Peter Jul 08 '20 at 06:49
  • Don't pass `true` as the final argument to the PHP `hash_mac` function. That changes the output format from hex digits to raw data. This is probably the only problem you have. – Jonathan Hall Jul 08 '20 at 07:16
  • thank you so much @Peter! its working now! – berusjamban Jul 08 '20 at 08:43

2 Answers2

2

you can try this function

func computeHmac256(src string, secret string) string {
    h := hmac.New(sha256.New, []byte(secret))
    h.Write([]byte(src))
    shaStr:= fmt.Sprintf("%x",h.Sum(nil))
    return base64.StdEncoding.EncodeToString([]byte(shaStr))
}
0

php code

base64_encode(hash_hmac('sha256', $data, $secret));

I tested successfully on golang and php. The result is same.