Skip to content

Instantly share code, notes, and snippets.

@stuntguy3000
Created September 28, 2014 00:36
Show Gist options
  • Save stuntguy3000/32c5f6e7d2912cf16b60 to your computer and use it in GitHub Desktop.
Save stuntguy3000/32c5f6e7d2912cf16b60 to your computer and use it in GitHub Desktop.
how to generate minecraft hex digests in java
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;
}
}
Copy link

ghost commented Sep 20, 2015

Çok güzel admin gardaş

@unascribed
Copy link

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