智能风控 iOS 端接入文档(C#)
隐私说明
请参照网易易盾隐私政策,请将易盾隐私政策链接放到应用“用户协议”中。
接入说明
接入“智能风控” SDK,开发者需要完成以下步骤:
1. 根据应用/游戏开发平台,将SDK拷贝到指定的工程目录,并修改项目配置;
2. 初始化SDK(初始化接口:init);
3. 根据用户登录信息调用SDK接口函数:setRoleInfo(如果非游戏应用,此接口可不调用,游戏应用必须要调用);
4. 验证SDK接入是否正确;
5. 可选择性的接入相关功能性接口;
6. 本SDK最低支持的系统:iOS 9.0;
注意:
- 全局必须要接入的接口:初始化接口;
- 游戏类型应用反外挂场景业务必须要接入的接口:设置用户信息接口
- 关键业务埋点时必须要使用的接口:同步获取凭证/异步获取凭证
- 强烈建议接入的接口:交互接口;
- 建议接入的接口:心跳接口、安全通信协议接口。
接入步骤
SDK 涉及到以下文件:
RiskPerception.unitypackage
导入SDK
(1) 打开unity工程,双击RiskPerception.unitypackage
,导入文件到您的工程
(2) 添加头文件,引入RiskPercetion.cs
using NTESHTPSec;
SDK接口调用
(1)初始化
- 头文件
using NTESHTPSec;
- 初始化接口
选择第一个或主场景(Scene),在任意脚本文件(建议选择较早加载的脚本)中调用如下代码进行初始化。
NTESRiskSecProtect.InitCallback initCallback = new NTESRiskSecProtect.InitCallback(initProductIdCallback);
NTESRiskSecProtect.init(ProductId, initCallback);
[MonoPInvokeCallback(typeof(NTESRiskSecProtect.InitCallback))]
public static void initProductIdCallback(int code, string msg, string content)
{
// code返回200说明初始化成功
...
}
ⓘ 注意
设置区域信息的接口:
setServerType
,需要在初始化接口:init
之前调用
ProductId可在易盾官网“智能风控”下的服务管理查询产品编号,或者可在群里咨询技术支持人员。产品编号示例:YD00713480122211
验证SDK接入是否正确
1、确认客户端SDK相关接口已调用
2、运行程序,确保已触发相关接口。
3、前往官网查询数据;输入角色信息进行查询。
SDK 接入调用说明
SDK 初始化接口(init)
接口用途:
用于初始化智能风控 SDK。
接入须知:
- 使用其他接口之前,必须先调用初始化接口,建议在应用/游戏启动过后第一时间调用(初始化后,并不会获取任何个人隐私相关信息);
- 该接口为 必须调用接口。
函数原型:
public static void init(string productId, InitCallback callback);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
productId | 易盾HTP分配的productId,可登录易盾后台获取 | 必填 |
callback | 初始化是否成功的回调函数 | 可选,不需要可填null |
配置信息设置:
(1) 设置服务器归属地
public static void setServerType(int serverType);
智能风控默认上报的服务器为中国大陆的服务器,若需要更改服务器归属地,可以调用该接口进行配置,支持的类型如下:
参数 | 赋值 | 说明 |
---|---|---|
serverType | 1 | 中国大陆地区,默认为该值,无须设置 |
serverType | 2 | 中国台湾地区 |
serverType | 3 | 海外地区 |
(2) 设置渠道信息
public static void setChannel(string channel)
若需要传递当前应用包体来源渠道可调用该接口(比如:App Store CN/App Store EU)。
(3) 设置额外数据
public static void setExtraData(string key, string value)
若需要客户端传递额外信息给易盾,可调用该接口,支持多次调用,但必须在 init 之前设置。
(4) 设置请求域名
public static void setHost(const char *host)
在私有化场景下,指定客户端进行数据上报等网络操作时的请求域名,如有私有化需求请联系技术支持。请注意,指定请求域名后,其他方式的网络配置将无效,如在设置请求域名后,设置服务器归属地将无法更改请求域名,并且所设置的域名服务器需要支持https协议。
示例代码:
using UnityEngine;
using System;
using System.Runtime.InteropServices;
using AOT;
using System.Text;
using NTESHTPSec;
public class Test : MonoBehaviour
{
private const string ProductId = "易盾提供的产品id";
void Start()
{
#if UNITY_IPHONE || UNITY_IOS
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
// 额外信息,反作弊接口需要,可不设置
NTESRiskSecProtect.setExtraData("GameVersion", "1.0.0");
NTESRiskSecProtect.setExtraData("AssetVersion", "1.0.0");
// 渠道
NTESRiskSecProtect.setChannel("App Store CN");
NTESRiskSecProtect.setHost("ir-sdk.netease.com");
// 服务器所在地址,1:中国大陆,2:中国台湾地区,3:其他地区
NTESRiskSecProtect.setServerType(1);
NTESRiskSecProtect.InitCallback initCallback = new NTESRiskSecProtect.InitCallback(initProductIdCallback);
NTESRiskSecProtect.init(ProductId, initCallback);
}
#endif
}
[MonoPInvokeCallback(typeof(NTESRiskSecProtect.InitCallback))]
public static void initProductIdCallback(int code, string msg, string content)
{
// code返回200说明初始化成功
...
}
}
设置角色信息接口(setRoleInfo)
接口用途:
游戏类型应用,在进行数据采集的过程中,会将角色 ID,角色名称、用户/角色账号等设置在风控 SDK 采集的数据中一同上传,用于表示角色信息,以便对有恶意、风险行为的用户/角色进行相应的处置。
接口须知:
- 须在 SDK 初始化且 用户同意隐私政策后才能调用该接口;
- 凡是涉及到用户登录、或者切换角色的地方,均需要调用该接口设置或者更新用户/玩家信息;
函数原型:
public static void setRoleInfo(string businessId, string roleId, string roleName, string roleAccount, string roleServer, int serverid, string gameJson);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
businessId | 当前业务 ID | 必填 |
roleId | 用户/玩家的角色 ID非游戏类型应用,roleId 可以与 roleAccount 相同 | 必填 |
roleName | 用户/玩家的角色名称;非游戏类型应用,roleName 可以是当前用户昵称相同 | 可选,不需要可填null |
roleAccount | 用户/玩家的账号;如业务方同时接入易盾反垃圾,则此账号需要与反垃圾接入中的account一致 | 可选,不需要可填null |
roleServer | 用户/玩家的角色的服务器名称 | 可选,不需要可填null |
serverId | 用户/玩家的角色所属服务器的 ID | 可选,不需要可填null |
gameJson | 游戏类型应用需要上传的信息,对应一个 json 字符串 | 可选,不需要可填null |
gameJson 字段说明:
key 名称 | key 类型 | key 值 | 必要性 | 说明 |
---|---|---|---|---|
游戏版本号 | String | GameVersion | 可选,不需要可填null | 游戏版本号 |
资源文件版本 | String | AssetVersion | 可选,不需要可填null | 游戏类型应用的资源文件版本号 |
示例代码:
NTESRiskSecProtect.setRoleInfo("易盾提供的业务id", "123456", "易小盾","yd@163.com", "游戏测试服", 123, "");
登出接口(logOut)
接口用途:
为了更好的统计该用户/玩家角色在本次登录后的行为,精准标识和打击有恶意行为的用户/玩家。
接入须知:
- 须在 SDK 初始化接口被调用后方可调用,在用户/玩家退出当前角色(包括切换角色)或者退出游戏时调用接口。
- 此接口主要用于判断用户/玩家本次生命周期,不强制要求接入。
函数原型:
public static void logOut();
示例代码:
NTESRiskSecProtect.logOut();
同步获取凭证(getToken)
接口用途:
用于关键业务节点风险防控场景中,比如注册、登录、领券、抽卡、兑换、点赞、评论等业务场景。业务方可通过此接口,获取检测唯一凭证 token。业务服务端通过此凭证实时获取当前用户/玩家风险检测结果,并根据结果进行处置。
接口适用场景为:
1、游戏类应用,当 SDK 数据上报接口被屏蔽导致数据上报失败时,通过 getToken 接口获取 SDK 采集信息,并由客户服务端传递给易盾服务器;
2、全类型应用,在关键业务节点主动调用检测时,通过 getToken 接口获取检测凭证,由客户服务端通过 token 凭证从易盾服务器查询检测结果。
接入须知:
函数原型:
public static AntiCheatResult getToken(int timeout, string businessId);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
timeout | 函数超时时间 | 必填,单位毫秒,[100,1000],此区间外的默认为3000 |
businessId | 业务 ID | 必填,由易盾后台分配,并在官网“服务管理”中查询 |
返回值:
AntiCheatResult类说明:
public class AntiCheatResult
{
public int code;
public string codeStr;
public string token;
public string businessId;
}
AntiCheatResult变量说明:
变量 | 说明 |
---|---|
code | 结果码,不同结果码含义如下: 201:SDK未初始化; 203:businessId不合法; 204:其他情况 |
codeStr | 结果码对应的字符说明: 201:error not init; 203:businessId invalid; 204:get token error |
token | 当 code 为200时,返回正常token。当网络状态不佳或者超时时,会返回离线 token |
businessId | 用于透传上报给反垃圾系统,实现数据互通,提升检测效果(如未接入反垃圾系统,可以不用处理此参数) |
示例代码:
AntiCheatResult result = NTESRiskSecProtect.getToken(3000, LoginBusinessID);
Debug.Log("token code:" + result.code);
Debug.Log("token:" + result.token);
异步获取凭证(getTokenAsync)
接口用途:
同 同步获取凭证。
接入须知:
函数原型:
public static void getTokenAsync(int timeout, String businessId, getTokenAysncBlock callback);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
businessId | 业务 ID | 必填,由易盾后台分配,并在官网“服务管理”中查询 |
timeout | 函数超时时间 | 必填,单位毫秒,[1000,10000],此区间外的默认为3000 |
callback | token 的回调 | 必填,用来接收 token |
AntiCheatResult变量说明:
变量 | 说明 |
---|---|
code | 结果码,不同结果码含义如下: 201:SDK未初始化; 203:businessId不合法; 204:其他情况 |
codeStr | 结果码对应的字符说明: 201:error not init; 203:businessId invalid; 204:get token error |
token | 当 code 为200时,返回正常token。当网络状态不佳或者超时时,会返回离线 token |
businessId | 用于透传上报给反垃圾系统,实现数据互通,提升检测效果(如未接入反垃圾系统,可以不用处理此参数) |
示例代码:
[MonoPInvokeCallback(typeof(NTESRiskSecProtect.getTokenAysncBlock))]
public static void getTokenAction1(AntiCheatResult result)
{
Debug.Log("token:" + result.code + "codeStr:" + result.codeStr + "token数据:" + result.token + "businessID:" + result.businessId);
}
NTESRiskSecProtect.getTokenAysncBlock render = new NTESRiskSecProtect.getTokenAysncBlock(getTokenAction1);
NTESRiskSecProtect.getTokenAsync(3000, "易盾提供的业务id", render);
交互接口(ioctl)
接口用途:
用于在客户端查询 SDK 采集的基础数据、设置需要传递给 SDK 数据(比如初始化配置内容、check 结果信息等)、及其他可能的定制功能服务。
接入须知:
接口调用前置条件是:调用了登录接口,并且设置了roleId等信息。
函数原型:
public static string ioctl(RequestCmdID request, string data);
参数说明:
参数 | 说明 | 必要性 |
---|---|---|
request | 对应向风控系统请求的命令 | 必填 |
data | 设置信息的附加数据 | 可选,不需要可填null |
request值说明:
public enum RequestCmdID
{
// 签名信息
Cmd_GetSignInfo = 0,
// 越狱状态
Cmd_IsRootDevice = 2,
// SDK版本
Cmd_GetHTPVersion = 7,
// 初始化配置内容,防止初始化失败情况下,客户可以通过服务端请求初始化配置并传递给SDK
Cmd_SetConfigData = 16,
// 客户服务端将check结果传递给SDK,便于执行后续动作
Cmd_SetResponseData = 17,
// 32位deviceID
Cmd_GetYiDunCode = 99,
// 64位deviceID
Cmd_GetYiDunID = 100,
};
返回值:
错误的情况下,返回:unsupported request(不支持的命令);正确的情况下,返回对应命令的结果。
注意:该接口的返回值类型均为String,对返回值做判断的时候需要注意该值的类型。
不同命令设置方法:
(1) 签名信息
向风控 SDK 查询应用的签名信息。
示例代码:
string signInfo = NTESRiskSecProtect.ioctl(RequestCmdID.Cmd_GetSignInfo, "");
返回值: 返回当前应用的签名信息,便于区分是盗版应用还是正版应用;
(2) 越狱状态
向风控 SDK 查询设备是否越狱。
示例代码:
string jailbreakStatus = NTESRiskSecProtect.ioctl(RequestCmdID.Cmd_GetSignInfo, "");
返回值: 当前设备是否越狱信息。若为越狱设备,返回值为:1;若不是越狱设备,返回值为:0。
(3) 风控 SDK 版本号信息
向风控 SDK 查询当前风控 SDK 版本号,便于掌握每个玩家当前使用的游戏的风控 SDK 版本。
示例代码:
string htpSDKVersion = NTESRiskSecProtect.ioctl(RequestCmdID.Cmd_GetHTPVersion, "");
返回值: 风控 SDK 版本号一定不为空,返回值示例:“2.0.1”。
(4) 设置配置信息
向风控 SDK 配置传递从易盾服务器获取到的产品的配置信息(主要适用于风控 SDK 因被黑灰产屏蔽或其他原因导致无法正常获取配置信息的情况)。
示例代码:
NTESRiskSecProtect.InitCallback initCallback = new NTESRiskSecProtect.InitCallback(initProductIdCallback);
NTESRiskSecProtect.init(ProductId, initCallback);
[MonoPInvokeCallback(typeof(NTESRiskSecProtect.InitCallback))]
public static void initProductIdCallback(int code, string msg, string content)
{
// code返回200说明初始化成功
if (code != 200) {
// 从易盾服务器获取到的产品的配置信息
...
string configData = "配置信息";
string ret = NTESRiskSecProtect.ioctl(RequestCmdID.Cmd_SetConfigData, configData);
}
}
返回值: 返回值为字符串格式:
返回值 | 说明 |
---|---|
0或者-1 | 输入数据格式有误 |
1 | 解析成功 |
(5) 设置响应信息
向风控 SDK 配置传递从易盾服务端获取到的命中及响应结果信息,以便 SDK 执行相关处置动作(主要适用于风控 SDK 因被黑灰产屏蔽或其他原因导致无法正常获取响应结果的情况)。
示例代码:
string sdkRespData = "从易盾服务端获取到的命中及响应结果信息";
string ret = NTESRiskSecProtect.ioctl(RequestCmdID.Cmd_SetResponseData, sdkRespData);
返回值: 返回值为字符串格式:
返回值 | 说明 |
---|---|
0或者-1 | 输入数据格式有误 |
1 | 解析成功 |
心跳接口(registInfoReceiver)
接口用途:
为保障风控 SDK 服务的安全运行,防止易盾风控服务被中止或者被剥离,定时向应用/游戏方客户端反馈风控 SDK 的心跳信息,告知应用/游戏方当前风控 SDK 运行状态,既方便应用/游戏方实时掌握风控服务运行状态,也能保证易盾风控服务正常运行。
同时心跳接口也可以主动实时返回风控数据(有别于交互接口),如需要详细说明文档,请联系易盾获取。
接口须知:
- 须在 SDK 初始化且用户同意隐私政策后才能调用该接口;
- 心跳系统在非主线程中运行,如需进行UI操作请切回到主线程中。
函数原型:
public static void registInfoReceiver(InfoReceiver receiver);
参数说明:
参数 | 类型 | 说明 |
---|---|---|
receiver | InfoReceiver | 回调函数,接收心跳信息; |
InfoReceiver 接口定义:
public delegate void InfoReceiver(int type, string info);
InfoReveiver 接口中,InfoReceiver 方法参数说明:
参数 | 类型 | 说明 |
---|---|---|
type | int | 接收数据的类型 |
Info | String | 接收的具体数据内容 |
示例代码:
NTESRiskSecProtect.InfoReceiver receiver = new NTESRiskSecProtect.InfoReceiver(infoReceiver);
NTESRiskSecProtect.registInfoReceiver(receiver);
[MonoPInvokeCallback(typeof(NTESRiskSecProtect.InfoReceiver))]
public static void infoReceiver(int type, string info)
{
if (type == NTESHeartBeat.INFO_TYPE_HEARTBEAT)
{
//(获取到info进行相关操作)
}
if (type == NTESHeartBeat.INFO_TYPE_ENC_HEARTBEAT)
{
//(获取到的info,为加密状态,需发往服务端进行解密)
}
}
解密后参数说明
- 建议获取加密后的心跳数据,然后发往客户服务端进行解析。
- 心跳接口是每隔 10s 会返回一次数据(“Info”),返回的数据为一个字符串,“Info” 包含三种信息,分别是:序列号、时间戳、网络状态,使用 “key:value” 格式并用 “||” 符号分割。信息含义如下所示:
名称 | 标识 | 说明 | 异常情况 | 是否必有 |
---|---|---|---|---|
序列号 | seq | 从初始值 “1” 开始递增 | 序列号不存在,或者乱序 | 是 |
时间戳 | t | 当前时间戳,以秒为单位 | 时间戳非当前时间 | 是 |
网络标识 | net | 数据发送是否成功( 1 为成功,0 为失败) | 网络异常,数据发送失败,则网络标识为:0 | 是 |
心跳的返回值示例:
- 易盾风控服务网络通信正常时:
seq:1||t:1589781840||net:1
- 易盾风控服务网络通信异常时:
seq:1||t:1589781840||net:0
处理建议:
- seq、t和net是否出现,该三个标识为心跳系统一定会返回的值,若无,说明反外挂异常;
- seq的值是否符合"从1开始依次递增"的规则,若不符合,说明返回值被篡改;
- net为0是否长期出现,若5分钟内net的取值都为0,说明网络异常;
- 若出现反外挂异常或网络异常,请结合游戏业务数据综合判断并自行处理。
数据校验接口(getDataSign)
接口用途:
应用/游戏协议如被破解,若为单机游戏类型应用,可直接影响到存档文件的安全性;若为帧同步游戏类型应用,可通过破解协议修改战斗数据;若为其他游戏类型应用,可被做成脱机协议,用于攻击或制作脱机外挂;若为非游戏类型应用,则可伪造业务数据欺骗客户端应用。为了保障应用/游戏协议安全,易盾风控服务提供 “数据校验” 方案,采用自研通讯协议校验算法。
接口须知:
- 客户端接入数据校验接口后,客户服务端需要对对应的数据进行校验,数据校验相关说明文档请联系易盾获取;
- 对于与服务端有通信的应用/游戏,强烈建议 使用该接口进行数据校验。
函数原型:
public static string getDataSign(string inputData);
参数说明:
参数名 | 类型 | 说明 |
---|---|---|
data | string | 需要签名的数据 |
返回值:
返回的数据即为校验结果,开发者需要将原始数据与校验结果发送到应用/游戏服务端,由应用/游戏服务端校验。
示例代码:
string signData = NTESRiskSecProtect.getDataSign("签名的数据");
服务端数据签名计算代码
服务端代码:
function getDataSign($data,$appkey)
{
}
校验函数使用示例:
$inputdata = "sfsfsfdsfsdfssdssdsdf";
$appkey = 客户的appid;
$sign = getDataSign($inputdata,$appkey);
这里计算生成的$sign 应该跟客户端返回的 sign 值一致
安全通信协议接口
接口用途:
该接口用于对通信数据进行白盒加密和白盒 HMAC 签名(相当于 数据校验接口 的升级版本),加密和签名的密钥均会被隐藏,攻击者无法获取,从而保障应用/游戏的通信安全。
最新版本接口(V2.1)更新内容如下:
- 自定义二进制格式,增大分析难度;
- 多重加密,防明文传输;
- 数据将进行校验,防止篡改;
- 支持多算法,一旦加密算法被破解,可及时更新为另一种算法;
- 一次一密,每次加密的密钥都不相同;
- 自定义安全随机数发生器,防止系统随机数接口被篡改,始终生成一样的密钥;
- 防重放攻击;
- 防模拟执行(脱离Android/iOS环境运行)。
接口须知:
- 1、白盒加密每个客户端都有单独的白盒查找表在
RiskPerceptionBundle.bundle
文件(需要找运营获取),需要将文件加入工程中和sdk同一目录下。 - 2、如需使用该接口,请联系易盾获取详细说明文档。
(1)加密数据到服务端(返回字符串)
函数原型
public static int safeCommToServer(int alg, string inputData, int dataSize, ref IntPtr outData, ref int outLen);
参数说明
参数 | 类型 | 说明 |
---|---|---|
alg | int | 加密算法 |
inputData | string | 需要加密的原文 |
dataSize | int | 传入加密数据的长度 |
outData | IntPtr | 加密结果,当返回值为 0 时,接口内部会为out申请空间,当out不再使用时,需手动释放内存 |
outLen | int | 加密结果大小 |
返回值
参数 | 类型 | 说明 |
---|---|---|
int | 当 ret == 0 时,才表示加密成功,这时可以取out的值作为加密结果;接口内部会为out申请空间,当out不再使用时,需手动释放内存 如果 ret 为其他值,需要根据具体的错误码做相应的处理; |
当 ret == 0 时,返回的数据即为加密和签名结果,开发者需要将此数据与校验结果发送到游戏服务端,由游戏服务端解密和校验,当 ret != 0 时,加密失败返回空字符串""
示例代码:
string v2Str = "this is client data";
string result = null;
IntPtr ptr = IntPtr.Zero;
int outLen = 0;
int ret = NTESRiskSecProtect.safeCommToServer(0, v2Str, v2Str.Length, ref ptr, ref outLen);
if (ret == 0)
{
byte[] cc = new byte[outLen];
Marshal.Copy(ptr, cc, 0, outLen);
result = Encoding.ASCII.GetString(cc);
// 释放 ptr
NTESRiskSecProtect.safeFree(ref ptr);
}
(2)加密数据到服务端(返回二进制)
函数原型
public static int safeCommToServerByte(int alg, string inputData, int dataSize, ref IntPtr outData, ref int outLen);
参数说明
参数 | 类型 | 说明 |
---|---|---|
alg | int | 加密算法 |
inputData | string | 需要加密的原文 |
dataSize | int | 传入加密数据的长度 |
outData | IntPtr | 加密结果,当返回值为 0 时,接口内部会为out申请空间,当out不再使用时,需手动释放内存 |
outLen | int | 加密结果大小 |
返回值
参数 | 类型 | 说明 |
---|---|---|
int | 当 ret == 0 时,才表示加密成功,这时可以取out的值作为加密结果;接口内部会为out申请空间,当out不再使用时,需手动释放内存 如果 ret 为其他值,需要根据具体的错误码做相应的处理; |
当 ret == 0 时,返回的数据即为加密和签名结果,开发者需要将此数据与校验结果发送到游戏服务端,由游戏服务端解密和校验,当 ret != 0 时,加密失败返回空字符串""
示例代码:
string v2Str = "this is client data";
string result = null;
IntPtr ptr = IntPtr.Zero;
int outLen = 0;
int ret = NTESRiskSecProtect.safeCommToServerByte(0, v2Str, v2Str.Length, ref ptr, ref outLen);
if (ret == 0)
{
byte[] cc = new byte[outLen];
Marshal.Copy(ptr, cc, 0, outLen);
result = Encoding.ASCII.GetString(cc);
// 释放 ptr
NTESRiskSecProtect.safeFree(ref ptr);
}
(3)解密服务端的数据(密文字符串)
函数原型
public static int safeCommFromServer(int alg, int timeout, string inputData, int dataSize, ref IntPtr outData, ref int outLen);
参数说明:
参数 | 类型 | 说明 |
---|---|---|
alg | int | 加密算法 如果 alg 不等于 0x0,则使用 alg 来进行解密,即指定算法解密,否则使用密文里的算法进行解密 |
timeout | int | 超时时间,单位为秒 如果 timeout不为0,则超过timeout的密文会返回nil |
inputData | string | 加密密文的字符串形式,由服务端返回 |
dataSize | int | 传入解密数据的长度 |
outData | IntPtr | 解密结果,当返回值为 0 时,接口内部会为out申请空间,当out不再使用时,需手动释放内存 |
outLen | int | 解密结果大小 |
返回值:
参数 | 类型 | 说明 |
---|---|---|
int | 当 ret == 0 时,才表示加密成功,这时可以取out的值作为解密结果;接口内部会为out申请空间,当out不再使用时,需手动释放内存 如果 ret 为其他值,需要根据具体的错误码做相应的处理; |
示例代码:
string v2DecodeStr = "加密密文,由服务端返回";
string decResult = null;
IntPtr outPtr = IntPtr.Zero;
int decOutLen = 0;
int ret1 = NTESRiskSecProtect.safeCommFromServer(0, 0, v2DecodeStr, v2DecodeStr.Length, ref outPtr, ref decOutLen);
if (ret1 == 0)
{
byte[] cc = new byte[decOutLen];
Marshal.Copy(outPtr, cc, 0, decOutLen);
decResult = Encoding.ASCII.GetString(cc);
// 释放 ptr
NTESRiskSecProtect.safeFree(ref outPtr);
}
(4)解密服务端的数据(密文二进制)
函数原型
public static int safeCommFromServer(int alg, int timeout, byte[] inputDataByte, int dataSize, ref IntPtr outData, ref int outLen);
参数说明:
参数 | 类型 | 说明 |
---|---|---|
alg | int | 加密算法 如果 alg 不等于 0x0,则使用 alg 来进行解密,即指定算法解密,否则使用密文里的算法进行解密 |
timeout | int | 超时时间,单位为秒 如果 timeout不为0,则超过timeout的密文会返回nil |
inputDataByte | byte[] | 加密密文的二进制形式,由服务端返回 |
dataSize | int | 传入解密数据的长度 |
outData | IntPtr | 解密结果,当返回值为 0 时,接口内部会为out申请空间,当out不再使用时,需手动释放内存 |
outLen | int | 解密结果大小 |
返回值:
参数 | 类型 | 说明 |
---|---|---|
int | 当 ret == 0 时,才表示加密成功,这时可以取out的值作为解密结果;接口内部会为out申请空间,当out不再使用时,需手动释放内存 如果 ret 为其他值,需要根据具体的错误码做相应的处理; |
示例代码:
string v2DecodeStr = "加密密文,由服务端返回";
byte[] v2DecodeByte = Encoding.UTF8.GetBytes(v2DecodeStr);
string decResult = null;
IntPtr outPtr = IntPtr.Zero;
int decOutLen = 0;
int ret1 = NTESRiskSecProtect.safeCommFromServer(0, 0, v2DecodeByte, v2DecodeByte.Length, ref outPtr, ref decOutLen);
if (ret1 == 0)
{
byte[] cc = new byte[decOutLen];
Marshal.Copy(outPtr, cc, 0, decOutLen);
decResult = Encoding.ASCII.GetString(cc);
// 释放 ptr
NTESRiskSecProtect.safeFree(ref outPtr);
}