业务方携带动画验证码校验成功后的validate来调用此接口进行二次验证。validate在一段时间内有效,接口IP需要配置IP白名单。
请求地址:https://openapi-gy.getui.com/v1/gy/captcha/verify
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 |
---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id |
gyuid | String | 必选 | 个验用户唯一标识 |
businessId | String | 必选 | 动画验证码业务id |
validate | String | 必选 | 动画验证码验证结果查询凭证 |
timestamp | Long | 必选 | 毫秒精度时间戳 |
sign | String | 必选 | 接口签名,生成规则: 1. 筛选:获取所有非空参数值的请求参数,不包括字节类型参数,如文件、字节流,剔除sign参数。 2. 排序:将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。 3. 拼接:将排序后的参数与其对应值,使用URL键值对的格式(即key1=value1&key2=value2…)拼接,此时生成的字符串为待签名字符串。将待签名字符串拼上“&key=${masterSecret}”,带入SHA256算法中得出sign。 |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 | |
verifyResult | 3 | Boolean | 可选 | 二次验证结果, true:成功 false:失败 |
{
"appId": "LLNstWgyGm8UM2SsherlU5",
"gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
"businessId": "20180523",
"validate": "6a2cab5c0abc06ea9a1503ff4eb619d1",
"timestamp": 1529391652123,
"sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功",
"data": {
"verifyResult": true,
}
}
}
返回码 | 返回码描述 |
---|---|
20000 | 接口调用成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40031 | IP受限 |
40032 | 参数错误 |
50000 | 未知错误 |
50001 | 其他错误 |
60001 | 业务ID无效 |
60002 | 请求过快 |
60004 | 无权限 |
60008 | sign验证失败 |
业务方携带反欺诈接口返回的token来调用此接口获取反欺诈结果,进行二次校验。token在一段时间内有效,接口需要配置IP白名单。
请求地址:https://openapi-gy.getui.com/v1/af/antifraud_query
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 |
---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id |
gyuid | String | 必选 | 个验用户唯一标识 |
token | String | 必选 | 查询反欺诈结果凭证 |
timestamp | Long | 必选 | 毫秒时间戳(13位),请使用当前毫秒时间戳,误差太大可能出错 |
sign | String | 必选 | 鉴权时的签名。 生成 sign 值:将 appId 、gyuid 、appkey、token、timestamp、mastersecret 对应的字符串按此固定顺序拼接后,使用 SHA256 算法加密。 示例 java 代码格式: String sign = sha256(appId + gyuid + token + timestamp + masterSecret) |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 | |
riskLevel | 3 | String | 可选 | 分为0-4共5个等级,0代表可信用户,1-2代表怀疑用户,3-4代表风险用户 |
riskType | 3 | Array |
可选 | 1:帐号风险,2:网络风险,3:设备风险,4:行为风险 |
{
"appId": "LLNstWgyGm8UM2SsherlU5",
"gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
"token": "6a2cab5c0abc06ea9a1503ff4eb619d1",
"timestamp": 1529391652123,
"sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功",
"data": {
"riskLevel": "1",
"riskType": ["1"],
}
}
}
返回码 | 返回码描述 |
---|---|
20000 | 成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40031 | IP受限 |
40032 | 参数错误 |
40033 | 请求过快,请稍后再试 |
40036 | 无权限 |
40041 | token失效 |
40044 | sign验证失败 |
50000 | 未知错误 |
50001 | 其他错误 |
业务方服务端在获取gyuid后,可通过gyuid定期按需获取设备风险信息。接口需配置IP白名单。
请求地址:https://openapi-gy.getui.com/v1/af/antifraud
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 |
---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id |
gyuid | String | 必选 | 个验用户唯一标识 |
userIp | String | 可选 | 用户ip |
pn | String | 可选 | 手机号码MD5 |
scene | Integer | 必选 | 场景,0:通用,1:注册,2:登录 |
timestamp | Long | 必选 | 毫秒精度时间戳 |
sign | String | 必选 | 1. 筛选:获取所有非空参数值的请求参数,不包括字节类型参数,如文件、字节流,剔除sign参数。 2. 排序:将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。 3. 拼接:将排序后的参数与其对应值,使用URL键值对的格式(即key1=value1&key2=value2…)拼接,此时生成的字符串为待签名字符串。将待签名字符串拼上“&key=${masterSecret}”,带入SHA256算法中得出sign。 |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 | |
riskLevel | 3 | String | 可选 | 分为0-4共5个等级,0代表可信用户,1-2代表怀疑用户,3-4代表风险用户 |
riskType | 3 | Array |
可选 | 1:帐号风险,2:网络风险,3:设备风险,4:行为风险 |
{
"appId": "LLNstWgyGm8UM2SsherlU5",
"gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
"scene": 1,
"timestamp": 1529391652123,
"sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功",
"data": {
"riskLevel": "1",
"riskType": ["1"],
}
}
}
返回码 | 返回码描述 |
---|---|
20000 | 成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40031 | IP受限 |
40032 | 参数错误 |
40033 | 请求过快,请稍后再试 |
40034 | 今日验证次数超限 |
40036 | 无权限 |
40044 | sign验证失败 |
50000 | 未知错误 |
50001 | 其他错误 |
业务方调用此接口获取手机号,参数token是来自于SDK端调用一键认证之后返回的用户授权凭证信息。token在一段时间内有效,接口IP需要配置IP白名单。
注:返回的手机号采用AES加密,密钥为应用对应的masterSecret,算法参考【附录】AES解密说明(直接下载: Java、 PHP、 Python、 NodeJs)。
请求地址:https://openapi-gy.getui.com/v2/gy/ct_login/gy_get_pn
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 |
---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id |
timestamp | Long | 必选 | 毫秒时间戳(13位),请使用当前毫秒时间戳,误差太大可能出错 |
sign | String | 必选 | 鉴权时的签名。 生成 sign 值:将 appkey、timestamp、mastersecret 对应的字符串按此固定顺序拼接后,使用 SHA256 算法加密。 示例 java 代码格式: String sign = sha256(appkey+timestamp+mastersecret) |
token | String | 必选 | 调用SDK上传token返回的凭证 (默认是10分钟的失效时间) |
gyuid | String | 必选 | 个验用户唯一标识,客户端CallBack回调方法中获取 |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 | |
pn | 3 | String | 可选 | AES加密的手机号,密钥为应用对应的masterSecret |
{
"appId": "LLNstWgyGm8UM2SsherlU5",
"timestamp": 1529391652123,
"gyuid":"12313ssad",
"sign": "8f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab517d1",
"token": ""
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功",
"data": {
"pn": "1fbf2605f954fad3ba18115000735aee",
}
}
}
返回码 | 返回码描述 |
---|---|
20000 | 接口调用成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40026 | 签名错误 |
40027 | 获得auth_token失败 |
40031 | IP受限 |
40032 | 参数错误 |
40033 | 请求过快,请稍后再试 |
40034 | 今日次数超限 |
40047 | 获取号码失败,解决办法: 1,检查客户端生成gyuid的appid 与 服务端appid是否一致。 2,可能调服务端接口取号的token失效了,客户端重新获取一键登入返回的token。 |
50000 | 未知错误 |
50001 | 其他错误 |
50002 | 未知错误 |
业务方调用此接口获取手机号,参数token是来自于SDK端调用一键认证之后返回的用户授权凭证信息。token在一段时间内有效,接口IP需要配置IP白名单。
注:返回的手机号采用AES加密,密钥为应用对应的masterSecret,算法参考【附录】AES解密说明(直接下载: Java、 PHP、 Python、 NodeJs)。
请求地址:https://h-gy.getui.net/v2/gy/ct_login/gy_get_pn
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 | |
---|---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id | |
timestamp | Long | 必选 | 毫秒时间戳(13位),请使用当前毫秒时间戳,误差太大可能出错 | |
token | String | 必选 | 调用SDK上传token返回的凭证 (默认是10分钟的失效时间) | |
gyuid | String | 必选 | 个验用户唯一标识,客户端CallBack回调方法中获取 |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 | |
pn | 3 | String | 可选 | AES加密的手机号,密钥为应用对应的masterSecret |
{
"appId": "LLNstWgyGm8UM2SsherlU5",
"timestamp": 1529391652123,
"gyuid":"12313ssad",
"token": ""
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功",
"data": {
"pn": "1fbf2605f954fad3ba18115000735aee",
}
}
}
返回码 | 返回码描述 |
---|---|
20000 | 接口调用成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40026 | 签名错误 |
40027 | 获得auth_token失败 |
40031 | IP受限 |
40032 | 参数错误 |
40033 | 请求过快,请稍后再试 |
40034 | 今日次数超限 |
40047 | 获取号码失败,解决办法: 1,检查客户端生成gyuid的appid 与 服务端appid是否一致。 2,可能调服务端接口取号的token失效了,客户端重新获取一键登入返回的token。 |
50000 | 未知错误 |
50001 | 其他错误 |
50002 | 未知错误 |
业务方调用校验本机手机号,参数token是来自于调用SDK返回的凭证。凭证在一段时间内有效,接口IP需要配置IP白名单。
请求地址:https://h-gy.getui.net/v1/gy/ct_login/server_token_validate
协议:HTTPS
请求方法:POST+json
参数 | 类型 | 约束 | 说明 | |
---|---|---|---|---|
appId | String | 必选 | 业务在个验申请的应用id | |
timestamp | Long | 必选 | 时间戳 | |
sign | String | 必选 | 鉴权时的签名。 生成 sign 值:将 appkey、timestamp、mastersecret 对应的字符串按此固定顺序拼接后,使用 SHA256 算法加密。 示例 java 代码格式: String sign = sha256(appkey+timestamp+mastersecret) |
|
token | String | 必选 | 调用SDK返回的凭证 | |
gyuid | String | 必选 | 个验用户唯一标识,客户端CallBack回调方法中获取 |
参数 | 层级 | 类型 | 约束 | 说明 |
---|---|---|---|---|
errno | 1 | Int | 必选 | 固定值 0 |
data | 1 | Object | 必选 | |
msg | 2 | String | 必选 | 接口返回码说明 |
result | 2 | String | 必选 | 接口返回码 |
data | 2 | Object | 可选 |
{
"gyuid":"3d56d9ee11f64e1bb68741696540821333",
"appId":"EsNxapHV5v98pP2Qd704f3",
"token":"1f64e1bb68741",
"timestamp":1563261119000,
"sign":"c6c30c460bcf75e4260fd59d942fc03c1205da4c877dbbc32a1b2ed335cea61f"
}
{
"errno": "0",
"data": {
"result": "20000",
"msg": "成功"
}
}
返回码 | 返回码描述 |
---|---|
20000 | 接口调用成功 |
40004 | 应用无效,应用不存在 |
40005 | appid为空 |
40009 | 未知错误 |
40026 | 签名错误 |
40027 | 获得auth_token失败 |
40031 | IP受限 |
40032 | 参数错误 |
40033 | 请求过快,请稍后再试 |
40034 | 今日次数超限 |
40053 | 手机号校验失败 |
50000 | 未知错误 |
50001 | 其他错误 |
50002 | 未知错误 |
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Date: 2019/12/18
* Description: AES解密
* */
public class AESUtil{
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//加密算法
private static final byte[] IV = "0000000000000000".getBytes(); //初始化向量
/**
* AES 解密操作
*
* @param content 待解密内容
* @param key 加密密钥
* @return 解密数据
* */
public static String decrypt(String content, String key) {
try {
// 创建密码器
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
// 配置密码器
IvParameterSpec ivSpec = new IvParameterSpec(IV);
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key), ivSpec);
// 解密
byte[] result = cipher.doFinal(hex2Bytes(content));
// 格式化输出
return new String(result, StandardCharsets.UTF_8);
} catch (Exception e) {
return null;
}
}
/**
* 获取密钥,取前16位,不足则复制
*
* @param key 用户密钥
* @return KeySpec对象
* */
private static SecretKeySpec getSecretKey(String key) {
if(key==null || key.isEmpty()){
return null;
}
StringBuilder s = new StringBuilder(key);
while(s.length() < 16){
s.append(key);
}
return new SecretKeySpec(s.substring(0,16).getBytes(), KEY_ALGORITHM);
}
/**
* hex字符串转byte数组
*
* @param hex 待转换的hex字符串
* @return 转换后的byte数组
* */
private static byte[] hex2Bytes(String hex){
if (hex.length() % 2 == 1){
hex="0" + hex;
}
byte[] result = new byte[hex.length()/2];
for (int i = 0; i < result.length; i++){
result[i] = (byte)Integer.parseInt(hex.substring(2*i,2*i+2), 16);
}
return result;
}
public static void main(String[] args) {
String pn = "1fbf2605f954fad3ba18115000735aee"; //密文
String masterSecret = "126781"; //密钥
System.out.println("解密后:" + AESUtil.decrypt(pn, masterSecret));
}
}
// 密文及密钥
$pn = '1fbf2605f954fad3ba18115000735aee';
$masterSecret = '126781';
// 参数设置
$encryptMethod = 'aes-128-cbc';
$iv = '0000000000000000';
// 取16位密钥
$key = $masterSecret;
while(strlen($key) < 16){
$key .= $masterSecret;
}
$key = substr($key, 0, 16);
// 解密
$result = openssl_decrypt(hex2bin($pn), $encryptMethod, $key, 1, $iv);
echo $result;
# pip3 install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
def decrypt(content, secret):
# 参数设置
iv = b'0' * 16
# 取16位密钥
key = secret
while len(key) < 16:
key += secret
key = key[0:16]
# 解密
cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
result = unpad(cipher.decrypt(bytes.fromhex(content)), 16)
return result.decode()
if __name__ == '__main__':
pn = '1fbf2605f954fad3ba18115000735aee' # 密文
master_secret = '126781' # 密钥
print(decrypt(pn, master_secret))
var CryptoJS = require("crypto-js");
function decrypt(content, secret){
// 参数设置
var iv = "0000000000000000";
// 取16位密钥
var key = secret;
while(key.length < 16){
key += secret;
}
key = key.substr(0, 16);
// 解密
var en = Buffer.from(content, 'hex').toString("base64");
var result = CryptoJS.AES.decrypt(en, CryptoJS.enc.Utf8.parse(key), {
iv:CryptoJS.enc.Utf8.parse(iv),
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return result.toString(CryptoJS.enc.Utf8);
}
// 密文及密钥
var pn = "1fbf2605f954fad3ba18115000735aee";
var masterSecret = "126781";
console.log(decrypt(pn, masterSecret));
如需其它语言示例,请联系我们的技术支持:文档中心右侧“技术咨询”。
以上文档对您是否有帮助?