跳转至

概述#

本文档讲述深思数盾科技股份有限公司(Beijing SenseShield Technology Co.Ltd,以下简称“深思数盾”)推出的 Virbox许可体系的原理和使用方法。
深思数盾总结多年软件版权保护的经验,推出全新软件保护产品:Virbox LM。包含许可体系,许可服务,许可管理等内容。Virbox LM 采用全新许可管理理念,加强软件许可保护,主动监视、反击黑客破解。使用到的数据加密、反监听、反调试技术等方式均代表了当今最先进的技术水平。其中许可(License)又可作为 Virbox许可服务的顶级概念,所有操作均基于许可操作。

本文档详细讲述了 Virbox许可体系(Virbox License)的概念和使用方法,本文将从:许可体系、许可管理、许可使用三个方面全面讲解 Virbox LM。

术语#

在此之前,为了便于读者清晰的理解文档中描述的一些内容,在此有必要对一些名词进行说明。

精锐5硬件锁:指深思数盾推出的一款硬件加密锁。

云锁:指 Virbox LM 许可的在线使用方式。

软锁:指 Virbox LM 许可的离线使用方式。

Virbox许可体系#

软件许可(Software License)是一种数据凭证,由软件作者与用户签订,用以规定和限制软件用户使用软件(或其源代码)的权利,以及作者应尽的义务。

Virbox LM 是北京深思数盾科技股份有限公司(SenseShield)根据中国国情、总结多年用户深度定制经验、以及对市场独特理解而研发的一套软件许可管理解决方案(以下简称 “Virbox许可”),其本质是控制软件的使用权限。尤其在业内领先的【移植算法】理念保证下,解决软件无锁情况下试用、加密锁丢失甄别等棘手问题,确保软件许可安全性与使用灵活的平衡。同时针对企业内部挑战如加密开发难度高、加密方案泄露风险(加密人员离职)、私自写锁卖锁等现象,提供强有力的保护工具与安全平台。领域涉及到单机锁(本地锁)许可、网络锁许可、云许可、软许可等。

Virbox许可 包含软件的产品信息和使用限制条件,产品信息可以有产品编号、产品模块等内容,限制条件可以有限制开始时间、结束时间、使用次数、软件同时使用的并发数等条款。

使用 Virbox许可,每个开发者可以给多于40亿个不同的产品创建独立的许可。此外,每个精锐5硬件锁最多可以存储6000个产品许可,云锁、软锁许可存储产品数量无最大限制。

许可内容#

