Skip to content

Instantly share code, notes, and snippets.

@ranggasama
Created January 20, 2021 11:08
Show Gist options
  • Save ranggasama/e1864515bd4749c04680374892de000e to your computer and use it in GitHub Desktop.
Save ranggasama/e1864515bd4749c04680374892de000e to your computer and use it in GitHub Desktop.
Sample Golang application to send HMAC authentication
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"crypto/tls"
"encoding/base64"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"time"
)
func main() {
algorithm := "hmac-sha256"
username := "hmac-user"
secret := "~,6a=HFaC/P]R5Zp"
url := "https://localhost"
path := "/ok"
method := "POST"
uuid := "9b83f786-5a70-11eb-ae93-0242ac130002"
// request path
url = url + path
// date
loc, _ := time.LoadLocation("GMT")
date := time.Now().In(loc)
layout := "Mon, 02 Jan 2006 15:04:05 GMT"
dateFormat := date.Format(layout)
// body
requestBody := []byte("{\"foo\":\"bar\"}")
digestBody := sha256.New()
digestBody.Write([]byte(requestBody))
digestBodyContent := base64.StdEncoding.EncodeToString(digestBody.Sum(nil))
digestBodyHeader := "SHA-256=" + digestBodyContent
signingString := "x-date: " + dateFormat + "\n" + method + " " + path + " HTTP/1.1" + "\n" + "x-uuid: " + uuid + "\n" + "digest: " + digestBodyHeader
digest := hmac.New(sha256.New, []byte(secret))
digest.Write([]byte(signingString))
signature := base64.StdEncoding.EncodeToString(digest.Sum(nil))
// ignore server certificate
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
request, err := http.NewRequest(method, url, bytes.NewBuffer(requestBody))
if err != nil {
log.Fatalln(err)
}
//header
authorization := "hmac username=\"" + username + "\", algorithm=\"" + algorithm + "\", headers=\"x-date request-line x-uuid digest\", signature=\"" + signature + "\""
log.Println("variables:")
fmt.Println("url: "+ url)
fmt.Println("username: "+ username)
fmt.Println("secret: "+ secret)
fmt.Println("body: "+ string(requestBody))
fmt.Println("signingString: "+ signingString)
fmt.Println("signature: "+ signature)
fmt.Println("authorization: "+ authorization)
request.Header.Set("Digest", digestBodyHeader)
request.Header.Set("Authorization", authorization)
request.Header.Set("X-Date", dateFormat)
request.Header.Set("X-UUID", uuid)
request.Header.Set("Content-Type", "application/json")
requestDump, err := httputil.DumpRequest(request, true)
if err == nil {
log.Println("request:", string(requestDump))
}
resp, err := client.Do(request)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println("response header:")
for k, v := range resp.Header {
fmt.Println(k, ":", v)
}
log.Println("response:", string(body))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment