Jump to content
Tuts 4 You

My Java keygen


chickenbutt

Recommended Posts

Was messing around in Java and wrote this up. Improvements?


public final class KeyDecoder
{
private static int CalculateHash(String licenseName)
{
int hash = 0; for (int i = 0; i < licenseName.length(); i++)
{
int xorValue = licenseName.charAt(i);
int rotateSequence = xorValue; for (int j = 0; j < 4; j++)
{
int rotateLeft = rotateSequence & 0x3;
int shiftLeft = rotateLeft;
int shiftRight = 32 - rotateLeft;
int rotatedBits = hash >>> shiftRight; hash = hash << shiftLeft | rotatedBits;
hash ^= xorValue; rotateSequence >>= 2;
}
} return hash + 1 & 0xFFFF;
} public static short[] getInfoArray(String registrationName, String registrationCode)
{
short[] infoArray = (short[])null; if ((registrationName != null) && (registrationCode != null))
{
registrationName = registrationName.toUpperCase().trim();
registrationCode = registrationCode.toUpperCase().trim(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < registrationCode.length(); i++)
{
char ch = registrationCode.charAt(i);
if (!Character.isLetter(ch)) {
continue;
}
sb.append(ch);
} registrationCode = sb.toString();
int registrationCodeLen = registrationCode.length(); if ((registrationName.length() > 0) && (registrationCodeLen > 0))
{
Vector dataWordList = new Vector(); int checksum = 0; int offset = 0;
int chCode = 65; while (offset < registrationCodeLen)
{
int dataWord = 0; for (int i = 0; i < 4; i++)
{
if (offset >= registrationCodeLen)
continue;
int ch = registrationCode.charAt(offset++); int chDiff = ch >= chCode ? ch - chCode : ch + 26 - chCode;
dataWord = dataWord << 4 | chDiff - 1;
chCode = ch;
} checksum += dataWord; dataWordList.add(new Integer(dataWord));
} Integer HashCode = (Integer)dataWordList.get(1);
Integer CheckSum = (Integer)dataWordList.get(dataWordList.size() - 1); int tCheckSum = CheckSum.intValue();
if ((checksum - tCheckSum & 0xFFFF) == tCheckSum)
{
int tHashCode = HashCode.intValue();
if (tHashCode == CalculateHash(registrationName))
{
int nitems = dataWordList.size() - 3;
if (nitems > 0)
{
Integer dataWord = (Integer)dataWordList.get(0);
int randomNumber = dataWord.intValue() & 0xFFFF; infoArray = new short[nitems];
for (int i = 0; i < nitems; i++)
{
dataWord = (Integer)dataWordList.get(2 + i);
infoArray[i] = (short)((dataWord.intValue() ^ randomNumber) & 0xFFFF);
}
}
}
}
}
} return infoArray;
} public static boolean getInfoArray(String registrationName, String registrationCode, short[] infoArray)
{
int[] dataWordList = (int[])null;
int numDataWords = 0;
int checksum = 0; boolean validFlag = true; if ((registrationName != null) && (registrationCode != null))
{
registrationName = registrationName.toUpperCase().trim();
registrationCode = registrationCode.toUpperCase().trim(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < registrationCode.length(); i++)
{
char ch = registrationCode.charAt(i);
if ((ch < 'A') || (ch > 'Z'))
continue;
sb.append(ch);
} registrationCode = sb.toString();
} else {
validFlag = false;
} if (validFlag) {
int registrationCodeLen = registrationCode.length(); if ((registrationName.length() > 0) && (registrationCodeLen > 0))
{
dataWordList = new int[infoArray.length + 3]; int offset = 0;
int chCode = 65; while (offset < registrationCodeLen)
{
int dataWord = 0; for (int i = 0; i < 4; i++)
{
if (offset >= registrationCodeLen)
continue;
int ch = registrationCode.charAt(offset++);
int chDiff = ch >= chCode ? ch - chCode : ch + 26 - chCode;
dataWord = dataWord << 4 | chDiff - 1;
chCode = ch;
} checksum += dataWord; if (numDataWords < dataWordList.length)
dataWordList[(numDataWords++)] = dataWord;
else
validFlag = false;
}
}
else {
validFlag = false;
}
} if (validFlag) {
int tCheckSum = dataWordList[(numDataWords - 1)]; if ((checksum - tCheckSum & 0xFFFF) == tCheckSum) {
int tHashCode = dataWordList[1]; if (tHashCode == CalculateHash(registrationName)) {
int nitems = numDataWords - 3;
if (nitems > 0) {
int randomNumber = dataWordList[0] & 0xFFFF; for (int i = 0; i < nitems; i++)
{
int dataWord = dataWordList[(2 + i)];
infoArray[i] = (short)((dataWord ^ randomNumber) & 0xFFFF);
}
} else {
validFlag = false;
}
} else {
validFlag = false;
}
} else {
validFlag = false;
}
} return validFlag;
}
}public final class KeyDecoder
{
private static int CalculateHash(String licenseName)
{
int hash = 0; for (int i = 0; i < licenseName.length(); i++)
{
int xorValue = licenseName.charAt(i);
int rotateSequence = xorValue; for (int j = 0; j < 4; j++)
{
int rotateLeft = rotateSequence & 0x3;
int shiftLeft = rotateLeft;
int shiftRight = 32 - rotateLeft;
int rotatedBits = hash >>> shiftRight; hash = hash << shiftLeft | rotatedBits;
hash ^= xorValue; rotateSequence >>= 2;
}
} return hash + 1 & 0xFFFF;
} public static short[] getInfoArray(String registrationName, String registrationCode)
{
short[] infoArray = (short[])null; if ((registrationName != null) && (registrationCode != null))
{
registrationName = registrationName.toUpperCase().trim();
registrationCode = registrationCode.toUpperCase().trim(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < registrationCode.length(); i++)
{
char ch = registrationCode.charAt(i);
if (!Character.isLetter(ch)) {
continue;
}
sb.append(ch);
} registrationCode = sb.toString();
int registrationCodeLen = registrationCode.length(); if ((registrationName.length() > 0) && (registrationCodeLen > 0))
{
Vector dataWordList = new Vector(); int checksum = 0; int offset = 0;
int chCode = 65; while (offset < registrationCodeLen)
{
int dataWord = 0; for (int i = 0; i < 4; i++)
{
if (offset >= registrationCodeLen)
continue;
int ch = registrationCode.charAt(offset++); int chDiff = ch >= chCode ? ch - chCode : ch + 26 - chCode;
dataWord = dataWord << 4 | chDiff - 1;
chCode = ch;
} checksum += dataWord; dataWordList.add(new Integer(dataWord));
} Integer HashCode = (Integer)dataWordList.get(1);
Integer CheckSum = (Integer)dataWordList.get(dataWordList.size() - 1); int tCheckSum = CheckSum.intValue();
if ((checksum - tCheckSum & 0xFFFF) == tCheckSum)
{
int tHashCode = HashCode.intValue();
if (tHashCode == CalculateHash(registrationName))
{
int nitems = dataWordList.size() - 3;
if (nitems > 0)
{
Integer dataWord = (Integer)dataWordList.get(0);
int randomNumber = dataWord.intValue() & 0xFFFF; infoArray = new short[nitems];
for (int i = 0; i < nitems; i++)
{
dataWord = (Integer)dataWordList.get(2 + i);
infoArray[i] = (short)((dataWord.intValue() ^ randomNumber) & 0xFFFF);
}
}
}
}
}
} return infoArray;
} public static boolean getInfoArray(String registrationName, String registrationCode, short[] infoArray)
{
int[] dataWordList = (int[])null;
int numDataWords = 0;
int checksum = 0; boolean validFlag = true; if ((registrationName != null) && (registrationCode != null))
{
registrationName = registrationName.toUpperCase().trim();
registrationCode = registrationCode.toUpperCase().trim(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < registrationCode.length(); i++)
{
char ch = registrationCode.charAt(i);
if ((ch < 'A') || (ch > 'Z'))
continue;
sb.append(ch);
} registrationCode = sb.toString();
} else {
validFlag = false;
} if (validFlag) {
int registrationCodeLen = registrationCode.length(); if ((registrationName.length() > 0) && (registrationCodeLen > 0))
{
dataWordList = new int[infoArray.length + 3]; int offset = 0;
int chCode = 65; while (offset < registrationCodeLen)
{
int dataWord = 0; for (int i = 0; i < 4; i++)
{
if (offset >= registrationCodeLen)
continue;
int ch = registrationCode.charAt(offset++);
int chDiff = ch >= chCode ? ch - chCode : ch + 26 - chCode;
dataWord = dataWord << 4 | chDiff - 1;
chCode = ch;
} checksum += dataWord; if (numDataWords < dataWordList.length)
dataWordList[(numDataWords++)] = dataWord;
else
validFlag = false;
}
}
else {
validFlag = false;
}
} if (validFlag) {
int tCheckSum = dataWordList[(numDataWords - 1)]; if ((checksum - tCheckSum & 0xFFFF) == tCheckSum) {
int tHashCode = dataWordList[1]; if (tHashCode == CalculateHash(registrationName)) {
int nitems = numDataWords - 3;
if (nitems > 0) {
int randomNumber = dataWordList[0] & 0xFFFF; for (int i = 0; i < nitems; i++)
{
int dataWord = dataWordList[(2 + i)];
infoArray[i] = (short)((dataWord ^ randomNumber) & 0xFFFF);
}
} else {
validFlag = false;
}
} else {
validFlag = false;
}
} else {
validFlag = false;
}
} return validFlag;
}
} private void CheckRegistered()
{
int todaysDate = (int)(System.currentTimeMillis() / 86400000L); aboutMessage = null; if ((username != null) && (username.length() > 0))
{
if ((registrationCode != null) && (registrationCode.length() > 0))
{
short[] infoArray = new short[2];
if (KeyDecoder.getInfoArray(username, registrationCode, infoArray)) {
expiryDate = infoArray[0];
iEdition = infoArray[1]; if ((iEdition >= 0) && (iEdition <= 2)) {
boolean keyValid = true;
expiryDate = infoArray[0]; if (expiryDate > 0) {
if (expiryDate >= 15286) {
registeredFlag = true;
} else {
Date date = new Date(expiryDate * 24L * 60L * 60L * 1000L);
Calendar cal = Calendar.getInstance();
cal.setTime(date); int ccyy = cal.get(1);
int month = cal.get(2);
int day = cal.get(5); registerMessage = String.format("Registration code not valid for Product released after %d/%d/%4d", new Object[] { Integer.valueOf(day), Integer.valueOf(month), Integer.valueOf(ccyy) });
registeredFlag = false;
}
} else if (expiryDate < 0) {
if (todaysDate <= -expiryDate) {
registeredFlag = true;
} else {
Date date = new Date(-expiryDate * 24L * 60L * 60L * 1000L);
Calendar cal = Calendar.getInstance();
cal.setTime(date); int ccyy = cal.get(1);
int month = cal.get(2);
int day = cal.get(5); registerMessage = String.format("Registration code expired on %d/%d/%4d", new Object[] { Integer.valueOf(day), Integer.valueOf(month), Integer.valueOf(ccyy) });
registeredFlag = false;
}
} else {
registerMessage = "Registration code has expired";
registeredFlag = false;
}
} else {
boolean keyValid = false;
registerMessage = "Registration code is not valid for this product";
registeredFlag = false;
}
} else {
registerMessage = "*** Invalid Key ***";
registeredFlag = false;
}
}
else
{
registerMessage = "Missing registration code";
registeredFlag = false;
}
}
else
{
registerMessage = "Missing username";
registeredFlag = false;
} if (registeredFlag)
{
switch (iEdition)
{
case -1:
setTitle(version + " (Unregistered Edition)");
break;
case 0:
setTitle(version + " (Personal Edition)");
break;
case 1:
setTitle(version + " (Business Edition)");
break;
case 2:
setTitle(version + " (GameCreators Edition)");
break;
default:
setTitle(version + " (Unknown Edition)");
} this.registerMenuItem.setVisible(false);
this.registerMenuItem.setVisible(true);
}
else
{
setTitle(version + " - Trial Version");
this.registerMenuItem.setVisible(true);
}
}
Link to comment

Anything not working as expected?

no. It's actually weak, the hashing function is just a shift+decode function, and the rest just converts underlying segments into date and edition info.

If I was doing a serious one it'd be export friendly RSA off of a HWID that go to a one-time server check which returns a key file that is sent through some RSA+HWID based decryption routines on-load, all under a good control-flow+crypt protector. I think JVM actually has a DRM API, or at least J2ME does I think, that has crypto and some isolation. Isolation is the key though, unfortunatly x86 has none that isn't accessble through debug+trace, except on newer Intel which is only accessible to rich vendors, and I think has been defeated.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...