限制内容描述读取权限写入权限备注
flag许可功能标志位任意权限只能Master权限变更二进制标识,保证许可功能是否开启。使用和判断方法是按照位操作。具体含义参考下文[许可标志位解释](#license_flag)
version许可的version任意权限只能Master权限变更当前许可的版本号
LicenseID许可ID值任意权限只能Master权限变更范围从1至4294967295,0号许是生产时写入,是用于管理用途且不可删除的特殊许可。
start\_time软件最早时间任意权限只能Master变更软件不能早于这个时间,否则不可使用。支持范围:2000.1.100:00:00到2099.12.3123:59:59
end\_time软件终止时间任意权限只能Master变更软件不能晚于这个时间,否则不可使用。支持范围:2000.1.100:00:00到2099.12.3123:59:59
first\_use\_time第一次使用的时间任意权限-第一次登录许可的时间,用于实现时间跨度授权
span\_time时间跨度任意权限只能Master权限变更许可第一次使用之后的时间跨度
counter软件计次数任意权限Master签发最大次数登录递减,当为0的时候许可失效
concurrency并发数,进程、网络等节点数目任意权限只能Master变更为网络锁的并发节点数或者最大用户数,用来控制许可登录数量。
ROM只读区许可有效只能Master变更登录之后可以读取,但是不可写入。参考下文[许可用户数据区](#user_data)
RAW读写区许可有效Master权限和许可登录之后登录之后可以读写,但是写入数据长度不能超过签发许可时设定的长度
PUB公开区任意权限只能Master变更数据只读不可写,用户可见
用户执行算法开发者自定义的算法不可读取只能Master变更可以绑定一个或多个许可,只有检测授权成功之后才能执行算法,只对绑定的许可有效
module模块任意权限只能Master变更只读不可写
time\_stamp升级流水号任意权限只能Master变更许可分发的UTC时间秒
serial升级流水号任意权限只能Master变更许可分发的UTC时间一秒之内的流水号

注:Master权限是指控制锁签发

许可标志位解释

许可标志位是用来控制许可条款的是否可用的使能位。开发者实际不需要关心其具体值,只需要了解具体所代表的意义即可。

成员 意义
L1 时钟限制,终止
L1 时钟限制,起始
L1 时钟限制,跨度授权(在N天之内的授权)
L1 次数限制
L1 并发数,以系统会话并发限制
L1 并发数,以进程会话并发限制
L2 若0号许可使用,设置此项则禁用所有许可
L2 许可为账户许可(暂不可用)
L2 许可单元是否有效

许可信息的结构#

许可信息可通过API获取,其中ControlAPI可获取到许可结构,具体使用方法请参考ss_lm_control.h提供的调用接口。

许可用户数据区

许可数据区包括只读区、读写区和公开区三种。数据区大小分配是第一次创建许可时候决定的,后期可以通过远程升级扩大数据区,访问空间不能超过最高预先分配的空间,访问数据区之前要先登录到许可。

数据区对应内容及权限如下:

名称 意义 数据区大小 备注
ROM 只读区 0-65535字节 使用控制锁修改ROM区数据
RAW 读写区 0-65535字节 应用程序合法登录后可以读写数据
PUB 公开区 0-65535字节 任意时候只能读取

只读区

开发者可以用用户数据区作软件所需要的数据的存储,例如一些配置信息。只读区较读写区更为常用,原因是所存储的内容不会在未授权的情况下被任意更改。

更改只读区内容只有一种方法:用安全远程更新的方法,通过签发生成一个包含新的数据内容升级包文件,使用工具写入加密锁,完成只读区数据的更新。

读写区

读写区允许开发者把运行过程中的必要数据保存在加密锁内,下次启动的时候读取并使用。

公开区

公开区数据允许开发者只读,开发者可以在此存储软件产品信息等内容,公开区数据将在 Virbox用户工具 上公开显示。修改只能依赖远程的安全升级包。

访问数据区

API提供了整套的用户数据区操作接口。包括:
slm_user_data_getsizeslm_user_data_readslm_user_data_writeslm_pub_data_getsizeslm_pub_data_read

API接口详情,请参考 ss_lm_runtime.h

0号许可#

Virbox许可体系 中提供了0号许可和普通许可的概念,其中0号许可是指许可ID为0的许可,其他许可均为普通许可。0号许可为默认许可,加密锁生产时自带的许可,永久有效,其许可内容和普通许可完全一致,但0号许可有自身的特别之处。

0号许可为开发者提供普通许可管理的功能,通过0号许可可以控制所有其他许可,例如:通过锁定0号许可来实现对所有普通许可的锁定,一旦签发锁定所有许可,0号许可的许可标识位将置为锁定状态,这时所有的普通许可将不可使用(由于0号许可永久有效,仍然可以使用0号许可)。

0号许可软件开发者不能删除,但是可以修改其中的许可标志位和许可条款等。

许可模式#

许可模式 描述
永久许可 一次签发,永不过期。
并发许可 存储于网络服务器的加密锁中,根据设置并发类型限制若干个应用程序或若干台计算机连接并使用网络许可,每个连接都会占用一个并发数。
试用许可 用户仅能在软件商授予的有限时间内使用某些软件功能。
租赁许可 开发者指定许可过期时间。
按需许可 开发者在许可中激活特定的产品功能或模块。

许可管理#

许可管理是许可生命周期(产品创建、许可的生成、许可证的发放、许可的使用、许可证的吊销)管理和用户管理的总称。

  • 【安全】许可的算法和许可的远程升级全部在加密锁内运行,秘钥和算法不出加密锁,无法被破解。软件的关键部分,例如数据、算法等,一旦和许可进行绑定,在调用其功能和特性时,必须调用许可证书获取授权之后才能访问。如果许可过期、被删除或者被锁定,所有与之绑定的算法一起失效,黑客无法通过破解授权API的返回值来破解整个软件。
  • 【易用】软件加密与授权分离,软件开发者只需要在产品设计阶段定义好与许可绑定的模块即可,无需处理软件到期等控制逻辑,一切由加密锁进行管理,减少工作量的同时,又能保证灵活、强大的许可管理方法。
  • 【超前】许可编码的空间可充分满足开发者需求,支持多达40亿个许可ID (1--0xFFFFFFFF)。另外,云锁支持的许可数量更多,可支持软件开发者未来几十年的发展规划。
  • 【升级】许可升级客户端,免除开发者自行开发许可升级工具等。并且,所有的数据和程序均可升级,前后兼容,过渡平滑。

Virbox许可管理的理念:

  • 一次加密,多种发布
  • 许可安全:数据绑定和算法绑定与许可锁内升级模式
  • 超前管理:大于40亿个许可空间与企业内部“三权”分立
  • 高安全性:打造安全的高性能软硬件环境;算法与许可直接绑定
  • 高易用性:完整的工作流和工具链支持;商业API支持;一套接口,多类型锁使用
  • 高灵活性:加密与授权完全分离;丰富的许可支持任何分发模式;安全远程升级
  • 高扩展性:完整的底层接口平台支持二次开发

许可和应用对照关系如下图所示:

许可和应用对照关系

许可生命周期#

许可生产#

加密锁内许可出厂时候只有0号许可,后面许可证只能通过开发者通过控制锁签发远程升级包,然后通过远程升级发放软件许可证。 其中升级包种类有:创建许可、更新许可、删除许可、锁定所有许可、解除锁定许可、删除所有许可。

许可升级#

许可升级规则

以下规则仅对硬件锁许可有效,云锁和软锁许可请参考云平台相关文档

序号名词解释备注
1许可升级不可重放一个升级包不能用两次,已经升级过的升级包不能再次使用。每个升级包拥有一个签发时间戳和流水号码保证。
2多包顺序升级多个升级包必需按照顺序升级每个升级包拥有一个签发时间戳和流水号码保证,并且后面的包签发时间和流水号码是递增关系
3许可新建(非强制)只能创建锁内不存在的许可防止业务出错
4许可新建(强制)创建锁内不存在的许可,若锁内已存在许可则覆盖原有许可对更新许可的有效优化
5更新许可只能更新锁内已经存在的许可防止骗取授权
6删除许可删除锁内已经存在的许可业务严谨性
7锁定全局许可锁内该厂商所有许可将不能使用对于做“坏事”的用户一种惩罚,只有开发者解锁。
8解除全局锁定许可解除锁定全局许可的限制取消惩罚

许可吊销#

许可吊销是指在许可有效期内删除可用许可的手段,签发删除许可升级包,执行远程升级即可。

许可深度应用#

加密算法#

Virbox许可管理 提供了若干种算法,除AES算法之外,还有DES、RSA、SHA-1 HASH开发者自定义算法供开发者使用。其中AES是最常用的软件保护算法,RSA算法常用于软件的正版验证,开发者也可以通过自定义一套算法提高软件保护级别。

AES算法#

AES算法是美国NIST最新的对称算法标准,提供目前已知的最佳安全性。SS LM内部包含了AES算法的实现,开发者可以通过API接口Encrypt和Decrypt完成加密解密。

AES算法过程可逆,即对一段Message进行Encrypt之后再Decrypt,其结果与Message相同,如图:

---------   Encrypt   --------   Decrypt   ---------
|Message| ----------->|Cipher| ----------->|Message|
---------             --------             ---------

注意:Encrypt和Decrypt的计算结果与License ID有关,开发者在使用算法的时候必须先登录当前许可。换句话说,Encrypt和Decrypt是与特定的License ID绑定,对于不同的License ID,计算结果也不相同,保证不同许可加密数据的安全性。另外,深思数盾对每个开发者的加密锁都是互不相同的,所以,不同开发者的相同License ID加密得到的结果也是不一样的。

算法与LicenseID绑定的目的:

  1. 与LicenseID绑定可以实现算法有 2^32 个不同版本,从而达到更好的保护效果;
  2. 方便对软件授权。

AES算法常用于加密软件中的数据或者变量,提高软件数据的安全性。

操作步骤:

  1. 开发者可以在编码阶段使用加密接口对代码中的关键数据(全局变量、敏感配置数据、账号信息等)加密;
  2. 使用密文替换原明文记录在代码文件中的数据;
  3. 当软件运行需要使用被加密的数据时,调用解密接口解密还原后使用。

强烈建议:开发者可以利用对称算法加密用户生成的文档全部或者关键部分,比如每次打开读取和保存文件时候,由于密钥存储在安全容器(加密锁里面),黑客无法攻击密钥。最终结果是不可能存在一个盗版软件能正确打开正版软件产生的数据文档,从而保证正版软件价值。其中SLM加密是锁内直接加解密,算法和密钥都无法从外部获取。

密钥使用的是锁内隐藏密钥,密钥的值由开发者ID、盐和绑定的licenseID计算得出,没有任何机制可以导出该密钥任何副本到加密锁以外。

通常情况下,建议锁内直接加解密算法使用的是锁内隐藏密钥,锁外快速加解密使用的是开发者设置密钥,该密钥如果没有设置,则使用默认值作为密钥(该默认值为全0的直接解密结果)。

RSA算法{#RSA}#

RSA是一种非对称算法,RSA适用于以下场景:

以RSA算法的数字签名和签名验证功能,确保在任何(甚至软件在已破解)情况下都不会出现“克隆锁”——克隆锁意味着一个克隆锁能够100%被正版软件所接受。在一些国家或地区,盗版软件销售会带来暴利,盗版者确保软件能够尽可能的接近原版,或者保护“劳动成果”(破解后的软件),会使用克隆加密锁替换正版加密锁与软件一起销售。

SS LM模块内部RSA算法使用2048位,这是目前最为合理的兼顾性能和安全性的密钥长度。

SS LM模块反克隆的基本思路是软件对加密锁的合法性进行验证,可以理解是身份识别过程,其工作流程如下:

  1. 软件的Challenger向加密锁锁发起一次挑战,最简单的方式就是产生一个随机数并发送给加密锁,要求作出相应;
  2. 加密锁的Responder对收到的随机数简单处理后进行数字签名,通过保存在加密锁内部的秘密私钥Kb进行;
  3. 软件中的Verifier对加密锁作出的签名结果进行验证,通过保存在软件内部的与Kb配对的Ka进行;

RSA算法特性在公钥完全公开的条件下,密钥长度2048不能通过计算得到私钥,因此任何人都不可能制作出能够被软件接受的克隆锁。

是否在软件中执行这种反克隆策略取决于软件所面临的盗版尤其是克隆锁压力。

远程正版验证的方法与反克隆类似,唯一区别是验证加密锁合法性的软件不再是客户端软件,而是联网服务器,软件公司可以通过开发一个小型的网络服务程序来给用户提供正版验证的服务。

许可数据加密#

许可加密常用于加密用户自定义的数据和外壳解密代码执行。

密钥对于应用是隔离的,与开发者编号相关。一个厂商的指定LicenseID的密钥始终不变,不同厂商相同LicenseID的密钥不同。

密钥由加密锁内计算生成,跟厂商和许可ID和私密值有关,无法从外部获取锁内密钥,保证许可加密的安全性。

内存托管#

内存托管原理是软件利用有效的许可作为凭证,在SS安全环境下对数据加密且数据校验,托管内存数据没有明文,并且无法非法修改。黑客极难查看与篡改使用。

开发者可以将软件中的敏感数据保存到托管内存,比如帐号口令、SQL数据库的帐号与密码,涉及到操作权限的临时数据等。内存托管处理提高软件与安全环境(SS服务)之间的耦合度,有效防止黑客绕过SS安全服务调试或运行客户软件。

内存托管的好处:

  • 敏感数据内存不泄密、无法篡改。
  • 可以跨线程安全交互数据。
  • 软件、许可和SS安全服务强耦合,提高软件防破解能力。

内存托管跟用户数据区有着极为相同的功能,但是还是有所区别,内存托管储存在本地SS,用户数据区写在加密锁内的许可区域,两者区别如下:

比较项目内存托管 用户数据区
实现方式SS安全环境内存加密锁内
读写速度
储存空间0-1G0-65535字节
寿命问题没有硬件锁受限于硬件寿命
APP访问隔离共享、分离只能共享
数据失效APP退出数据失效永久保存
数据安全非授权不能读写、极难篡改非授权无法读取与篡改
数据完整可信几乎100% 通过算法保证取决于硬件

建议:

  • 临时性、大数据量、频繁读写和运行时的敏感数据保存到托管内存。
  • 下次启动时需要获取的业务运行数据结果保存到用户数据区。

许可使用#

快速使用#

Virbox Protector,是深思数盾科技股份有限公司经过多年技术深耕开发的一款高强度自动保护(加密)工具。 Virbox Protector 与 Virbox许可服务、云锁、精锐5硬件锁或软锁配套使用,集自动代码移植、混淆、外壳加密、数据加密于一身, 无需编程就能达到极高的保护强度,是业界领先的软件保护工具。

使用 Virbox Protector 可快速对您开发完成的软件进行安全保护。您的软件开发过程不需要添加任何模块或者功能,一切打包完成后,使用 Virbox Protector 对您的软件进行一次保护,保护过程中选择加密锁类型(本地锁、网络锁、云锁或者软锁,也可以是任意多种锁的组合)。之后您的软件便可以直接使用 Virbox许可体系 提供的许可保护。

具体使用方法请参考:《virboxprotector用户帮助手册》

灵活使用#

Virbox SDK提供了一套完整的许可管理和许可使用的API,将帮助您更全面的体验 Virbox许可体系 带来的便捷。开发者可通过调用API来灵活实现自己的加密方案,结合 Virbox许可 提供的许可加解密、数据区等功能,实现深度保护方案,进一步加大破解难度。

Virbox SDK主要提供以下API接口

slm_runtime#

Virbox许可 的使用接口,简称RuntimeAPI,是许可体系最为关键的接口,开发者软件通过此接口进行许可的访问,即开发者软件直接使用到的接口。

SDK中的文件体现

文件名 作用 说明
ss_lm_runtime.h RuntimeAPI头文件 每个接口函数描述
slm_runtime_api.lib RuntimeAPI的静态库 含反调试功能,开发者软件正式发布时选用
slm_runtime_api_dev.lib RuntimeAPI的开发静态库 不含反调试功能,开发者开发过程中可使用的库
slm_runtime.dll RuntimeAPI的动态库 含反调试功能,开发者软件正式发布时选用
slm_runtime_dev.dll RuntimeAPI的开发动态库 不含反调试功能,开发者开发过程中可使用的库
slm_runtime_easy.dll RuntimeAPI的动态库 简易接口,方便其他语言调用
slm_runtime_easy_dev.dll RuntimeAPI的开发动态库 同上
libruntime.lib RuntimeAPI的静态库 使用内存加载的方式,使用此静态库后软件不需要进行VMP加壳保护
libruntime_dev.lib RuntimeAPI的开发静态库 使用内存加载的方式,开发者开发过程中调试用,同上

注:
1. 开发库(带dev字样)不具有反调试功能,是方便开发者在开发过程中调试软件使用的,不可在发布时使用,否则软件不具备反调试功能,降低了黑客的破解难度
2. libruntime.lib是使用内存加载后的静态库,功能和基本的静态库功能完全一致,内存加载的方法是免去了程序调用静态库后,仍然需要使用VMP加壳的过程

下面是一段C语言调用RuntimeAPI的示例:

#include "stdio.h"
#include "ss_lm_runtime.h"

int main(int argc, char **argv)
{
    SLM_HANDLE_INDEX hslm = 0;
    BYTE original_data[TEST_ENCRYPT_DATA_SIZE ] = {"test_data1234567890"};
    BYTE encrypted_data[TEST_ENCRYPT_DATA_SIZE] = {0};
    BYTE decrypted_data[TEST_ENCRYPT_DATA_SIZE] = {0};

    SS_UINT32 sts = SS_OK;

    SS_BYTE psd[16] = { 0xDB, 0x3B, 0x83, 0x8B, 0x2E, 0x4F, 0x08, 0xF5, 0xC9, 0xEF, 0xCD, 0x1A, 0x5D, 0xD1, 0x63, 0x41 };     // 开发者API密码,每个开发者独立,必须也只能从深思开发者中心获取到。
    ST_LOGIN_PARAM login_struct = {0};
    ST_INIT_PARAM st_init_param = {0};

    //0. 全局初始化函数,调用此方法来初始化slm_runtime
    st_init_param.version = SLM_CALLBACK_VERSION02;
    st_init_param.pfn =  &(app_ss_msg_core);
    memcpy(st_init_param.password, psd, sizeof(psd));

    sts = slm_init(&(st_init_param));

    //1. slm_login 登录许可
    login_struct.license_id = 0;  //登录0号许可
    login_struct.size = sizeof(ST_LOGIN_PARAM);
    login_struct.timeout = 86400;

    sts = slm_login(login_struct,STRUCT, &(hslm),NULL);//
    if (SS_OK == sts)
    {
        printf("slm_login ok,许可登录成功!\n");
    }
    else
    {
        printf("slm_login faield error = 0x%08X, 许可登录失败:%s\n",sts, slm_error_msg(sts, 1));
        goto end;
    }
    // 2. 使用许可加密对测试数据进行加密
    printf("before encrypt: %s\n", original_data);
    sts = slm_encrypt(hslm, original_data, encrypted_data, TEST_ENCRYPT_DATA_SIZE); 
    if (SS_OK == sts)
    {
        printf("slm_encrypt ok!许可加密成功\n");
        //hex printf encrypted_data,可通过十六进制打印,查看加密后的数据是不可读的
    }
    else
    {
        printf("slm_encrypt faield error = 0x%08X, 加密失败: %s\n",sts, slm_error_msg(sts, 1));
        goto end;
    }
    // 3. 使用许可解密对加密后的数据进行解密
    sts = slm_decrypt(hslm, encrypted_data, decrypted_data, TEST_ENCRYPT_DATA_SIZE); 
    if (SS_OK == sts)
    {
        printf("slm_decrypt ok!许可解密成功\n");
        // 在此对比原始数据original_data 和解密后数据 decrypted_data是否一致
    }
    else
    {
        printf("slm_decrypt faield error = 0x%08X, 解密失败: %s\n",sts, slm_error_msg(sts, 1));
        goto end;
    }

end:
    slm_logout(hslm);
    return sts;
}

slm_control#

Virbox 许可 的管理接口,简称ControlAPI。主要提供加密锁信息的查询、许可内容和状态的查询、许可会话的查询等功能。

文件名 作用 说明
ss_lm_control.h ControlAPI头文件 每个接口函数描述
slm_control_api.lib ControlAPI的静态库 接口的实现
slm_control.dll ControlAPI的动态库 接口的实现

下面是一段C语言调用ControlAPI的示例:

// 本示例简单展示如何获取加密锁内许可信息

#include <stdio.h>
#include "json/json.h"     // 示例中采用jsoncpp解析json结构
#include "ss_error.h"
#include "ss_lm_control.h"

int main(int argc, char **argv)
{
    SS_UINT32 buf_size = 0;
    SS_UINT32 ret = 0;
    void *ipc = NULL;
    char *dev_desc = NULL;

    Json::Reader reader;
    Json::Value  root;
    Json::Value  desc;

    ret = slm_client_open(&ipc);
    if (ret != SS_OK)
    {
        return -1;
    }
    printf("slm_client_open ok\n");
    ret = slm_get_all_description(ipc, JSON, &dev_desc);
    if (ret != SS_OK)
    {
        printf("slm_get_all_description failed,errorcode=0x%08x",ret);
    }
    else
    {
        printf("slm_get_all_description ok\n");
        printf("begin prase all lock\n");
        if (!reader.parse(dev_desc, root))
        {
            printf("parse error \n");
        }
        else
        {
            printf("parse ok \n");
        }
    }
    std::string dev_type;
    std::string host_name;
    std::string ip;
    std::string sn;
    std::string devp_id;
    std::string print_str;

    int dev_num = root.size();          // 设备数量
    for (int i = 0; i < dev_num; ++i)
    {
        desc = root[i]; 
        if(desc != NULL)
        {
            char *lic_context = NULL;
            print_str = "\nbegin to read license \n";

            if (!desc["host_name"].isNull())
            {
                host_name = desc["host_name"].asString();
                print_str += "[host_name:" + host_name + "] ";
            }
            if (!desc["ip"].isNull())
            {
                ip = desc["ip"].asString();
                print_str += "[ip:" + ip + "] ";
            }
            if (!desc["type"].isNull())
            {
                dev_type = desc["type"].asString();
                print_str += "[type:" + dev_type + "] ";
            }
            if (!desc["sn"].isNull())
            {
                sn = desc["sn"].asString();
                print_str += "[sn:" + sn + "] ";
            }
            if (!desc["developer_id"].isNull())
            {
                devp_id = desc["developer_id"].asString();
                print_str += "[devp_id:" + devp_id + "] ";
            }
            print_str += "\n";
            printf(print_str.c_str());

            ret = slm_read_brief_license_context(ipc, JSON, desc.toStyledString().c_str(), &lic_context); 
            if(ret == SS_OK && lic_context != NULL)
            {
                printf(lic_context);
                printf("\n");
                slm_free(lic_context);
                lic_context = NULL;

                printf("slm_read_brief_license_context ok\n");
            }
            else
            {
                printf("slm_read_brief_license_context failed, [sn=%s] \n[errorcode=0x%08x]", sn.c_str(), ret);
            }
        }
    }

    slm_client_close(ipc);

    return 0;
}

D2CAPI#

Virbox SDK 为开发者提供了“开发者管理工具”,可帮助开发者快速的签发硬件锁许可。D2CAPI 为开发者提供了签发硬件锁许可的接口。开发者可以通过调用 D2CAPI 更加灵活的操作许可分发过程和许可条款的各种组合方式。此外,如果使用云许可可直接在云平台开发者中心中签发云许可。

D2CAPI 生成的 d2c包 是精锐5硬件锁唯一识别的许可升级格式包,d2c包 对许可内容进行了签名和加密,保证数据的完整性和安全性。另外,精锐5硬件锁自带抗重放功能,所有 d2c包 在精锐5锁内只可使用一次。

SDK中的文件体现

文件名 作用 说明
d2c.h d2cAPI头文件 每个接口函数描述
libd2c.dll d2cAPI的动态库 所有接口的实现

注:D2CAPI的使用比较复杂,具体使用案例请参考 Sample。

slm_update#

此接口主要提供了 d2c包 升级的功能,开发者可以通过 D2CAPI 制作许可 d2c包,然后可通过slm_update接口将许可升级到硬件锁中。极大的提高了写锁的灵活性。slm_update 接口的实现,在 RuntimeAPI 和 ControlAPI 中都有实现,调用时使用这两个库中的任意一个均可实现升级功能。具体使用方法请参考 Sample。