Skip to content

Instantly share code, notes, and snippets.

@toqueteos toqueteos/sha1.go
Last active Apr 24, 2019

Embed
What would you like to do?
Minecraft player auth SHA-1 digest.
// You can test this online at: http://play.golang.org/p/Sn4VE79ruZ
package main
import (
"crypto/sha1"
"fmt"
"io"
"strings"
)
var examples = map[string]string{
"Notch": "4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48",
"jeb_": "-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1",
"simon": "88e16a1019277b15d58faf0541e11910eb756f6",
}
func main() {
for username, hash := range examples {
digest := AuthDigest(username)
fmt.Printf("%q = %s\n", username, digest)
fmt.Println("> Matches wiki example?", yesno(hash == digest))
}
}
func yesno(b bool) string {
if b {
return "Yes"
}
return "No"
}
// AuthDigest computes a special SHA-1 digest required for Minecraft web
// authentication on Premium servers (online-mode=true).
// Source: http://wiki.vg/Protocol_Encryption#Server
//
// Also many, many thanks to SirCmpwn and his wonderful gist (C#):
// https://gist.github.com/SirCmpwn/404223052379e82f91e6
func AuthDigest(s string) string {
h := sha1.New()
io.WriteString(h, s)
hash := h.Sum(nil)
// Check for negative hashes
negative := (hash[0] & 0x80) == 0x80
if negative {
hash = twosComplement(hash)
}
// Trim away zeroes
res := strings.TrimLeft(fmt.Sprintf("%x", hash), "0")
if negative {
res = "-" + res
}
return res
}
// little endian
func twosComplement(p []byte) []byte {
carry := true
for i := len(p) - 1; i >= 0; i-- {
p[i] = byte(^p[i])
if carry {
carry = p[i] == 0xff
p[i]++
}
}
return p
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.