# 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");
    }
}
Last Updated: 3/12/2024, 3:19:42 PM