Skip to content

Instantly share code, notes, and snippets.

@toqueteos
Last active April 10, 2023 19:34
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toqueteos/5372776 to your computer and use it in GitHub Desktop.
Save toqueteos/5372776 to your computer and use it in GitHub Desktop.
Minecraft player auth SHA-1 digest.
// You can test this online at: https://play.golang.org/p/hhayRT1VWgj
package main
import (
"crypto/sha1"
"encoding/hex"
"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(hex.EncodeToString(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
}
@4kills
Copy link

4kills commented Jul 14, 2020

Excuse me, I think your comment over the function twosComplement(:[]byte):[]byte is wrong / misleading. I am pretty sure the hash is big endian, with the MSB being located at p[0] and the LSB being located at p[len(p)-1].

@Tnze
Copy link

Tnze commented Mar 15, 2021

To encode a []byte base 16, you would use encoding/hex instead of `fmt.Sprintf("%x") for better performance:

fmt.Sprintf("%x", hash) == hex.EncodeToString(hash)

@Hunam6
Copy link

Hunam6 commented Apr 10, 2023

Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment