Java服务器的JSON数据包三重加密算法

由于游戏对数据包的传输内容很关注,如果写的不好很容易被破解。我这里采用的是json传输数据,所以要对数据进行加密解密,用来更方便的做操作。

基本加密顺序就是 JSON字符串->Base64字符串->DES加密

其中

Base64是一重加密

Base64里面我改进了算法,支持任意形式的字典表,所以这个地方是第二重加密

DES在Base64的基础上再次用秘钥加密。

有人问为什么还需要改Base64的字典表,其实原因就是DES的秘钥只能是8个字节,按照现在计算机的处理速度,24小时就破解了。

 

首先我们要有个处理Base64的处理类,这里我把网上一个公开的类库做了改进,做了一个混排编码格式

 

 

public class Base64 {

 

private static final char[] legalChars = “ghijk67stuJKLM89rvwxyzAlmnOUV+/abcdefPQRSTopqCDEFG012345BHINWXYZ”

.toCharArray();//字典内顺序任意更改,只要内容保证不缺就行

private static HashMap<Character,Integer> hashDecode=new HashMap<Character,Integer>();

/**

* data[]进行编码

*

* @param data

* @return

*/

 

public static String encode(byte[] data) {

int start = 0;

int len = data.length;

StringBuffer buf = new StringBuffer(data.length * 3 / 2);

 

int end = len – 3;

int i = start;

int n = 0;

 

while (i <= end) {

int d = ((((int) data[i]) & 0x0ff) << 16)

| ((((int) data[i + 1]) & 0x0ff) << 8)

| (((int) data[i + 2]) & 0x0ff);

 

buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append(legalChars[d & 63]);

 

i += 3;

 

if (n++ >= 14) {

n = 0;

buf.append(” “);

}

}

 

if (i == start + len – 2) {

int d = ((((int) data[i]) & 0x0ff) << 16)

| ((((int) data[i + 1]) & 255) << 8);

 

buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append(“=”);

} else if (i == start + len – 1) {

int d = (((int) data[i]) & 0x0ff) << 16;

 

buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(“==”);

}

 

return buf.toString();

}

public static byte[] decode(String s) {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

try {

decode(s, bos);

} catch (IOException e) {

throw new RuntimeException();

}

byte[] decodedBytes = bos.toByteArray();

try {

bos.close();

bos = null;

} catch (IOException ex) {

System.err.println(“Error while decoding BASE64: ” + ex.toString());

}

return decodedBytes;

}

private static void decode(String s, OutputStream os) throws IOException {

int i = 0;

 

int len = s.length();

 

while (true) {

while (i < len && s.charAt(i) <= ‘ ‘)

i++;

 

if (i == len)

break;

 

int tri = (decode(s.charAt(i)) << 18)

+ (decode(s.charAt(i + 1)) << 12)

+ (decode(s.charAt(i + 2)) << 6)

+ (decode(s.charAt(i + 3)));

 

os.write((tri >> 16) & 255);

if (s.charAt(i + 2) == ‘=’)

break;

os.write((tri >> 8) & 255);

if (s.charAt(i + 3) == ‘=’)

break;

os.write(tri & 255);

 

i += 4;

}

}

private static int decode(char c) {

if(hashDecode.size()==0)

{

for(int i =0;i<64;i++)

{ char ch = legalChars[i];

hashDecode.put(ch, i);

}

}

if(hashDecode.containsKey(c))

{

return hashDecode.get(c);

}

else if(c ==’=’)

return 0;

else

throw new RuntimeException(“unexpected code: ” + c);

}

}

 

 

然后是Des加密算法

 

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

 

public class DateSecret {

 

private static String keyCode=”123456″;//秘钥可以任意改,只要总长度是8个字节就行

private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };

public static String encryptDES(String encryptString)

throws Exception {

IvParameterSpec zeroIv = new IvParameterSpec(iv);

SecretKeySpec key = new SecretKeySpec(keyCode.getBytes(), “DES”);

Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”);

cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

byte[] encryptedData = cipher.doFinal(encryptString.getBytes(“utf-8”));

return Base64.encode(encryptedData);

}

public static String decryptDES(String decryptString)

throws Exception {

byte[] byteMi = Base64.decode(decryptString);

IvParameterSpec zeroIv = new IvParameterSpec(iv);

SecretKeySpec key = new SecretKeySpec(keyCode.getBytes(), “DES”);

Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”);

cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);

byte decryptedData[] = cipher.doFinal(byteMi);

 

return new String(decryptedData ,”utf-8″);

}

/**将二进制转换成16进制

* @param buf

* @return  String

*/

public static String parseByte2HexStr(byte buf[]) {

StringBuffer sb = new StringBuffer();

for (int i = 0; i < buf.length; i++) {

String hex = Integer.toHexString(buf[i] & 0xFF);

if (hex.length() == 1) {

hex = ‘0’ + hex;

}

sb.append(hex.toUpperCase());

}

return sb.toString();

}

 

}

使用示例

 

 

String strDecode = DateSecret.decryptDES(str);//解密

 

String strOut = DateSecret.encryptDES(str);//加密

标签