一、前言
token加密原理分析主要参考:http://www.360doc.com/content/19/1108/09/13474884_871818718.shtml 由于在网上搜到的都是使用python来解码的,这里加上使用java来加密解密美团外卖店铺列表等接口的token参数和X-FOR-WITH
二、代码示例
1.token加密解密
(1) 取出token值
(2)代码解密
使用代码解密得出
其中token解密出的数据中有sign这一项,使用同样的方法解密,即可得出sign是由什么参数加密而来。
加密和解密代码如下:
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterOutputStream;
public class TokenHelp {
public static void main(String[] args) throws Exception{
String token="eJx9kuuOojAUgN+FhP2jESigYGImIIjAeAdH3Ww2aBEqN4UCwmbffTv3zWSzSdNzztfTpN9Jf1G5Cakhx3IDlutSlZ9TQ4rrsb0+1aVwQU5ESRhIgjAY8GDQpU6fTOR4GbBClzrmW40afhcFtgtE9sczWJP6E3xmQCDrucMkDVSI8bUYMkwo9moPJR7qJT7CpZf2TlnCvCImQSn070yE0iDK0uAh9SoUeNh3mqs/kjn22xnlBR4TEmR5Y8IXVvinLIVfIEY49ke0PqBVnZZ0WpdphaflCTH9/0viLEDpwznLT/4I56X/7eidop9lHo9e7tG8QoMJWf+8TfgrJMmrC0nebWh+8rcPzWvkoTTof3H64F+9Pg5e3EhFA5H4AZEYAlF63oglEIknEIkpGX3ikNGTGL1F7y3i93pGfgAZSYGClGS+1cSRjqugVVbhUn7UckGd40Cyq9i9ra2ND679dSAUhZmdGytImDPkoqjKMIQVTGEiX8bqghEKczpH85CvtZ2r8HU/twxBXQi4BPx4lavt1K3jLX9g+ovbZMZNVve2rBzbspssq3dLw3DF6yop5Ylg2dqBi098YGzchSk5AHUqcd2Oi1yMwKbdINa+zLQnZb+dgcGBt6YoaD3FFw75rF2pxzio3WqxTdjxbdmuw6Nu80XHx1ttwV7QyQFM3cLsyTEaL2yVs2AbS9xC2Flru7OkYFUXph0z3OD9qoW3I2TaR+Yu1rMDf9s3DLzDzX2vNxuRNU2urNlD3582k3A953ZOYVX9amY/FigvJSN5cmXDvahyR9kpTnxxR9TvP6gPHhs=";
String result = decompressData(token);
System.out.println(result);
JSONObject jsonObject = JSONObject.parseObject(result);
String sign = jsonObject.get("sign").toString();
String params = decompressData(sign);
System.out.println(params);
}
/**
* zlib压缩+base64
*/
public static String compressData(String data) {
ByteArrayOutputStream bos;
DeflaterOutputStream zos;
try {
bos = new ByteArrayOutputStream();
zos = new DeflaterOutputStream(bos);
zos.write(data.getBytes());
zos.close();
return new String(Base64.encodeBase64(bos.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* zlib解压+base64
*/
public static String decompressData(String encdata) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InflaterOutputStream zos = new InflaterOutputStream(bos);
zos.write(Base64.decodeBase64(encdata.getBytes()));
zos.close();
return new String(bos.toByteArray());
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
2.X-FOR-WITH
加密分析依然参考上面的分析原理
加解密代码如下:
package com.tang.crawler.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AESEncryptionUtil {
public static String key="jvzempodf8f9anyt";
/**
* 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。
* 偏移量必须为16位
* @param sKey
* @param ivParameter
* @param sSrc
* @return
*/
public static String encrypt(String sKey, String ivParameter, byte[] sSrc) {
try {
return new BASE64Encoder()
.encode(getCipher(sKey, ivParameter, Cipher.ENCRYPT_MODE).doFinal(sSrc));//此处使用BASE64做转码。
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
* @param sKey key
* @param ivParameter 偏移量
* @param sSrc
* @return
*/
public static byte[] decrypt(String sKey, String ivParameter, byte[] sSrc) {
try {
return getCipher(sKey, ivParameter, Cipher.DECRYPT_MODE)
.doFinal(new BASE64Decoder().decodeBuffer(new String(sSrc)));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
/**
* 加密算法
* @param seed key
* @param ivParameter 偏移量
* @param encryptMode 模式
* @return
* @throws UnsupportedEncodingException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidAlgorithmParameterException
* @throws InvalidKeyException
*/
private static Cipher getCipher(String seed, String ivParameter, int encryptMode)
throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
byte[] raw = seed.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
cipher.init(encryptMode, skeySpec, iv);
return cipher;
}
public static void main(String[] args) throws Exception{
String text="Q8/eNHqW/CHdiHWHwSVXawZ3tNAA6f/DPMyA02ix0kTFnJ126UbyIO/5pbLzl9hw3+naadrcvTeDN6gMCMzwtguvA2ByJdFeRtpEUj58RDKIFjvt1G22vaVW5dU5kfLp9YDT07gNnWSny2WCrTjoECfD7LEegh09Cudc5G8fro/zL+Uv4LaSyEyazlFP9nxTRKap7yxnhR8uPFP/O3HVlw==";
byte[] decrypt = decrypt(key, key, text.getBytes("UTF-8"));
String result = new String(decrypt);
System.out.println(result);
String encrypt = encrypt(key, key, result.getBytes("UTF-8"));
System.out.println(encrypt);
}
}