Last active
April 10, 2023 19:34
-
-
Save toqueteos/5372776 to your computer and use it in GitHub Desktop.
Minecraft player auth SHA-1 digest.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} |
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)
Thanks a lot
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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].