Hello guys.
Today I release the V5 encryption files written by Mike (office.boy) and Nils (Nillus).
All credits belong to them and I absolutely don't take ANY credit.
Habbo's V5 dcr have forced encryption which means without this encryption you won't be able to code a V5. For developers only!
FuseSecret.java:
RC4.javaPHP Code:package com.blunk.security;
import java.security.SecureRandom;
import java.util.Random;
/**
* This class contains functions such as SecretDecode (For decoding a public key to init with
* Encryption) and GenerateSecret (For generating a secret key to init with Encryption) All secretz!
*
* 07/06/2009 - * Tidyed up, made more efficient for Connection Handshake!
*
* @author Mike
*/
public class FuseSecret
{
private static SecureRandom randomGen = new SecureRandom(); /* Used for SecretKeyDecode within Encryption */
/**
* Decodes a public key sent by the Server for use with the Encryption.
*
* @param tKey The public Key sent to the client.
* @return tKeyChecksum The decoded key.
* @author Sulake
*/
public static int SecretDecode(String origKey)
{
String table = origKey.substring(0, origKey.length() / 2);
String key = origKey.substring(origKey.length() / 2);
int checkSum = 0;
for (int i = 0; i < table.length(); i++)
{
int offset = table.indexOf(key.charAt(i));
if (offset % 2 == 0)
offset *= 2;
if (i % 3 == 0)
offset *= 3;
if (offset < 0)
offset = table.length() % 2;
checkSum += offset;
checkSum ^= offset << (i % 3) * 8;
}
return checkSum;
}
/**
* Generates a random key. (Public Key)
*
* @return tTable + tKey The final Key
* @author Sulake
*/
public static String GenerateSecret()
{
int length = 30 + Math.abs(randomGen.nextInt() % 40);
StringBuffer table = new StringBuffer(length);
StringBuffer key = new StringBuffer(length);
int charModLen = "abcdefghijklmnopqrstuvwxyz1234567890".length();
for (int i = 0; i < length; i++)
{
Character c = new Character("abcdefghijklmnopqrstuvwxyz1234567890".charAt(Math.abs(randomGen.nextInt() % charModLen)));
table.append(c);
c = new Character("abcdefghijklmnopqrstuvwxyz1234567890".charAt(Math.abs(randomGen.nextInt() % charModLen)));
table.append(c);
key.append(c);
}
return table.toString() + key.toString();
}
/**
* Once again, Math.Pow() sucks in Java.
*
* @param i
* @param power
* @return int The result
* @author Nillus
*/
public static int IntegralPow(int i, int power)
{
// Cba with using two double() with Math.pow
for (int x = 0; x < power; x++)
i *= i;
return i;
}
/**
* Because Java's random function sucks ass - you can't generate a random number BETWEEN a given
* range. Hence the reason why this is here.
*
* @param tStart The start of the range.
* @param tEnd The end of the range.
* @param tRand The instance of the "Random()" class.
* @return int A random int between given range.
* @author javapractices.com
*/
public static int GenerateRandomInRange(int tStart, int tEnd, Random tRand)
{
if (tStart > tEnd)
throw new IllegalArgumentException("The starting number cannot be larger than the ending number!");
// Stop any possible overflow
long tRange = (long)tEnd - (long)tStart + 1;
long tFraction = (long)(tRange * tRand.nextDouble());
return (int)(tFraction + tStart);
}
}
HabboRC4_static.javaPHP Code:package com.blunk.security;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Used to decipher incomming packets from the Habbo V5 Client. Credits to Matthew Parlane for
* original class.
*
* @author Mike
*/
public class RC4
{
private int j;
private int i;
private static final char HEXALPHABET_CHARS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private int pSBox[];
private int pKey[];
private final int pArtificialKey[] = { 108, 214, 122, 91, 114, 79, 16, 141, 115, 222, 207, 216, 238, 65, 59, 50, 186, 70, 42, 248, 107, 12, 33, 247, 66, 79, 53, 216, 159, 81, 145, 249, 179, 111, 233, 56, 49, 251, 123, 162, 26, 46, 182, 96, 208, 93,
114, 202, 255, 19, 164, 208, 79, 91, 241, 128, 158, 25, 252, 194, 217, 120, 22, 44, 1, 253, 45, 91, 113, 89, 203, 80, 34, 112, 99, 82, 103, 8, 90, 240, 39, 17, 230, 232, 80, 180, 173, 164, 112, 33, 217, 155, 170, 41, 187, 156, 213, 199, 176,
180, 177, 236, 167, 128, 31, 155, 210, 208, 55, 198, 5, 243, 27, 48, 78, 13, 142, 64, 80, 21, 18, 19, 175, 252, 126, 194, 111, 190, 99, 94, 184, 248, 167, 77, 45, 5, 141, 128, 72, 0, 45, 107, 88, 140, 147, 30, 248, 243, 208, 82, 137, 181, 69,
177, 8, 216, 25, 3, 239, 179, 160, 159, 129, 135, 23, 62, 192, 90, 91, 172, 119, 255, 55, 39, 78, 216, 12, 188, 45, 204, 93, 54, 30, 165, 129, 78, 151, 253, 92, 31, 196, 126, 4, 72, 182, 180, 216, 144, 78, 255, 185, 228, 134, 92, 103, 81, 2,
144, 123, 161, 101, 187, 145, 187, 171, 62, 21, 244, 17, 231, 203, 120, 176, 87, 150, 89, 244, 7, 29, 21, 235, 165, 86, 125, 184, 90, 232, 232, 145, 15, 198, 165, 103, 12, 245, 177, 151, 29, 45, 26, 184, 91, 20, 16, 231, 174, 237, 207, 165,
251, 114, 185, 245, 68, 82, 116, 216, 0, 203, 89, 234, 174, 100, 220, 60, 42, 60, 103, 17, 93, 208, 72, 242, 116, 148, 84, 230, 115, 56, 138, 134, 107, 199, 17, 73, 58, 75, 187, 200, 253, 141, 249, 246, 74, 201, 166, 194, 156, 72, 221, 20, 6,
91, 191, 243, 100, 3, 113, 79, 59, 175, 94, 112, 81, 69, 166, 145, 89, 163, 111, 180, 110, 146, 156, 43, 206, 248, 22, 188, 27, 123, 152, 65, 136, 212, 185, 83, 104, 162, 69, 21, 208, 116, 78, 193, 2, 179, 222, 109, 66, 75, 56, 46, 21, 105,
140, 236, 13, 78, 58, 30, 55, 114, 228, 96, 156, 89, 179, 116, 30, 63, 7, 52, 10, 182, 25, 87, 29, 166, 75, 64, 89, 30, 110, 40, 50, 121, 107, 44, 151, 246, 147, 131, 39, 105, 227, 58, 66, 56, 82, 107, 73, 91, 133, 210, 202, 174, 56, 108, 29,
117, 109, 128, 103, 237, 227, 13, 138, 177, 180, 146, 142, 82, 83, 115, 194, 148, 62, 74, 92, 154, 95, 194, 104, 216, 2, 166, 59, 150, 137, 164, 49, 189, 33, 236, 46, 82, 169, 73, 77, 177, 81, 67, 98, 181, 116, 49, 76, 97, 204, 227, 29, 203,
113, 110, 242, 255, 140, 46, 204, 144, 39, 234, 167, 30, 150, 110, 219, 138, 136, 88, 12, 179, 71, 23, 150, 233, 80, 217, 244, 248, 111, 65, 255, 69, 217, 55, 49, 43, 228, 225, 10, 123, 71, 41, 173, 7, 15, 194, 8, 87, 209, 75, 212, 179, 144,
151, 48, 134, 47, 109, 212, 8, 24, 66, 102, 198, 211, 35, 184, 154, 76, 147, 170, 90, 247, 53, 31, 164, 5, 189, 12, 208, 99, 185, 52, 74, 154, 137, 235, 112, 132, 5, 16, 65, 124, 87, 109, 83, 170, 37, 20, 88, 134, 2, 86, 218, 169, 222, 128,
202, 28, 87, 81, 154, 199, 124, 239, 130, 47, 88, 219, 61, 97, 18, 95, 81, 144, 123, 64, 49, 239, 24, 87, 134, 24, 102, 230, 169, 145, 83, 11, 126, 166, 230, 149, 31, 164, 94, 197, 27, 225, 35, 17, 24, 241, 140, 17, 42, 10, 40, 124, 217, 114,
116, 252, 232, 55, 77, 88, 75, 5, 48, 180, 220, 218, 124, 97, 177, 184, 192, 205, 59, 54, 89, 152, 79, 6, 64, 29, 167, 155, 62, 14, 197, 181, 66, 142, 153, 91, 230, 43, 96, 110, 122, 187, 235, 209, 190, 241, 128, 50, 23, 53, 114, 43, 111,
106, 99, 15, 232, 115, 101, 210, 234, 245, 238, 164, 56, 123, 94, 125, 223, 97, 210, 151, 91, 204, 4, 72, 140, 41, 143, 19, 93, 212, 153, 102, 182, 243, 102, 93, 214, 32, 68, 236, 146, 92, 168, 99, 46, 150, 249, 34, 177, 203, 105, 126, 129,
43, 156, 166, 3, 168, 43, 81, 183, 131, 168, 111, 131, 157, 155, 195, 195, 177, 47, 180, 82, 61, 225, 62, 150, 176, 212, 191, 129, 117, 98, 72, 173, 192, 36, 203, 15, 224, 254, 52, 127, 174, 231, 38, 213, 239, 120, 52, 178, 101, 97, 132, 130,
144, 152, 251, 226, 90, 18, 233, 74, 41, 88, 28, 17, 58, 177, 84, 226, 119, 241, 25, 192, 7, 157, 125, 170, 188, 191, 186, 75, 97, 225, 115, 184, 100, 168, 133, 0, 220, 95, 160, 242, 14, 185, 219, 214, 108, 157, 142, 32, 135, 69, 86, 64, 90,
236, 179, 137, 64, 128, 214, 63, 132, 152, 177, 167, 158, 8, 122, 139, 89, 115, 11, 27, 85, 94, 45, 12, 164, 18, 169, 213, 74, 196, 61, 55, 60, 238, 33, 77, 181, 88, 166, 61, 96, 152, 139, 209, 42, 223, 203, 149, 25, 93, 71, 132, 40, 77, 31,
187, 168, 88, 210, 106, 251, 181, 29, 15, 158, 194, 183, 176, 230, 91, 2, 124, 174, 86, 165, 57, 108, 191, 227, 106, 164, 159, 110, 35, 205, 248, 254, 105, 129, 25, 77, 6, 164, 93, 176, 192, 205, 26, 96, 109, 191, 35, 239, 46, 124, 53, 208,
221, 175, 169, 246, 68, 228, 158, 39, 221, 66, 234, 170, 154, 6, 192, 132, 25, 6, 168, 169, 26, 251, 183, 23, 204, 192, 34, 96, 126, 20, 183, 135, 20, 223, 115, 137, 254, 247, 13, 71, 7, 176, 162, 184, 184, 255, 128, 229, 236, 107, 42, 80,
68, 112, 127, 4, 57, 89, 26, 78, 251, 177, 21, 151, 224, 26, 227, 112, 78, 240, 11, 247, 87, 103 };
/**
* Constructor
*
* @param tPublicKey The Public Key Decoded (Since, we don't decode the key within the RC4
* class! - We do that elsewhere using FuseSecret!)
*/
public RC4(int tPublicKeyDecode)
{
this.pSBox = new int[256];
this.pKey = new int[256];
this.i = 0;
this.j = 0;
// Setup the pSBox (It's the table!)
this.init(tPublicKeyDecode);
}
/**
* Sets up the Encryption tables ready to encipher/decipher!
*/
@SuppressWarnings("unchecked")
private void init(int tKey)
{
String keyStr = Integer.toString(tKey);
for (int i = 0; i < 256; i++)
{
char meep = keyStr.charAt(i % keyStr.length());
pKey[i] = Character.getNumericValue(meep);
pSBox[i] = i;
}
int keyLength = (tKey & 31);
if (keyLength < 20)
keyLength += 20;
int keyOffset = (tKey % 1024);
int prevKey = 0, keySkip = 0, nKey = 0;
List cKey = new LinkedList();
cKey = new ArrayList();
for (int i = 0; i < 256; i++)
{
keySkip = ((i % 3) + (prevKey % 39));
nKey = pArtificialKey[(keyOffset + i + keySkip) % (pArtificialKey.length)];
prevKey = nKey;
cKey.add(Integer.toString(nKey));
}
for (int i = 0; i < 256; i++)
{
Object tmp = cKey.get(i % keyLength);
pKey[i] = Integer.parseInt(tmp.toString());
pSBox[i] = i;
}
int k = 0;
j = 0;
for (int i = 0; i < 256; i++)
{
j = (j + pSBox[i] + pKey[i]) % 256;
k = pSBox[i];
pSBox[i] = pSBox[j];
pSBox[j] = k;
}
i = 0;
j = 0;
}
/**
* Just for me, I, Mike, to do some hardc0re debugging!
*/
public void DebugTables()
{
for (int i = 0; i < pSBox.length; i++)
{
System.out.println("pSBox[" + Integer.toString(i) + "] = " + Integer.toString(pSBox[i]));
}
}
public char[] decipher(char[] data)
{
char[] result = new char[data.length / 2];
for (int x = 0, z = 0; x < data.length; x += 2, z++)
{
int t = RC4.hexToByte(data[x], data[x + 1]);
result[z] = (char)(t ^ moveUp());
}
return result;
}
private int moveUp()
{
i = (i + 1) % 256;
j = (j + pSBox[i]) % 256;
int swap = pSBox[i];
pSBox[i] = pSBox[j];
pSBox[j] = swap;
return pSBox[(pSBox[i] + pSBox[j]) % 256];
}
/**
* Very fast method for converting two hex bytes to the original byte.
* @param A The first byte.
* @param B The second byte.
* @return The result of the two bytes.
*/
private static int hexToByte(char A, char B)
{
int C = 0; // The output value
int D = 0; // Counter used for determining hex value
while (D < HEXALPHABET_CHARS.length)
{
if (HEXALPHABET_CHARS[D] == (A & 0xff))
{
C = (D << 4);
break;
}
D++;
}
D = 0;
while (D < HEXALPHABET_CHARS.length)
{
if (HEXALPHABET_CHARS[D] == (B & 0xff))
{
C += D;
break;
}
D++;
}
return C;
}
}
PHP Code:package com.blunk.security;
/**
* For now, we'll use a Static implementation of the RC4 Algorithm. USAGE: For use with
* "SECRET_KEY 0" only!
*
* @author Mike
* @deprecated
*/
@Deprecated
public class HabboRC4_static
{
private int i;
private int j;
private int table[];
private String[] di = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
/**
* The constructor
*
* @deprecated
*/
@Deprecated
public HabboRC4_static()
{
// No key to init remember! As this IS STATIC!
this.table = new int[256];
this.i = 0;
this.j = 0;
this.init();
}
/**
* Sets up the encryption tables!
*
* @deprecated
*/
@Deprecated
private void init()
{
// No decoded key to pass remember!
table[0] = 100;
table[1] = 196;
table[2] = 80;
table[3] = 73;
table[4] = 246;
table[5] = 166;
table[6] = 191;
table[7] = 151;
table[8] = 23;
table[9] = 25;
table[10] = 19;
table[11] = 4;
table[12] = 113;
table[13] = 27;
table[14] = 43;
table[15] = 251;
table[16] = 161;
table[17] = 54;
table[18] = 58;
table[19] = 121;
table[20] = 21;
table[21] = 31;
table[22] = 175;
table[23] = 176;
table[24] = 211;
table[25] = 125;
table[26] = 39;
table[27] = 98;
table[28] = 112;
table[29] = 193;
table[30] = 104;
table[31] = 95;
table[32] = 68;
table[33] = 186;
table[34] = 71;
table[35] = 149;
table[36] = 119;
table[37] = 3;
table[38] = 146;
table[39] = 135;
table[40] = 108;
table[41] = 67;
table[42] = 44;
table[43] = 172;
table[44] = 222;
table[45] = 209;
table[46] = 26;
table[47] = 160;
table[48] = 6;
table[49] = 148;
table[50] = 156;
table[51] = 48;
table[52] = 229;
table[53] = 192;
table[54] = 134;
table[55] = 59;
table[56] = 133;
table[57] = 35;
table[58] = 89;
table[59] = 225;
table[60] = 83;
table[61] = 111;
table[62] = 143;
table[63] = 9;
table[64] = 199;
table[65] = 153;
table[66] = 181;
table[67] = 106;
table[68] = 74;
table[69] = 194;
table[70] = 157;
table[71] = 174;
table[72] = 214;
table[73] = 63;
table[74] = 207;
table[75] = 77;
table[76] = 197;
table[77] = 105;
table[78] = 69;
table[79] = 227;
table[80] = 250;
table[81] = 123;
table[82] = 116;
table[83] = 30;
table[84] = 204;
table[85] = 178;
table[86] = 107;
table[87] = 16;
table[88] = 202;
table[89] = 15;
table[90] = 201;
table[91] = 252;
table[92] = 1;
table[93] = 217;
table[94] = 255;
table[95] = 124;
table[96] = 136;
table[97] = 127;
table[98] = 72;
table[99] = 20;
table[100] = 131;
table[101] = 28;
table[102] = 102;
table[103] = 103;
table[104] = 76;
table[105] = 210;
table[106] = 34;
table[107] = 224;
table[108] = 142;
table[109] = 185;
table[110] = 247;
table[111] = 190;
table[112] = 14;
table[113] = 248;
table[114] = 218;
table[115] = 115;
table[116] = 17;
table[117] = 198;
table[118] = 245;
table[119] = 36;
table[120] = 188;
table[121] = 150;
table[122] = 45;
table[123] = 213;
table[124] = 57;
table[125] = 212;
table[126] = 242;
table[127] = 114;
table[128] = 237;
table[129] = 203;
table[130] = 130;
table[131] = 163;
table[132] = 61;
table[133] = 239;
table[134] = 66;
table[135] = 52;
table[136] = 141;
table[137] = 144;
table[138] = 7;
table[139] = 235;
table[140] = 13;
table[141] = 183;
table[142] = 117;
table[143] = 79;
table[144] = 200;
table[145] = 171;
table[146] = 118;
table[147] = 75;
table[148] = 208;
table[149] = 177;
table[150] = 220;
table[151] = 51;
table[152] = 158;
table[153] = 169;
table[154] = 0;
table[155] = 147;
table[156] = 55;
table[157] = 206;
table[158] = 244;
table[159] = 219;
table[160] = 33;
table[161] = 145;
table[162] = 173;
table[163] = 129;
table[164] = 24;
table[165] = 253;
table[166] = 231;
table[167] = 40;
table[168] = 128;
table[169] = 60;
table[170] = 152;
table[171] = 37;
table[172] = 101;
table[173] = 5;
table[174] = 92;
table[175] = 91;
table[176] = 97;
table[177] = 139;
table[178] = 164;
table[179] = 243;
table[180] = 86;
table[181] = 221;
table[182] = 159;
table[183] = 42;
table[184] = 65;
table[185] = 109;
table[186] = 140;
table[187] = 195;
table[188] = 230;
table[189] = 236;
table[190] = 238;
table[191] = 81;
table[192] = 228;
table[193] = 249;
table[194] = 12;
table[195] = 187;
table[196] = 234;
table[197] = 137;
table[198] = 56;
table[199] = 32;
table[200] = 184;
table[201] = 162;
table[202] = 165;
table[203] = 254;
table[204] = 99;
table[205] = 179;
table[206] = 233;
table[207] = 85;
table[208] = 49;
table[209] = 232;
table[210] = 126;
table[211] = 88;
table[212] = 41;
table[213] = 82;
table[214] = 240;
table[215] = 70;
table[216] = 223;
table[217] = 93;
table[218] = 50;
table[219] = 90;
table[220] = 182;
table[221] = 170;
table[222] = 22;
table[223] = 122;
table[224] = 241;
table[225] = 226;
table[226] = 2;
table[227] = 10;
table[228] = 8;
table[229] = 154;
table[230] = 47;
table[231] = 53;
table[232] = 96;
table[233] = 62;
table[234] = 216;
table[235] = 180;
table[236] = 29;
table[237] = 94;
table[238] = 215;
table[239] = 168;
table[240] = 138;
table[241] = 189;
table[242] = 18;
table[243] = 87;
table[244] = 38;
table[245] = 120;
table[246] = 84;
table[247] = 11;
table[248] = 155;
table[249] = 205;
table[250] = 110;
table[251] = 78;
table[252] = 64;
table[253] = 132;
table[254] = 167;
table[255] = 46;
}
/**
* Deciphers incomming Habbo Packets!
*
* @param tData Data to decipher
* @return cipher Deciphered data!
* @deprecated
*/
@Deprecated
public String decipher(String tData)
{
int t = 0;
int k = 0;
StringBuffer cipher = new StringBuffer(tData.length());
for (int x = 0; x < tData.length(); x += 2)
{
i = (i + 1) % 256;
j = (j + table[i]) % 256;
t = table[i];
table[i] = table[j];
table[j] = t;
k = table[(table[i] + table[j]) % 256];
t = Integer.parseInt(tData.substring(x, x + 2), 16);
cipher = cipher.append((char)(t ^ k));
}
return cipher.toString();
}
/**
* Enciphers the data.
*
* @param tData The data to encipher
* @return The Enciphered data
* @deprecated
*/
@Deprecated
public String encipher(String tData)
{
int t = 0;
int k = 0;
StringBuffer cipher = new StringBuffer(tData.length() * 2);
for (int x = 0; x < tData.length(); x++)
{
i = (i + 1) % 256;
j = (j + table[i]) % 256;
t = table[i];
table[i] = table[j];
table[j] = t;
k = table[(table[i] + table[j]) % 256];
int c = tData.charAt(x) ^ k;
if (c <= 0)
{
cipher.append("00");
}
else
{
cipher.append(di[c >> 4 & 0xf]);
cipher.append(di[c & 0xf]);
}
}
return cipher.toString();
}
}

