# Java
# Java AES256
# 说明:
到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)
gradle配置:
compile 'com.google.guava:guava:21.0' compile 'com.squareup.okhttp3:okhttp:3.8.0' compile 'net.sf.json-lib:json-lib:2.4:jdk15'
# Java代码示例(jdk1.8)
/*
* This Java source file was generated by the Gradle 'init' task.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Base64;
import java.util.Random;
import java.util.Iterator;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import net.sf.json.JSONArray;
import net.sf.json.JSONFunction;
import net.sf.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.RequestBody;
import okhttp3.MediaType;
public class App {
private static String SNUSER = "xxx";
private static String SNKEY = "xxxx";
private static String SHA1(String decript) {
try {
MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
digest.update(decript.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
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 countryCode, String nationalNumber) {
List list = new ArrayList();
Map map = new LinkedHashMap();
String sha1 = SHA1(nationalNumber);
map.put("country_code", countryCode);
map.put("national_number_sha1", sha1);
list.add(map);
JSONArray jsArr = JSONArray.fromObject(list);
System.out.println("request plain =>" + jsArr);
String encoded = Base64.getEncoder().encodeToString(encryptAES(jsArr.toString()));
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://api.yazx.com/phone/check/v3/")
.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) {
TestGetStatus("86", "13800000000");
}
}