aes-128-gcm算法,对接中宣部防沉迷

  • 对接国家防沉迷系统,加密字符串部分
	private static final Integer ZERO = 0;
    private static final Integer MAC = 16;
    private static final Integer DEFAULT_GCM_LV = 12;
    private static final Integer SECRET_LENGTH_128 = 128;
    private static final String AES = "AES";
    private static final String ALGORITHM = "AES/GCM/PKCS5Padding";
    private static final String UTF8= "utf-8";
    
	/**
     * 转换16进制字符串
     **/
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }
    
	/***
     * @version 1.0 aes-128-gcm 加密
     * @params content 为加密信息 secretKey 为32位的16进制key
     * @return 返回base64编码
     **/
    public static String encryptByAES128Gcm(String content, String secretKey) {
        try {
            SecretKey key = new SecretKeySpec(parseHexStr2Byte(secretKey), AES);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] iv = cipher.getIV();//oracle jdk default 12
            byte[] encryptData = cipher.doFinal(content.getBytes(UTF8));
            byte[] message = new byte[DEFAULT_GCM_LV + content.getBytes(UTF8).length + MAC];
            System.arraycopy(iv, ZERO, message, ZERO, DEFAULT_GCM_LV);
            System.arraycopy(encryptData, ZERO, message, DEFAULT_GCM_LV, encryptData.length);
            return Base64.encodeBase64String(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    
	/***
     * @version 1.0 aes-128-gcm 解密
     * @return  返回解密字符串
     */
    public static String decryptByAES128Gcm(String content, String secretKey) throws Exception {
        SecretKey key = new SecretKeySpec(parseHexStr2Byte(secretKey), AES);
        byte[] message = Base64.decodeBase64(content);
        Cipher cipher= Cipher.getInstance(ALGORITHM );
        GCMParameterSpec params = new GCMParameterSpec(SECRET_LENGTH_128, message, ZERO, DEFAULT_GCM_LV);
        cipher.init(Cipher.DECRYPT_MODE, key, params);
        byte[]  decryptData = cipher.doFinal(message, DEFAULT_GCM_LV, message.length - DEFAULT_GCM_LV);
        return new String(decryptData);
    }
  • SHA256对加密字符计算部分
	public static final String ENCODE_ALGORITHM = "SHA-256";

    public static String done(String str) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance(ENCODE_ALGORITHM);
            messageDigest.update(str.getBytes());
            byte[] outputDigest_sign = messageDigest.digest();
            return bytesToHexString(outputDigest_sign);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
  • 补充
  1. 密钥为16进制字符串,需要进行转换;
  2. 调试接口,测试用例需参考指定文档,使用规定的数据进行测试(之前调试使用自己的数据,调试半天不通过╮(╯▽╰)╭);
  3. 字符转字节需要指定utf-8的编码格式。String.getBytes()默认取操作系统的编码格式,如ide中指定,则以指定的编码格式为准。

版权声明:本文为XJYPC原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。