# 简版密码服务接入方案
# 1 文档说明
# 1.1 使用对象
接入密码服务产品的第三方应用相关人员
# 1.2 版本信息
| 版本信息 | 版本信息 | 修订人 | 修订内容 |
|---|---|---|---|
| 3.3 | 2023-03-26 | SIMKEY团队 | 创建 |
# 2 术语及缩略语定义
下列术语、定义和缩略语适用于本标准
| 名词 | 解释 |
|---|---|
| API | Application Programming Interface,应用程序编程接口 |
| LTE | 3GPP Long Term Evolution,3GPP长期演进技术 |
| VPN | Virtual Private Network,虚拟专用网络 |
| OA | Office Automation,办公自动化 |
| OTA | Over The Air |
| SDK | SoftwareDevelopment Kit,软件开发工具包 |
| OMA | Open Mobile API |
| UICC | Universal Integrated Circuit Card |
| CRM | Customer Relationship Management |
- 访问控制执行器(access control enforcer)
访问控制执行器,组成安全模块访问 API 的部分软件,它从安全模块上获取访问规则,并运用这些规则来控制设备应用,对于安全模块上各种应用程序的访问。
- 终端设备(mobile device)
本规范中特指任何包含安全模块的终端设备,如移动电话。
- 开放移动设备操作系统(open mobile OS)
允许加载第三方应用程序的移动设备操作系统
- 安全模块(secure element)
可用于移动设备的智能卡芯片。例如 UICC 卡/SIM 卡、嵌入式安全模块、高 安全 SD 卡等
- 安全模块应用(applet)
一个安装并运行在安全模块里面的应用。例如一个 Java 卡应用或一个 Native 卡应用。为与设备应用区别,本文档中统一称为“Applet”。
- 终端应用(device a pplication)
一个安装并运行于移动设备上的应用程序,简称“应用”。本文中的手机终端 应用特指集成 CTPass SDK 包的手机应用程序。
- 会话(session)
设备(例如手机终端)应用和安全模块之间打开的一个连接。
- 通道(channel)
设备(例如手机终端)应用和 Applet 之间打开的一个连接。
# 3 Android Studio 工程配置
# 3.1 在项目中集成SDK
# 3.1.1 放置aar文件
将 libcissskf.aar 拷贝到工程 module 的 libs 目录下
# 3.1.2 放置so文件
将libLiteService.so文件按架构类型拷贝到工程 module 的jniLibs 目录下
# 3.1.2 添加配置
在 module 的 build.gradle 文件中添加aar和so文件配置
android分支内添加:
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
android分支外添加:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
implementation 'org.bouncycastle:bcprov-jdk15on:1.65'
implementation files('libs/libcissskf.aar')
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 3.1.3 添加依赖
在 module 的 build.gradle 中配置其他必须的依赖
implementation 'org.bouncycastle:bcprov-jdk15on:1.65'
# 3.1.4 添加外部库
Android9.0以后通过OMA访问SIM卡的库已经集成在Android系统中,为了兼容旧系统版本的手机,在 module 的 AndroidManifest.xml 配置 openmobileapi
在 application 节点里面面添加
<uses-library android:name="org.simalliance.openmobileapi" android:required="false"/>
如下图:
2
3
# 3.1.5 添加权限
在module的AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.SMARTCARD" />
<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2
3
4
5
6
7
8
9
如果是 targetSdkVersion > = 23 时, 有的权限需要动态申请
# 3.2 应用混淆
在对应module的proguard-rules.pro文件中添加混淆,如下所示
## ----------------------------------
## ########## SIMKEY SKF ##########
## ----------------------------------
-keep class com.simkey.sec.libciss.card.skf.** {*;}
-keep class com.simkey.sec.libciss.card.apdu.OMAAPDUSenderForSKF {*;}
-keep class com.simkey.sec.liteservice.** {*;}
## ----------------------------------
## ########## oma ##########
## ----------------------------------
-keep class org.simalliance.openmobileapi.** { *; }
-dontwarn org.simalliance.openmobileapi.**
2
3
4
5
6
7
8
9
10
11
保证skf的sdk不被混淆, 否则无法和 SIM 卡进行交互
# 3.3 调用SDK
# 3.3.1 在 Application 里面的初始化
1.在 onCreate 方法中添加 CISSSKFInit.init 初始化方法进行初始化, 如果不进行此步骤则无法发送指令到SIM卡 参数:
| 表头 | 表头 | 表头 | 表头 |
|---|---|---|---|
| context | Context | 上下文 | |
| scanBleNow | boolean | 单元格 | 是否立即扫描蓝牙设备, 如果使用”pcsc:Auto”来连接卡, 那么建议开启扫描. 注意: android api 23 及以上需要 app 进行动态权限申请 |
2.因简版密码服务中无连接SIM卡的接口,请使用如下方式连接:
| 参数 | 说明 | 备注 |
|---|---|---|
| "pcsc:OMA" | 仅使用 OMA 模式连接,CISSSKFInit.init初始化方法可以传入false | |
| "pcsc:Auto" | 自动模式, 优先使用 OMA, OMA 不通则扫描周围的蓝牙设备。如果扫描不到设备则连接失败。为了能够迅速的扫描到蓝牙设备,CISSSKFInit.init 初始化方法应该传入 true | |
| "pcsc:Ble:xx" | 仅蓝牙模式,需要传入蓝牙的 mac 地址,MAC 地址要大写。比如:"pcsc:Ble:00:B7:1D:0A:A5:01" CISSSKFInit.init初始化方法可以传入false |
调用如下:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
boolean scanBleNow = false;//是否进行蓝牙扫描,false表示不进行蓝牙扫描
CISSSKFInit.init(this, scanBleNow);
//初始化之后可以设置日志显示与否, 默认不显示
OMAAPDUSenderForSKF.getInstance().setLogAble(true);
//连接卡,使用OMA通道,简版密码服务未提供连接卡的方式,此处代替连接卡
OMAAPDUSenderForSKF.getInstance().connect("pcsc:OMA");
//连接卡,使用自动,CISSSKFInit参数必须为true
//OMAAPDUSenderForSKF.getInstance().connect("pcsc:Auto");
//连接卡,使用蓝牙通道,不需要再扫描,CISSSKFInit参数可以为false
//OMAAPDUSenderForSKF.getInstance().connect("pcsc:Ble:00:B7:1D:0A:A5:01");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
将继承Application的类MyApp添加到AndroidManifest.xml中,如下图所示:
# 3.3.2 密码服务的初始化
先获取密码服务实例 LiteService (附录1)
LiteService liteService = new LiteService();
进行密码服务初始化
liteService.init();//调用所有接口之前先调用
如果不进行此操作,APP会闪退
# 3.3.3 在 Android中的使用
完成上述各个步骤之后,可以对密码服务接口进行调用了, 例子如下
String appName = "xxxxxx";
int result = liteService.openApplication(appName);
2
# 3.3.5 日志
默认不打印日志, 如果需要日志的话,则添加代码:
OMAAPDUSenderForSKF.getInstance().setLogAble(true);
日志会在 logcat 打印, 且会在手机的外部存储中保存到文件
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
boolean scanBleNow = true;
CISSSKFInit.init(this, scanBleNow);
//初始化之后可以设置日志显示与否, 默认不显示
OMAAPDUSenderForSKF.getInstance().setLogAble(true);
}
}
2
3
4
5
6
7
8
9
10
11
# 附录
# 附录1
| 名称 | 说明 | 作用 |
|---|---|---|
| LiteService | 简版密码服务实例 | 用来进行接口调用 |
| LiteConst | 简版密码服务常量 | 用来提供常量参数 |
| Envelop | 封装后的数字信封 | 普通PO类 |
| KeyInfo | 非对称密钥的信息 | 普通PO类 |
| MyLong | 含有一个long型成员变量value | 用来运送输入输出的数字 |
# 附录2
常量定义:
| 常量 | 值 | 含义 |
|---|---|---|
| 用户权限 | ||
| ADMIN_TYPE | 0 | 管理员PIN类型 |
| USER_TYPE | 1 | 用户PIN类型 |
| 读写权限 | ||
| ACCESS_ANYONE | 0 | 任何人 |
| ACCESS_USER | 1 | 用户权限 |
| ACCESS_ADMIN | 2 | 管理员权限 |
| ACCESS_NEVER | 4 | 不允许 |
| 分组密码算法 | ||
| SGD_3DES | 0x00000001 | 3DES算法 |
| SGD_AES | 0x00000010 | AES算法 |
| SGD_SM1 | 0x00000100 | SM1算法 |
| SGD_SM4 | 0x00000400 | SM4算法 |
| 加解密模式 | ||
| SGD_ECB | 0x00000001 | |
| SGD_CBC | 0x00000002 | |
| 非对称密码算法标识 | ||
| SGD_RSA | 0x00010000 | RSA算法 |
| SGD_SM2 | 0x00020100 | SM2椭圆曲线密码算法 |
| 密码杂凑算法标识 | ||
| SGD_SM3 | 0x00000001 | SM3杂凑算法 |
| SGD_SHA1 | 0x00000002 | SHA_1杂凑算法 |
| SGD_SHA256 | 0x00000004 | SHA_256杂凑算法 |
| SGD_MD5 | 0x00000008 | MD5杂凑算法 |
# 附录3
错误码:
| 名称 | 值 | 含义 |
|---|---|---|
| SAR_OK | 0x00000000 | 成功 |
| SAR_FAIL | 0x0A000001 | 失败 |
| SAR_UNKNOWNER | 0x0A000002 | 异常错误 |
| SAR_NOSUPPORTYETERR | 0x0A000003 | 不支持的服务 |
| SAR_FILEERR | 0x0A000004 | 文件操作错误 |
| SAR_INVALIDHANDLEERR | 0x0A000005 | 无效的句柄 |
| SAR_INVALIDPARAMERR | 0x0A000006 | 无效的参数 |
| SAR_READFILEERR | 0x0A000007 | 读文件错误 |
| SAR_WRITEFILEERR | 0x0A000008 | 写文件错误 |
| SAR_NAMELENERR | 0x0A000009 | 名称长度错误 |
| SAR_KEYUSAGEERR | 0x0A00000A | 密钥用途错误 |
| SAR_MODULUSLENERR | 0x0A00000B | 模的长度错误 |
| SAR_NOTINITIALIZEERR | 0x0A00000C | 未初始化 |
| SAR_OBJERR | 0x0A00000D | 对象错误 |
| SAR_MEMORYERR | 0x0A00000E | 内存错误 |
| SAR_TIMEOUTERR | 0x0A00000F | 超时 |
| SAR_INDATALENERR | 0x0A000010 | 输入数据长度错误 |
| SAR_INDATAERR | 0x0A000011 | 输入数据错误 |
| SAR_GENRANDERR | 0x0A000012 | 生成随机数错误 |
| SAR_HASHOBJERR | 0x0A000013 | HASH对象错误 |
| SAR_HASHERR | 0x0A000014 | HASH运算错误 |
| SAR_GENRSAKEYERR | 0x0A000015 | 产生RSA密钥错误 |
| SAR_RSAMODULUSLENERR | 0x0A000016 | RSA密钥模长错误 |
| SAR_CSPIMPRTPUBKEYERR | 0x0A000017 | CSP服务导入公钥错误 |
| SAR_RSAENCERR | 0x0A000018 | RSA加密错误 |
| SAR_RSADECERR | 0x0A000019 | RSA解密错误 |
| SAR_HASHNOTEQUALERR | 0x0A00001A | HASH值不相等 |
| SAR_KEYNOTFOUNTERR | 0x0A00001B | 密钥未发现 |
| SAR_CERTNOTFOUNTERR | 0x0A00001C | 证书未发现 |
| SAR_NOTEXPORTERR | 0x0A00001D | 对象未导出 |
| SAR_DECRYPTPADERR | 0x0A00001E | 解密时做补丁错误 |
| SAR_MACLENERR | 0x0A00001F | MAC长度错误 |
| SAR_BUFFER_TOO_SMALL | 0x0A000020 | 缓冲区不足 |
| SAR_KEYINFOTYPRERR | 0x0A000021 | 密钥类型错误 |
| SAR_NOT_EVENTERR | 0x0A000022 | 无事件错误 |
| SAR_DEVICE_REMOVED | 0x0A000023 | 设备已移除 |
| SAR_PIN_INCORRECT | 0x0A000024 | PIN不正确 |
| SAR_PIN_LOCKED | 0x0A000025 | PIN被锁死 |
| SAR_PIN_INVALID | 0x0A000026 | PIN无效 |
| SAR_PIN_LEN_RANGE | 0x0A000027 | PIN长度错误 |
| SAR_USER_ALREADY_LOGGED_IN | 0x0A000028 | 用户已经登录 |
| SAR_USER_PIN_NOT_INITIALIZED | 0x0A000029 | 没有初始化用户口令 |
| SAR_USER_TYPE_INVALID | 0x0A00002A | PIN类型错误 |
| SAR_APPLICATION_NAME_INVALID | 0x0A00002B | 应用名称无效 |
| SAR_APPLICATION_EXISTS | 0x0A00002C | 应用已经存在 |
| SAR_USER_NOT_LOGGED_IN | 0x0A00002D | 用户没有登录 |
| SAR_APPLICATION_NOT_EXISTS | 0x0A00002E | 应用不存在 |
| SAR_FILE_ALREADY_EXIST | 0x0A00002F | 文件已经存在 |
| SAR_NO_ROOM | 0x0A000030 | 空间不足 |
| SAR_FILE_NOT_EXIST | 0x0A000031 | 文件不存在 |
| SAR_REACH_MAX_CONTAINER_COUNT | 0x0A000032 | 已达到最大可管理容器数 |