Created
September 28, 2014 00:36
-
-
Save stuntguy3000/32c5f6e7d2912cf16b60 to your computer and use it in GitHub Desktop.
how to generate minecraft hex digests in java
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
package com.serverid; | |
import java.io.UnsupportedEncodingException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
public class ServerID | |
{ | |
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); | |
public static void main(String[] args) | |
{ | |
// The test values provided on http://wiki.vg/Protocol_Encryption are: | |
// sha1(Notch) : 4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48 | |
// sha1(jeb_) : -7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1 | |
System.out.println(javaHexDigest("Notch")); | |
System.out.println(javaHexDigest("jeb_")); | |
} | |
private static String javaHexDigest(String data) | |
{ | |
MessageDigest digest = null; | |
try { | |
digest = MessageDigest.getInstance("SHA-1"); | |
digest.reset(); | |
digest.update(data.getBytes("UTF-8")); | |
} catch (NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
byte[] hash = digest.digest(); | |
boolean negative = (hash[0] & 0x80) == 0x80; | |
if (negative) | |
hash = twosCompliment(hash); | |
String digests = getHexString(hash); | |
if (digests.startsWith("0")) | |
{ | |
digests = digests.replaceFirst("0", digests); | |
} | |
if (negative) | |
{ | |
digests = "-" + digests; | |
} | |
digests = digests.toLowerCase(); | |
return digests; | |
} | |
public static String getHexString(byte[] bytes) { | |
char[] hexChars = new char[bytes.length * 2]; | |
int v; | |
for ( int j = 0; j < bytes.length; j++ ) { | |
v = bytes[j] & 0xFF; | |
hexChars[j * 2] = hexArray[v >>> 4]; | |
hexChars[j * 2 + 1] = hexArray[v & 0x0F]; | |
} | |
return new String(hexChars); | |
} | |
private static byte[] twosCompliment(byte[] p) | |
{ | |
int i; | |
boolean carry = true; | |
for (i = p.length - 1; i >= 0; i--) | |
{ | |
p[i] = (byte)~p[i]; | |
if (carry) | |
{ | |
carry = p[i] == 0xFF; | |
p[i]++; | |
} | |
} | |
return p; | |
} | |
} |
This code is broken.
This code will not generate correct hashes in a lot of cases. I wrote a small test suite to generate 2000 random strings, and compare the hashed value to the one generated by vanilla (effectively new BigInteger(md.digest()).toString(16)
). I found it has a 13% failure rate, and here are some examples of the way this fails:
Hashing L3CcLplRqgIvKtzb... FAIL
Vanilla: 8908b881f6827e31dfac8dd5da2748cba79a690
ServerID: 08908b881f6827e31dfac8dd5da2748cba79a6908908b881f6827e31dfac8dd5da2748cba79a690
Standard: 08908b881f6827e31dfac8dd5da2748cba79a690
Hashing pTJ3pyyOPblCiJ1y... FAIL
Vanilla: -f1b407986637d137df41cb29a921bfacb5e6031
ServerID: -0f1b407986637d137df41cb29a921bfacb5e6031f1b407986637d137df41cb29a921bfacb5e6031
Standard: f0e4bf86799c82ec820be34d656de40534a19fcf
Hashing BlFBO4ZN5igrMxoB... FAIL
Vanilla: -80c2b00389a1ee2ed0d3ea1808b0847d227271e
ServerID: -080c2b00389a1ee2ed0d3ea1808b0847d227271e80c2b00389a1ee2ed0d3ea1808b0847d227271e
Standard: f7f3d4ffc765e11d12f2c15e7f74f7b82dd8d8e2
Final output from the test suite: Done. 273/2000 failed (13% failure rate)
In short, DO NOT USE THIS CODE. It will silently fail in subtle ways, which will result in server authentication failing for seemingly no reason... 13% of the time.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Çok güzel admin gardaş