# Java
# 一.说明
关于Java AES256bit的问题: 到Oracle官网下载对应Java版本的 JCE ,解压后放到 JAVA_HOME/jre/lib/security/
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html (opens new window) http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html (opens new window) http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html (opens new window) 替换标准JDK不支持AES 256bit加密的问题
关于jdk <1.8时base64问题: jdk版本小于1.8时需替换base64算法(demo使用的是java.util.Base64,jdk1.8才支持)。 若替换成sun.misc.BASE64Encoder,注意要去掉BASE64Encoder生成的换行符, 否则服务端会返回json解析错误 关于Invalid AES key length: xxx bytes 问题: 首选确保Java AES256bit替换jdk问题已解决,然后,查看SNKEY和SNUSER是否填反,最后看SNKEY长度是否正确(32bytes)
延迟查询失败问题: 为避免网络传输及处理延迟造成的查询失败,建议单次查询的手机号码数量不要超过100个。
# 二.代码示例
import java.util.Base64;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import net.sf.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.RequestBody;
import okhttp3.MediaType;
public class IpOnline {
private static String SNUSER = "XXX";
private static String SNKEY = "XXX";
private static byte[] encryptAES(String phoneno) {
try {
SecretKeySpec key = new SecretKeySpec(SNKEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
byte[] phonenobyteContent = phoneno.getBytes();
byte[] ivbytes = new byte[16];
Random rand = new Random();
rand.nextBytes(ivbytes);
IvParameterSpec ivSpec = new IvParameterSpec(ivbytes);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec );
byte[] result = cipher.doFinal(phonenobyteContent);
byte[] finalbytes = new byte[ivbytes.length + result.length];
System.arraycopy(ivbytes, 0, finalbytes, 0, ivbytes.length);
System.arraycopy(result, 0, finalbytes, ivbytes.length, result.length);
return finalbytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] decryptAES(String phoneno) {
try {
byte[] asBytes = Base64.getDecoder().decode(phoneno.toString().replace("\n", ""));
byte[] iv = new byte[16];
byte[] encryptBytes = new byte[asBytes.length - iv.length];
System.arraycopy(asBytes, 0, iv, 0, iv.length);
System.arraycopy(asBytes, iv.length, encryptBytes, 0, encryptBytes.length);
SecretKeySpec key = new SecretKeySpec(SNKEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivspec);
byte[] result = cipher.doFinal(encryptBytes);
return result;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void TestGetStatus(String data) {
String encoded = Base64.getEncoder().encodeToString(encryptAES(data));
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,
"{\"snuser\": \"" + SNUSER + "\", \"data\": \"" + encoded + "\"}");
Request request = new Request.Builder()
.url("https://ipdata.yazx.com/api/ip/v2/check/")
.post(body)
.addHeader("content-type", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
String jsonData = response.body().string();
System.out.println("response plain =>" + jsonData);
JSONObject object = JSONObject.fromObject(jsonData);
String encryptData = object.getString("data");
byte[] deDataBytes = decryptAES(encryptData);
System.out.println("result => success" + new String(deDataBytes, "utf-8"));
} catch (Exception e) {
System.out.println("result => failed");
e.printStackTrace();
}
}
public static void main(String[] args) {
String Data = "{\"ip\": \"122.241.179.74\", \"attack_time\": 1663320929}";
TestGetStatus(Data);
}
}