提交 f004ccf9 编写于 作者: D duangavin123

update 导入OpenHarmony工程

Signed-off-by: Nduangavin123 <duanxichao@huawei.com>
上级 75e24d57
# IPC通信鉴权开发指导<a name="ZH-CN_TOPIC_0000001058671861"></a>
- [场景介绍](#section18502174174019)
- [接口说明](#section1633115419401)
- [开发步骤](#section022611498210)
- [常见问题](#section15729104510271)
## 场景介绍<a name="section18502174174019"></a>
系统服务通过IPC跨进程方式开放的接口,需要对接口调用者进行鉴权操作。在Samgr中注册的系统服务,可以通过进程间通信的方式暴露接口给其他进程访问,同时需要配置相应的访问策略,当其他进程访问这些接口时,将会触发IPC通信鉴权机制校验访问进程是否拥有权限访问该接口,若无权限,则访问会被拒绝。
当开发一个系统服务时,如果需要对外开放某些接口,开发者可以通过IPC通信鉴权组件配置这些接口的访问策略。当其他服务通过IPC方式访问这些接口时,会触发Samgr服务调用IPC通信鉴权组件的接口检查调用者服务是否有权限调用该接口。
## 接口说明<a name="section1633115419401"></a>
IPC通信鉴权提供的API,仅供Samgr调用,开发者在开发服务时需要配置对应的访问策略,Samgr会调用如下接口获取和检查调用者是否具有正确的访问权限,提供的API列表如下。
**表 1** IPC通信鉴权API接口功能介绍
<a name="table10494122145517"></a>
<table><thead align="left"><tr id="row1494152195511"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p14941221135515"><a name="p14941221135515"></a><a name="p14941221135515"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p8494172116555"><a name="p8494172116555"></a><a name="p8494172116555"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1849482118555"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1414381815720"><a name="p1414381815720"></a><a name="p1414381815720"></a>int GetCommunicationStrategy(RegParams params, PolicyTrans **policies, unsigned int *policyNum)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p749582195510"><a name="p749582195510"></a><a name="p749582195510"></a>服务注册过程中查询调用接口对应的访问策略,仅供Samgr调用</p>
</td>
</tr>
<tr id="row8495521115517"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p966319247576"><a name="p966319247576"></a><a name="p966319247576"></a>int IsCommunicationAllowed(AuthParams params)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p134951921115511"><a name="p134951921115511"></a><a name="p134951921115511"></a>检查访问主体进程是否有权限调用受访客体进程的接口,仅供Samgr调用</p>
</td>
</tr>
</tbody>
</table>
## 开发步骤<a name="section022611498210"></a>
本部分以BMS服务通过IPC通信方式对外开放接口为例,讲解如何通过IPC通信鉴权组件配置对应接口的访问策略。这里BMS在Samgr中注册的service为bundlems,为开放的接口注册的Feature为BmsFeature。
1. OpenHarmony侧在源码路径下的头文件base/security/permission/services/permission\_lite/ipc\_auth/include/policy\_preset.h中配置相应的访问策略,产品侧独有的在vendor/hisilicon/产品名称/hals/security/permission\_lite/ipc\_auth/include/policy\_preset\_product.h中配置相应的访问策略,配置策略后将头文件中的宏POLICY\_PRODUCT 配置为1;访问策略主要有三种类型:
(1)type为RANGE类型:允许某个特定范围UID的进程访问,需要指定uidMin和uidMax;
(2)type为FIXED类型:允许指定的几个UID的进程访问,需要指定fixedUid,最多配置8个;
(3)type为BUNDLENAME类型:只允许特定的应用访问,需要指定bundleName(包名);
```
FeaturePolicy bmsFeature[] = {
{
"BmsFeature",
{
{
.type=FIXED, // 允许指定UID的进程访问的方式
.fixedUid={2, 3, 8}
},
{
.type=RANGE, // 允许特定范围内的UID的进程访问的方式
.uidMin=100,
.uidMax=__INT_MAX__,
},
}
},
{
"BmsInnerFeature",
{
{
.type=FIXED, // 允许指定UID的进程访问的方式
.fixedUid={2, 3, 8}
},
{
.type=RANGE,
.uidMin=100,
.uidMax=999,
},
}
},
};
```
2. 将步骤1中定义的Feature的策略加配到全局策略中,需要配置feature数量;
```
static PolicySetting g_presetPolicies[] = {
{"permissionms", pmsFeature, 1},
{"abilityms", amsFeature, 2},
{"bundlems", bmsFeature, 2}, // 步骤1定义的BMS的feature,数量为2
{"dtbschedsrv", dmsFeature, 1},
{"samgr", samgrFeature, 1},
{"appspawn", appspawnFeature, 1},
{"WMS", wmsFeature, 1},
{"bundle_daemon", bdsFeature, 1},
};
```
3. 将步骤1中定义的BmsFeature注册到Samgr;
```
const char BMS_SERVICE[] = "bundlems";
const char BMS_FEATURE[] = "BmsFeature";
static void Init()
{
SamgrLite *sm = SAMGR_GetInstance();
if (sm == nullptr) {
return;
}
// 注册服务到Samgr
sm->RegisterFeature(BMS_SERVICE, reinterpret_cast<Feature *>(BundleMsFeature::GetInstance()));
sm->RegisterFeatureApi(BMS_SERVICE, BMS_FEATURE,
GetBmsFeatureApi(reinterpret_cast<Feature *>(BundleMsFeature::GetInstance())));
HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS feature start success");
}
APP_FEATURE_INIT(Init);
```
完成以上开发步骤后,开发者在Samgr注册服务时,Samgr会调用IPC通信鉴权组件的GetCommunicationStrategy接口获取服务的访问策略;当其他服务或应用通过IPC方式访问这些服务时,Samgr会调用IPC通信鉴权组件的IsCommunicationAllowed接口检查调用者服务的权限,如果满足访问策略,则可以访问开发者接口,否则拒绝访问。
## 常见问题<a name="section15729104510271"></a>
- 开发新服务后,在Samgr注册失败问题
**现象描述**
开发完新服务后,在启动时出现服务在Samgr注册失败问题。
**可能原因**
服务注册过程中,Samgr需要从IPC通信鉴权模块获取该服务的访问策略,但是未在该模块配置该服务的UID。
**解决办法**
在base/security/permission/services/permission\_lite/ipc\_auth/src/ipc\_auth\_impl.c中配置有效的服务的UID。
# 概述<a name="ZH-CN_TOPIC_0000001058831526"></a>
- [基本概念](#section175012297491)
- [约束与限制](#section2029921310472)
OpenHarmony安全子系统目前提供给开发者的安全能力主要包含应用可信、权限管理、设备可信。涉及以下几个模块:
- 应用验签
为了确保应用内容的完整性,系统通过应用签名和Profile对应用的来源进行管控,同时对于调试应用,还可通过验签接口验证应用和设备的UDID是否匹配,确保应用安装在了正确的设备上。
- 应用权限管理
应用权限是管理应用访问系统资源和使用系统能力的一种通用方式,应用在开发阶段需要在profile.json中指明此应用在运行过程中可能会调用哪些权限,其中静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示涉及到敏感信息,所以需要用户进行动态授权。
- 可信设备群组管理
提供基于群组概念的同华为账号群组、点对点群组(如二维码、碰一碰等)的设备安全可信关系的创建和查询,分布式应用可基于该能力进行设备间的可信认证,然后向分布式软总线请求设备间安全会话。
## 基本概念<a name="section175012297491"></a>
在进行依赖验签组件的应用开发前,开发者应了解以下基本概念:
- Samgr
Samgr\(System Ability Manager\)系统能力管理,在OpenHarmony上作为一个管理系统能力的模块,详见系统服务框架子系统。
- BMS
BMS\(Bundle Manager Service\)包管理管理,在OpenHarmony上主要负责应用的安装、卸载和数据管理。
- 授权文件
本文中的授权文件,指HarmonyAppProvision,简称profile。HarmonyAppProvision采用json文件格式进行描述。
- 调试应用
指开发者从应用市场申请调试证书与调试授权文件,并以此签名的hap包。
- 发布应用
指开发者从应用市场申请发布证书与发布授权文件,以此签名的hap包,上传至应用市场,并由应用市场正式发布的hap包。
- OpenHarmony签名应用
OpenHarmony开源了一个根CA的证书和密钥,以此根CA签发的签名证书和授权文件签名的应用。
## 约束与限制<a name="section2029921310472"></a>
- 仅支持以下三类应用的验签:应用市场调试应用、应用市场发布应用、OpenHarmony签名应用。
- 若对应用市场调试应用验签,则本机UDID需要在授权文件授权调试的UDID列表中。
# 应用权限管理开发指导<a name="ZH-CN_TOPIC_0000001058864249"></a>
- [运作机制](#section193961322175011)
- [场景介绍](#section18502174174019)
- [接口说明](#section1633115419401)
- [开发步骤](#section022611498210)
## 运作机制<a name="section193961322175011"></a>
由于OpenHarmony允许安装三方应用,所以需要对三方应用的敏感权限调用进行管控,具体实现是应用在开发阶段就需要在profile.json中指明此应用在运行过程中可能会调用哪些敏感权限,这些权限包括静态权限和动态权限,静态权限表示只需要在安装阶段注册就可以,而动态权限一般表示获取用户的敏感信息,所以需要在运行时让用户确认才可以调用,授权方式包括系统设置应用手动授权等。除了运行时对应用调用敏感权限进行管控外,还需要利用应用签名管控手段确保应用安装包已经被设备厂商进行了确认。
**表 1** OpenHarmony权限列表
<a name="table058213105512"></a>
<table><thead align="left"><tr id="row4583510656"><th class="cellrowborder" valign="top" width="33.333333333333336%" id="mcps1.2.4.1.1"><p id="p75834101518"><a name="p75834101518"></a><a name="p75834101518"></a><span id="text1659749759"><a name="text1659749759"></a><a name="text1659749759"></a>OpenHarmony</span>权限</p>
</th>
<th class="cellrowborder" valign="top" width="25.83258325832583%" id="mcps1.2.4.1.2"><p id="p1458351016516"><a name="p1458351016516"></a><a name="p1458351016516"></a>授权方式</p>
</th>
<th class="cellrowborder" valign="top" width="40.83408340834084%" id="mcps1.2.4.1.3"><p id="p105838101254"><a name="p105838101254"></a><a name="p105838101254"></a>权限说明</p>
</th>
</tr>
</thead>
<tbody><tr id="row45831101153"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p155831510951"><a name="p155831510951"></a><a name="p155831510951"></a>ohos.permission.LISTEN_BUNDLE_CHANGE</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p158301014512"><a name="p158301014512"></a><a name="p158301014512"></a>system_grant(静态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p155835101512"><a name="p155835101512"></a><a name="p155835101512"></a>允许该应用获取应用变化消息。</p>
</td>
</tr>
<tr id="row958316106513"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p1258313104515"><a name="p1258313104515"></a><a name="p1258313104515"></a>ohos.permission.GET_BUNDLE_INFO</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p16583161014519"><a name="p16583161014519"></a><a name="p16583161014519"></a>system_grant(静态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p11583910850"><a name="p11583910850"></a><a name="p11583910850"></a>允许该应用获取应用信息。</p>
</td>
</tr>
<tr id="row458351013520"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p11583310757"><a name="p11583310757"></a><a name="p11583310757"></a>ohos.permission.INSTALL_BUNDLE</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p95834109511"><a name="p95834109511"></a><a name="p95834109511"></a>system_grant(静态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p858319108518"><a name="p858319108518"></a><a name="p858319108518"></a>允许该应用安装应用。</p>
</td>
</tr>
<tr id="row139426341265"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p169421434164"><a name="p169421434164"></a><a name="p169421434164"></a>ohos.permission.CAMERA</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p1594212341164"><a name="p1594212341164"></a><a name="p1594212341164"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p1942334361"><a name="p1942334361"></a><a name="p1942334361"></a>此应用可随时使用相机拍摄照片和录制视频。</p>
</td>
</tr>
<tr id="row114648235612"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p746502318619"><a name="p746502318619"></a><a name="p746502318619"></a>ohos.permission.MODIFY_AUDIO_SETTINGS</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p6466223362"><a name="p6466223362"></a><a name="p6466223362"></a>system_grant(静态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p8466323567"><a name="p8466323567"></a><a name="p8466323567"></a>允许该应用修改全局音频设置,例如音量和用于输出的扬声器。</p>
</td>
</tr>
<tr id="row193133381266"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p1631315381568"><a name="p1631315381568"></a><a name="p1631315381568"></a>ohos.permission.READ_MEDIA</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p1731320383610"><a name="p1731320383610"></a><a name="p1731320383610"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p931303817611"><a name="p931303817611"></a><a name="p931303817611"></a>允许该应用读取您的视频收藏。</p>
</td>
</tr>
<tr id="row738215284617"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p73824281363"><a name="p73824281363"></a><a name="p73824281363"></a>ohos.permission.MICROPHONE</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p1138217281162"><a name="p1138217281162"></a><a name="p1138217281162"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p1338214281661"><a name="p1338214281661"></a><a name="p1338214281661"></a>此应用可随时使用麦克风进行录音。</p>
</td>
</tr>
<tr id="row1777413579619"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p1577415710613"><a name="p1577415710613"></a><a name="p1577415710613"></a>ohos.permission.WRITE_MEDIA</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p14774175715612"><a name="p14774175715612"></a><a name="p14774175715612"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p677419573612"><a name="p677419573612"></a><a name="p677419573612"></a>允许该应用写入您的音乐收藏。</p>
</td>
</tr>
<tr id="row18922519719"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p1892954719"><a name="p1892954719"></a><a name="p1892954719"></a>ohos.permission.DISTRIBUTED_DATASYNC</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p15892105875"><a name="p15892105875"></a><a name="p15892105875"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p12892175879"><a name="p12892175879"></a><a name="p12892175879"></a>管控分布式数据传输能力。</p>
</td>
</tr>
<tr id="row109781511376"><td class="cellrowborder" valign="top" width="33.333333333333336%" headers="mcps1.2.4.1.1 "><p id="p797810117714"><a name="p797810117714"></a><a name="p797810117714"></a>ohos.permission.DISTRIBUTED_VIRTUALDEVICE</p>
</td>
<td class="cellrowborder" valign="top" width="25.83258325832583%" headers="mcps1.2.4.1.2 "><p id="p109787110712"><a name="p109787110712"></a><a name="p109787110712"></a>user_grant(动态权限)</p>
</td>
<td class="cellrowborder" valign="top" width="40.83408340834084%" headers="mcps1.2.4.1.3 "><p id="p19978813720"><a name="p19978813720"></a><a name="p19978813720"></a>允许应用使用分布式虚拟能力</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **说明:**
>静态权限:应用安装时由系统授予的权限,对应于权限敏感级别的system\_grant
>动态权限:应用在运行过程中需要用户授权的权限,对应于权限敏感级别的user\_grant
## 场景介绍<a name="section18502174174019"></a>
应用权限是软件用来访问系统资源和使用系统能力的一种通行方式。在涉及用户隐私相关功能和数据的场景,例如:访问个人设备的硬件特性,如摄像头、麦克风,以及读写媒体文件等,OpenHarmony通过应用权限管理组件来保护这些数据以及能力。
在系统应用开发过程中,如果应用要使用敏感权限,开发者可以调用应用权限管理组件接口检查待访问权限是否被授权,如果未授权,操作不允许。
## 接口说明<a name="section1633115419401"></a>
应用权限管理提供的API接口,当前仅供系统应用和系统服务调用,具体API接口如下。
**表 2** 应用权限管理API接口功能介绍
<a name="table9789027162518"></a>
<table><thead align="left"><tr id="row9789427112518"><th class="cellrowborder" valign="top" width="55.66%" id="mcps1.2.3.1.1"><p id="p9790102717251"><a name="p9790102717251"></a><a name="p9790102717251"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="44.34%" id="mcps1.2.3.1.2"><p id="p779032715251"><a name="p779032715251"></a><a name="p779032715251"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row187901627112516"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p138014275353"><a name="p138014275353"></a><a name="p138014275353"></a>int CheckPermission(int uid, const char *permissionName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p57901727202510"><a name="p57901727202510"></a><a name="p57901727202510"></a>检查指定UID的应用进程是否具有访问系统服务API的权限</p>
</td>
</tr>
<tr id="row19341734164410"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p123453412448"><a name="p123453412448"></a><a name="p123453412448"></a>int CheckSelfPermission(const char *permissionName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p937645212447"><a name="p937645212447"></a><a name="p937645212447"></a>检查调用者是否具有访问系统服务API的权限</p>
</td>
</tr>
<tr id="row879032715258"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p13071135133514"><a name="p13071135133514"></a><a name="p13071135133514"></a>int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p1379072718259"><a name="p1379072718259"></a><a name="p1379072718259"></a>查询应用申请的所有权限,并检查权限是否被授予</p>
</td>
</tr>
<tr id="row877239193516"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p878133903516"><a name="p878133903516"></a><a name="p878133903516"></a>int GrantPermission(const char *identifier, const char *permName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p678143943515"><a name="p678143943515"></a><a name="p678143943515"></a>将指定权限授予应用程序</p>
</td>
</tr>
<tr id="row3616164223510"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p1617142163517"><a name="p1617142163517"></a><a name="p1617142163517"></a>int RevokePermission(const char *identifier, const char *permName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p06171242143517"><a name="p06171242143517"></a><a name="p06171242143517"></a>收回应用程序的指定权限</p>
</td>
</tr>
<tr id="row13790122742516"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p23273123365"><a name="p23273123365"></a><a name="p23273123365"></a>int GrantRuntimePermission(int uid, const char *permissionName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p177908273259"><a name="p177908273259"></a><a name="p177908273259"></a>应用运行时动态授予指定权限</p>
</td>
</tr>
<tr id="row18566191217452"><td class="cellrowborder" valign="top" width="55.66%" headers="mcps1.2.3.1.1 "><p id="p169891916194512"><a name="p169891916194512"></a><a name="p169891916194512"></a>int RevokeRuntimePermission(int uid, const char *permissionName)</p>
</td>
<td class="cellrowborder" valign="top" width="44.34%" headers="mcps1.2.3.1.2 "><p id="p937132011440"><a name="p937132011440"></a><a name="p937132011440"></a>应用运行时动态撤销指定权限</p>
</td>
</tr>
</tbody>
</table>
## 开发步骤<a name="section022611498210"></a>
本部分以包管理器的应用权限开发为例进行讲解。开发过程中,首先需要明确涉及的敏感权限,并在config.json中声明该权限,在安装应用程序时,包管理器会调用应用权限管理组件的接口检查该权限是否被授予,若授予,安装流程正常进行,否则安装失败。
1. 在开发过程中,包管理器明确需要安装应用的权限(ohos.permission.INSTALL\_BUNDLE),并在config.json中声明该权限;
```
{
...
"module": {
"package": "com.huawei.kitframework",
"deviceType": [
"phone", "tv","tablet", "pc","car","smartWatch","sportsWatch","smartCamera", "smartVision"
],
"reqPermissions": [{
// 声明需要的权限:安装应用程序的权限名
"name": "ohos.permission.INSTALL_BUNDLE",
"reason": "install bundle",
"usedScene": {
"ability": [
"KitFramework"
],
"when": "always"
}
},
{
"name": "ohos.permission.LISTEN_BUNDLE_CHANGE",
"reason": "install bundle",
"usedScene": {
"ability": [
"KitFramework"
],
"when": "always"
}
},
{
"name": "ohos.permission.GET_BUNDLE_INFO",
"reason": "install bundle",
"usedScene": {
"ability": [
"KitFramework"
],
"when": "always"
}
}
],
...
}
```
2. 当包管理器开发应用安装功能接口时,会调用权限管理相关接口检查自身是否具有安装应用程序的权限,例如:以安装应用的权限名"ohos.permission.INSTALL\_BUNDLE"作为入参,调用CheckPermission接口检查包管理器是否具有安装应用的权限,如果有权限,安装流程继续执行,否则返回安装失败;
```
constexpr static char PERMISSION_INSTALL_BUNDLE[] = "ohos.permission.INSTALL_BUNDLE";
bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback)
{
if ((hapPath == nullptr) || (installerCallback == nullptr) || (installParam == nullptr)) {
HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to nullptr parameters");
return false;
}
// 检查ohos.permission.INSTALL_BUNDLE权限是否被授予
if (CheckPermission(0, static_cast<const char *>(PERMISSION_INSTALL_BUNDLE)) != GRANTED) {
HILOG_ERROR(HILOG_MODULE_APP, "BundleManager install failed due to permission denied");
return false; // 返回安装失败
}
// 安装流程
...
}
```
# 应用验签开发指导<a name="ZH-CN_TOPIC_0000001058671627"></a>
- [场景介绍](#section18502174174019)
- [验签流程](#section554632717226)
- [接口说明](#section1633115419401)
- [开发步骤](#section4207112818418)
- [生成OpenHarmony签名应用](#section167151429133312)
## 场景介绍<a name="section18502174174019"></a>
为了确保应用的完整性和来源可靠,OpenHarmony需要对应用进行签名和验签。
- 应用开发阶段:开发者完成开发并生成安装包后,需要开发者对安装包进行签名,以证明安装包发布到设备的过程中没有被篡改。OpenHarmony的应用完整性校验模块提供了签名工具、签名证书生成规范,以及签名所需的公钥证书等完整的机制,支撑开发者对应用安装包签名。为了方便开源社区开发者,版本中预置了公钥证书和对应的私钥,为开源社区提供离线签名和校验能力;在OpenHarmony商用版本中应替换此公钥证书和对应的私钥。
- 应用安装阶段:OpenHarmony用户程序框架子系统负责应用的安装。在接收到应用安装包之后,应用程序框架子系统需要解析安装包的签名数据,然后使用应用完整性校验模块的API对签名进行验证,只有校验成功之后才允许安装此应用. 应用完整性校验模块在校验安装包签名数据时,会使用系统预置的公钥证书进行验签。
## 验签流程<a name="section554632717226"></a>
未经签名的Hap包的压缩方式是ZIP格式,简单分为文件块,中心目录(Central directory)块,中心目录结尾(EOCD,End of central directory record)块。
经过签名的Hap包,在文件块,和中心目录块之间,插入了签名块。签名块由整包签名数据块(data sign block)、授权文件签名数据块(profile sign block)和签名头(sign head)组成,如下图所示。
**图 1** 经过签名的Hap包结构<a name="fig699855043"></a>
![](figure/zh-cn_image_0000001181934155.png)
整个验签流程,主要分为三部分:整包验签、授权文件验签,以及授权文件内容校验。
**整包验签**
整包签名数据块是一个PKCS7格式的签名块(signed data),验签过程包括PKSC7签名验证、哈希比较、证书链验证以及证书链与设备预置根证书的匹配校验。
**授权文件验签**
授权文件数据块是一个PKCS7格式的签名块(signed data),其中PKCS7签名块的内容信息\(contentinfo\)是授权文件的内容。验签过程包括:PKCS7签名验证、哈希比较、证书链验证以及签发授权文件证书的合法性校验。
**授权文件内容校验**
验签模块将对授权文件内容进行合法性检查。如果授权文件是调试类型,则会比对本机UDID是否在授权文件授权调试的UDID列表中,如果本机UDID在授权文件授权调试的UDID列表中,则会进一步比较授权文件中的调试证书和整包签名使用的证书是否相同,如果相同,则验证通过。
## 接口说明<a name="section1633115419401"></a>
验签组件当前提供innerkits接口,仅供系统应用调用,相关接口及功能描述如下:
**表 1** 轻量级系统验签组件API接口功能介绍
<a name="table1731550155318"></a>
<table><thead align="left"><tr id="row4419501537"><th class="cellrowborder" valign="top" width="37.66%" id="mcps1.2.3.1.1"><p id="p54150165315"><a name="p54150165315"></a><a name="p54150165315"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="62.339999999999996%" id="mcps1.2.3.1.2"><p id="p941150145313"><a name="p941150145313"></a><a name="p941150145313"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row34145016535"><td class="cellrowborder" valign="top" width="37.66%" headers="mcps1.2.3.1.1 "><p id="p122711391160"><a name="p122711391160"></a><a name="p122711391160"></a>int APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)</p>
</td>
<td class="cellrowborder" valign="top" width="62.339999999999996%" headers="mcps1.2.3.1.2 "><p id="p13562171015712"><a name="p13562171015712"></a><a name="p13562171015712"></a>主入口函数,输入文件路径,进行验签,并将从描述文件中获取的数据通过verifyRst返回给调用者</p>
</td>
</tr>
<tr id="row1746172917474"><td class="cellrowborder" valign="top" width="37.66%" headers="mcps1.2.3.1.1 "><p id="p2131144717619"><a name="p2131144717619"></a><a name="p2131144717619"></a>int APPVERI_SetDebugMode(bool mode)</p>
</td>
<td class="cellrowborder" valign="top" width="62.339999999999996%" headers="mcps1.2.3.1.2 "><p id="p1577114614282"><a name="p1577114614282"></a><a name="p1577114614282"></a>设置测试模式,设置mode为true,则支持基于测试根密钥的证书链校验,设置mode为false,则关闭基于测试根密钥的证书链校验。</p>
<p id="p2431455765"><a name="p2431455765"></a><a name="p2431455765"></a>注:当前没有基于现有测试根密钥的证书,开发者可根据自身需要,替换测试根密钥并进行相关验证。</p>
</td>
</tr>
<tr id="row10992232154714"><td class="cellrowborder" valign="top" width="37.66%" headers="mcps1.2.3.1.1 "><p id="p685215538611"><a name="p685215538611"></a><a name="p685215538611"></a>void APPVERI_FreeVerifyRst(VerifyResult *verifyRst)</p>
</td>
<td class="cellrowborder" valign="top" width="62.339999999999996%" headers="mcps1.2.3.1.2 "><p id="p126575774517"><a name="p126575774517"></a><a name="p126575774517"></a>释放verifyRst中申请的内存</p>
</td>
</tr>
</tbody>
</table>
**表 2** 标准系统验签组件API接口功能介绍
<a name="table10383348161613"></a>
<table><thead align="left"><tr id="row9384114813161"><th class="cellrowborder" valign="top" width="37.66%" id="mcps1.2.3.1.1"><p id="p038411483162"><a name="p038411483162"></a><a name="p038411483162"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="62.339999999999996%" id="mcps1.2.3.1.2"><p id="p9384124871618"><a name="p9384124871618"></a><a name="p9384124871618"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row11384194871614"><td class="cellrowborder" valign="top" width="37.66%" headers="mcps1.2.3.1.1 "><p id="p138411487168"><a name="p138411487168"></a><a name="p138411487168"></a>nt HapVerify(const std::string&amp; filePath, HapVerifyResult&amp; hapVerifyResult)</p>
</td>
<td class="cellrowborder" valign="top" width="62.339999999999996%" headers="mcps1.2.3.1.2 "><p id="p0384184810169"><a name="p0384184810169"></a><a name="p0384184810169"></a>校验应用完整性,识别应用来源。</p>
</td>
</tr>
</tbody>
</table>
## 开发步骤<a name="section4207112818418"></a>
### 生成OpenHarmony签名应用<a name="section167151429133312"></a>
参考文档:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md
# 安全<a name="ZH-CN_TOPIC_0000001157319395"></a>
- **[概述](subsys-security-overview.md)**
- **[应用验签开发指导](subsys-security-sigverify.md)**
- **[应用权限管理开发指导](subsys-security-rightmanagement.md)**
- **[IPC通信鉴权开发指导](subsys-security-communicationverify.md)**
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册