Skip to content

Instantly share code, notes, and snippets.

@everettcaleb
Last active November 11, 2020 00:11
Show Gist options
  • Save everettcaleb/3b377cc3a0214ed49156472b615555f4 to your computer and use it in GitHub Desktop.
Save everettcaleb/3b377cc3a0214ed49156472b615555f4 to your computer and use it in GitHub Desktop.
HMAC Token Authentication in Go, Python, and JavaScript
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "http://localhost", nil)
if err != nil {
fmt.Println("Error 1")
return
}
client := &http.Client{}
h := hmac.New(sha256.New, []byte("secret"))
h.Write([]byte("keyid|test.example.com"))
req.Header.Add("Authorization", fmt.Sprint("Bearer ", "key|test.example.com|", hex.EncodeToString(h.Sum(nil))))
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error 2")
return
}
defer resp.Body.Close()
fmt.Println(resp.StatusCode)
}
const crypto = require('crypto');
const http = require('http');
const hmac = crypto.createHmac('sha256', Buffer.from('secret'));
hmac.update([ KEY, 'test.example.com' ].join('|'));
const authorization = 'Bearer ' + [ 'keyid', 'test.example.com', hmac.digest('hex') ].join('|');
http.get({
host: 'localhost',
port: 80,
headers: {
authorization
}
}, res => {
console.log(res.statusCode);
});
import hmac
import requests
h = hmac.new('secret'.encode(), 'keyid|test.example.com'.encode(), 'sha256')
auth = 'Bearer keyid|test.example.com|' + h.hexdigest()
headers = { 'Authorization': auth }
res = requests.get('http://localhost', headers=headers)
print(res.status_code)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
h := hmac.New(sha256.New, []byte("secret"))
h.Write([]byte("keyid|test.example.com"))
fmt.Println(hex.EncodeToString(h.Sum(nil)))
}
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'secret');
crypto.createHmac('sha256', Buffer.from('secret'))
.update([ 'keyid', 'test.example.com' ].join('|'));
console.log(hmac.digest('hex'));
import hmac
h = hmac.new('secret'.encode(), 'keyid|test.example.com'.encode(), 'sha256')
print(h.hexdigest())
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"strings"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
parts := strings.Split(auth, " ")
if parts[0] != "Bearer" {
w.WriteHeader(401)
return
}
tokenParts := strings.Split(parts[1], "|")
key, service, signature := tokenParts[0], tokenParts[1], tokenParts[2]
h := hmac.New(sha256.New, []byte("secret"))
h.Write([]byte("keyid|test.example.com"))
serverSig := hex.EncodeToString(h.Sum(nil))
if key != "keyid" || service != "test.example.com" || signature != serverSig {
w.WriteHeader(401)
return
}
w.WriteHeader(200)
})
http.ListenAndServe(":80", nil)
}
const http = require('http');
const crypto = require('crypto');
http.createServer((req, res) => {
let { authorization } = req.headers;
if (!authorization) {
console.log('Failed authorization');
return send401(res);
}
let [ bearer, token ] = authorization.split(' ');
if (bearer != 'Bearer') {
console.log('Failed Bearer');
return send401(res);
}
const [ key, service, mac ] = token.split('|');
const serverMac = crypto.createHmac('sha256', Buffer.from('secret'));
serverMac.update([ key, service ].join('|'));
if (key != 'keyid' || service != 'test.example.com' || serverMac.digest('hex') != mac) {
console.log(key, service, serverMac.digest('hex'));
console.log('Something else');
return send401(res);
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('OK');
}).listen(80);
function send401(res) {
res.writeHead(401, { 'Content-Type': 'text/plain' });
res.end('Unauthorized');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment