【Java】防沉迷实名认证系统接口测试代码(已全示例通过)

下面的代码以及置顶文件使用并修改了作者:jspp@qq.com的开源代码,只作学习使用,侵删

背景:

在接入Taptap的防沉迷实名认证前,需要先通过国家防沉迷实名认证系统的接口测试,要求全部示例通过才能允许使用接口:

核心代码:

接口加密需要使用密钥对请求报文体数据进行AES-128/GCM + BASE64算法加密

java 复制代码
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class AESUtil {

//    这个算法在我这边跑不起来,所以换成了下面的那个方法
//    public static String  encrypt(String content, String key) {
//        try {
//            byte[] hexStr = hexToByteArray(key);
//            //加密算法:AES/GCM/PKCS5Padding
//         // 初始化加密算法
//            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//            SecretKeySpec skeySpec = new SecretKeySpec(hexStr, "AES");
//            //随机生成iv 12位
//            byte[] iv = RandomStringUtils.random(12).getBytes();
//            //数据加密, AES-GCM-128
//            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new GCMParameterSpec(128, iv));
//            byte[] encrypted = cipher.doFinal(content.getBytes());          //数据加密
//            //iv+加密数据 拼接  iv在前,加密数据在后
//            ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + encrypted.length);
//            byteBuffer.put(iv);
//            byteBuffer.put(encrypted);
//            byte[] cipherMessage = byteBuffer.array();
//            //java.util.Base64
//            return java.util.Base64.getEncoder().encodeToString(cipherMessage);
//
//        } catch (Exception e) {
//        	e.printStackTrace();
//            throw new RuntimeException(e);
//        }
//    }
    
    public static String encrypt(String cleartext,String key) {
        try 
        {
        	byte[] hexStr = hexToByteArray(key);
        	SecretKeySpec skeySpec = new SecretKeySpec(hexStr, "AES");
            // encoding format needs thought
            byte[] clearTextbytes = cleartext.getBytes("UTF-8");
            final SecureRandom secureKeyRandomness = SecureRandom.getInstanceStrong();
            final KeyGenerator AES_keyInstance = KeyGenerator.getInstance("AES");
            AES_keyInstance.init(128, secureKeyRandomness);
            final Cipher AES_cipherInstance = Cipher.getInstance("AES/GCM/NoPadding");
            AES_cipherInstance.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encryptedText = AES_cipherInstance.doFinal(clearTextbytes);
            byte[] iv = AES_cipherInstance.getIV();
            byte[] message = new byte[12 + clearTextbytes.length + 16];
            System.arraycopy(iv, 0, message, 0, 12);
            System.arraycopy(encryptedText, 0, message, 12, encryptedText.length);
            return java.util.Base64.getEncoder().encodeToString(message);
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static byte[] hexToByteArray(String hex) {
        int l = hex.length();
        byte[] data = new byte[l / 2];
        for (int i = 0; i < l; i += 2)
        {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }

}

使用SHA256算法对待加密字符串进行计算

java 复制代码
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha256Utils {

    /**
     * 利用java原生的类实现SHA256加密
     * @param str 加密后的报文
     * @return
     */
    public static String getSHA256(String str){
        MessageDigest messageDigest;
        String encodestr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodestr = byte2Hex(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodestr;
    }
    /**
     * 将byte转为16进制
     * @param bytes
     * @return
     */
    private static String byte2Hex(byte[] bytes){
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i=0;i<bytes.length;i++){
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length()==1){
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }

}

坑爹的点:

  1. 接口测试中使用的AppId、密钥等并非Taptap那边的数据,而是网络游戏防沉迷实名认证系统中的相关数据:
  2. 测试数据要尽可能多地使用《网络游戏防沉迷实名认证系统测试系统说明》中的所有数据,数据集一定要够多,有部分数据是有规律的,可以类推更多的其他数据,加大训练集,比如这些:
  3. 出现错误码:1005 SYS REQ IP ERROR (接口请求IP地址非法),应该是在网络游戏防沉迷实名认证系统的IP白名单中没有填入公网IP:
  4. 出现错误码:1007 SYS REQ EXPIRE ERROR (接口请求过期) ,原因是传入的timestamp没有算东八区的时间戳(单位毫秒),在Java中比较简单,直接用System.currentTimeMillis(),但是其他编程语言要记得算上时区
  5. 出现错误码:1011 SYS REQ PARTNER AUTH ERROR(接口请求方身份核验错误),原因是上面提到的接口加密算法(AES-128/GCM + BASE64加密)或者 SHA256算法加签算法有问题,可以直接参考一下上述Java版的代码
  6. 出现错误码:1012 SYS REQ PARAM CHECK ERROR (接口请求报文核验失败),看一下自己报文的拼接是否出现了问题,要严格按照文档的格式来拼接,详情可以看我置顶文件,里面有整个maven项目
  7. 出现错误码:4002 TEST TASK NOT EXIST (测试任务不存在),原因是某一项测试数据已经通过了,这个测试数据就不能再用了,也有可能是你的测试码过期了,更新一下测试码即可
相关推荐
XXX-171 天前
3.postman脚本语言、接口关联(json引用(变量)、脚本用正则表达式)、断言封装、自动化构造接口请求(Postman工具)
软件测试·接口测试·postman
XXX-172 天前
7.Jmeter数据驱动(csv数据文件设置)+Jmeter数据库操作
软件测试·jmeter·接口测试
XXX-172 天前
1.接口测试基础
软件测试·接口测试
XXX-174 天前
6.接口测试加密接口(Jmeter/工具/函数助手对话框、Beanshell脚本)
软件测试·jmeter·接口测试
MYPM_AndyLiu4 天前
Codes 开源研发项目管理平台——敏捷测试管理创新解决方案
jmeter·接口测试·postman·缺陷管理·testlink·测试用例管理·开源免费测试理平台
XXX-174 天前
3.接口测试的基础/接口关联(Jmeter工具/场景一:我一个人负责所有的接口,项目规模不大)
软件测试·接口测试
土小帽软件测试11 天前
F12抓包04:(核心功能)Network接口抓包、定位缺陷
接口测试·抓包·软件测试学习·f12·f12抓包
土小帽软件测试11 天前
F12抓包06-1:浏览器导出postman测试脚本
测试工具·接口测试·postman·抓包·软件测试学习·f12·f12抓包
小码哥说测试14 天前
接口测试 —— 如何设计高效的测试用例!
自动化测试·软件测试·python·selenium·测试工具·测试用例·接口测试
FIT2CLOUD飞致云21 天前
IDEA插件支持API调试、接口用例支持一键同步API变更,MeterSphere开源持续测试工具v3.2.0版本发布
开源·接口测试·metersphere·团队协作·持续测试·测试管理