OpenHarmony3.1安全子系统-签名系统分析

介绍

应用签名系统主要负责鸿蒙hap应用包的签名完整性校验,以及应用来源识别等功能。

  • 子系统间接口: 应用完整性校验模块给其他模块提供的接口;
  • 完整性校验: 通过验签,保障应用包完整性,防篡改;
  • 应用来源识别: 通过匹配签名证书链与可信源列表,识别应用来源。

目录

/base/security/appverify
├── interfaces/innerkits/appverify         # 应用完整性校验模块代码
│       ├── config                         # 应用签名根证书和可信源列表配置文件存放目录
│       ├── include                        # 头文件存放目录
│       ├── src                            # 源代码存放目录
│       ├── test                           # 模块自动化测试用例存放目录
├── test/resource                          # 测试资源存放目录

接口

目前签名系统对外只提供了一个校验的接口,这个接口会负责完整性已经来源的校验。

接口名

说明

int HapVerify(const std::string& filePath, HapVerifyResult& hapVerifyResult)

校验应用完整性,识别应用来源

代码分析

HapVerify

HapVerify函数是签名校验的入口函数,目前实现在

interfaces/innerkits/appverify/src/hap_verify.cpp

这个函数里面首先是做了一个初始化的操作,然后就是对应的完整性验证逻辑了。

int HapVerify(const std::string& filePath, HapVerifyResult& hapVerifyResult)
{
    if (!g_isInit && !HapVerifyInit()) {
        return VERIFY_SOURCE_INIT_FAIL;
    }
    HapVerifyV2 hapVerifyV2;
    return hapVerifyV2.Verify(filePath, hapVerifyResult);
}

HapVerifyInit

这个函数主要就是签名需要用到的信息的初始化。

签名系统内部在签名校验前需要做的:

ca管理,可信资源管理,CRL管理,设备类型管理,ticket管理

/**
 * @brief 初始化
 * 
 * @return true 
 * @return false 
 */
bool HapVerifyInit()
{
    //初始化ca管理实例,主要是从json文件中获取ca,方便后续验证ca比较ca
    TrustedRootCa& rootCertsObj = TrustedRootCa::GetInstance();
    //初始化可信资源管理实例,主要是可信app的管理,主要是匹配app的证书。
    TrustedSourceManager& trustedAppSourceManager = TrustedSourceManager::GetInstance();
    //初始化CRL管理实例,证书吊销列表的相关管理
    HapCrlManager& hapCrlManager = HapCrlManager::GetInstance();
    //设备信息的管理,主要用于判断是否是debug模式
    DeviceTypeManager& deviceTypeManager = DeviceTypeManager::GetInstance();
    TrustedTicketManager& trustedTicketSourceManager = TrustedTicketManager::GetInstance();
    g_mtx.lock();
    g_isInit = rootCertsObj.Init() && trustedAppSourceManager.Init();
    if (!g_isInit) {
        rootCertsObj.Recovery();
        trustedAppSourceManager.Recovery();
    }
    trustedTicketSourceManager.Init();
    hapCrlManager.Init();
    deviceTypeManager.GetDeviceTypeInfo();
    g_mtx.unlock();
    return g_isInit;
}

verify

目前使用的是v2版本的校验,猜测和android对应的v2签名一致。

int HapVerifyV2::Verify(const std::string& filePath, HapVerifyResult& hapVerifyV1Result)
{
    HAPVERIFY_LOG_DEBUG(LABEL, "Start Verify");
    std::string standardFilePath;
    //检查文件路径信息
    if (!CheckFilePath(filePath, standardFilePath)) {
        return FILE_PATH_INVALID;
    }

    //检查文件是否可以正常open,并且不是空文件
    RandomAccessFile hapFile;
    if (!hapFile.Init(standardFilePath)) {
        HAPVERIFY_LOG_ERROR(LABEL, "open standard file failed");
        return OPEN_FILE_ERROR;
    }

    int resultCode = Verify(hapFile, hapVerifyV1Result);
    return resultCode;
}

int HapVerifyV2::Verify(RandomAccessFile& hapFile, HapVerifyResult& hapVerifyV1Result)
{
    SignatureInfo hapSignInfo;
    if (!HapSigningBlockUtils::FindHapSignature(hapFile, hapSignInfo)) {
        return SIGNATURE_NOT_FOUND;
    }
    hapVerifyV1Result.SetVersion(hapSignInfo.version);
    hapVerifyV1Result.SetPkcs7SignBlock(hapSignInfo.hapSignatureBlock);
    hapVerifyV1Result.SetPkcs7ProfileBlock(hapSignInfo.hapSignatureBlock);
    hapVerifyV1Result.SetOptionalBlocks(hapSignInfo.optionBlocks);
    Pkcs7Context pkcs7Context;
    if (!VerifyAppPkcs7(pkcs7Context, hapSignInfo.hapSignatureBlock)) {
        return VERIFY_APP_PKCS7_FAIL;
    }
    int profileIndex = 0;
    if (!HapSigningBlockUtils::GetOptionalBlockIndex(hapSignInfo.optionBlocks, PROFILE_BLOB, profileIndex)) {
        return NO_PROFILE_BLOCK_FAIL;
    }
    bool profileNeedWriteCrl = false;
    if (!VerifyAppSourceAndParseProfile(pkcs7Context, hapSignInfo.optionBlocks[profileIndex].optionalBlockValue,
        hapVerifyV1Result, profileNeedWriteCrl)) {
        HAPVERIFY_LOG_ERROR(LABEL, "APP source is not trusted");
        return APP_SOURCE_NOT_TRUSTED;
    }
    if (!GetDigestAndAlgorithm(pkcs7Context)) {
        HAPVERIFY_LOG_ERROR(LABEL, "Get digest failed");
        return GET_DIGEST_FAIL;
    }
    std::vector<std::string> publicKeys;
    if (!HapVerifyOpensslUtils::GetPublickeys(pkcs7Context.certChains[0], publicKeys)) {
        HAPVERIFY_LOG_ERROR(LABEL, "Get publicKeys failed");
        return GET_PUBLICKEY_FAIL;
    }
    hapVerifyV1Result.SetPublicKey(publicKeys);
    std::vector<std::string> certSignatures;
    if (!HapVerifyOpensslUtils::GetSignatures(pkcs7Context.certChains[0], certSignatures)) {
        HAPVERIFY_LOG_ERROR(LABEL, "Get sianatures failed");
        return GET_SIGNATURE_FAIL;
    }
    hapVerifyV1Result.SetSignature(certSignatures);
    if (!HapSigningBlockUtils::VerifyHapIntegrity(pkcs7Context, hapFile, hapSignInfo)) {
        HAPVERIFY_LOG_ERROR(LABEL, "Verify Integrity failed");
        return VERIFY_INTEGRITY_FAIL;
    }
    WriteCrlIfNeed(pkcs7Context, profileNeedWriteCrl);
    return VERIFY_SUCCESS;
}

签名结构

SignatureInfo

这部分主要是在zip文件头部添加的签名的信息。

struct SignatureInfo {
    HapByteBuffer hapSignatureBlock;
    long long hapSigningBlockOffset;
    long long hapCentralDirOffset;
    long long hapEocdOffset;
    HapByteBuffer hapEocd;
    std::vector<OptionalBlock> optionBlocks;
    int version;
};

Pkcs7Context

签名算法相关的结构信息,这部分是在SignatureInfo.hapSignatureBlock中存储的信息

struct Pkcs7Context {
    bool needWriteCrl;
    int digestAlgorithm;
    MatchingResult matchResult;
    std::string certIssuer;
    PKCS7* p7;
    Pkcs7CertChains certChains;
    HapByteBuffer content;
};

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/24395.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

互联网中的web3.0和gpt有何联系?

文章目录 ⭐前言⭐web 3.0&#x1f496; web1.0-web3.0的概念 ⭐chatgpt&#x1f496; gpt的概念 ⭐总结⭐结尾 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享互联网中的web3.0和gpt的关系。 互联网的发展 第一台计算机的出现 世界上第一台通用计算机“ENIAC”于…

JavaScript键盘事件

目录 一、keydown&#xff1a;按下键盘上的任意键时触发。 二、keyup&#xff1a;释放键盘上的任意键时触发。 三、keypress&#xff1a;在按下并释放能够产生字符的键时触发&#xff08;不包括功能键等&#xff09;。 四、input&#xff1a;在文本输入框或可编辑元素的内容…

SCSI介绍和SCSI命令承载于各类总线的方式

1. SCSI协议简介 小型计算机系统接口(SCSI&#xff0c;Small Computer System Interface&#xff09;是一种用于计算机及其周边设备之间&#xff08;硬盘、软驱、光驱、打印机、扫描仪等&#xff09;系统级接口的独立处理器标准。虽然名字里面带个接口&#xff0c;但实际上是一…

基于深度学习的高精度野生目标检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度野生目标检测识别系统可用于日常生活中检测与定位野生目标目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的野生目标目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测…

Apache DolphinScheduler——开源大数据调度器神器(国人之光)

本文已参与「新人创作礼」活动&#xff0c;一起开启掘金创作之路。 1. 简 介 Apache DolphinScheduler(海豚调度),国人之光&#xff0c;是许多国人雷锋开源在Apache的顶级项目&#xff0c;主要功能就是负责任务的调度处理。 1.1 概 念 Apache DolphinScheduler是一个分布式去…

玩转用户旅程地图

图&#xff1a;史江鸿 从事需求分析和产品设计工作已经有几个年头了&#xff0c;我很享受这个职业。因为在这段职业历程中&#xff0c;我学到了很多有意思的方法和工具&#xff0c;用户旅程地图就是其中一个。 如今在国内外许多IT公司&#xff0c;用户旅程地图已经成为需求分析…

Python连接达梦数据库

python如果想连接达梦数据库&#xff0c;必须要安装dmPython。 简介&#xff1a;dmPython 是 DM 提供的依据 Python DB API version 2.0 中 API 使用规定而开发的数据库访问接口。dmPython 实现这些 API&#xff0c;使 Python 应用程序能够对 DM 数据库进行访问。 dmPython 通…

微服务之服务容错

Informal Essay By English Share a sentence that I think is very reasonable, as long as you can know the underlying logic of anything, you can hold it without fear 参考书籍&#xff1a; “凤凰架构” 引言 在 Martin Fowler 与 James Lewis合写的文章《Micros…

Linux内核源码分析 2:Linux内核版本号和源码目录结构

一、Linux的版本 1. 稳定版和开发版 Linux内核主要分为两种版本&#xff1a; 稳定版&#xff08;长期支持版&#xff09;&#xff1a;稳定版的内核具有工业级的强度&#xff0c;可以广泛地应用和部署。而每一代新推出的稳定版内核大部分都只是修正了一些Bug或是加入了一些新的…

MySQL数据类型

文章目录 一、数据类型分类二、数值类型1.tinyint类型2.bit类型3.float类型4.decimal类型 三、字符串类型1.char类型2.varchar类型 四、日期和时间类型五、enum类型和set类型1.enum类型2.set类型 一、数据类型分类 MySQL的数据类型一共有如下几类&#xff0c;表格中简单介绍了…

企业级API网关之典型应用场景

目 录 01 企业面对API与网关的现状‍‍‍‍‍ 02 APIGW介绍及企业应用场景 03 总结 01 企业面对API与网关的现状‍ 在企业中&#xff0c;进行新的系统/应用/产品开发时&#xff0c;具有周密的流程&#xff1a;从需求分析、设计、开发、测试、发布与验收。所以&#xff0c;一…

bmp转jpg怎么转?bmp转换jpg的几个方法

bmp转换jpg的几个方法~什么是BMP呢&#xff1f;BMP是位图文件格式的一种&#xff0c;全称为Bitmap&#xff08;位图&#xff09;&#xff0c;是一种基于像素的图像文件格式。BMP是Windows操作系统中最常用的图像格式之一&#xff0c;通常以.bmp或.dib作为文件扩展名。BMP文件格…

华芯微特SWM34-IO速度优化

对比测试了一下IO翻转速度在各种函数调用的情况下的差异 CPU运行速度150Mhz,SDRAM开 直接调用翻转函数 while(1) {GPIO_InvBit(GPIOA, PIN0)&#xff1b; }速度大约5Mhz&#xff0c;主要是因为函数调用开销和函数内部的移位和异或操作&#xff0c;增加了指令的运行数量。 vo…

Rust每日一练(Leetday0012) 首末位置、插入位置、有效数独

目录 34. 查找元素的首末位置 Find-first-and-last-position-of-element-in-sorted-array &#x1f31f;&#x1f31f; 35. 搜索插入位置 Search Insert Position &#x1f31f; 36. 有效的数独 Valid Sudoku &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏…

Atcoder beginner contest 302

A - Attack AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> #define int long long using namespace std; signed main() {int a, b;cin >> a >> b;if (a % b 0) cout << a / b << endl;else c…

加密与解密 调试篇 动态调试技术 (二)

目录 常见的断点 1.INT 3 断点 检测 绕过 2.硬件断点 原理 我们给出硬件中断的例子 删除硬件断点 3.内存断点 原理 例子 删除 区别 总结 4.内存访问一次性断点 5.消息断点 例子 删除 6.条件断点 &#xff08;1&#xff09;按寄存器条件中断 &#xff08;2&…

【JDK】一、jdk17的下载与安装配置(图文说明超详细)

JDK17的下载与安装 前言一、JDK17下载1、官方下载地址 &#xff08; Oracle中国的官方网站&#xff09; 二、JDK17安装1、先看一下我现在的java版本和环境变量2、开始新的安装第一步&#xff1a;双击下载的jdk-17.0.7_windows-x64_bin.exe 进入到安装页面第二步&#xff1a;jdk…

sqlmap命令大全(附详细扫描流程)

一、sqlmap命令大全。 -u 指定目标URL (可以是http协议也可以是https协议)-d 连接数据库--dbs 列出所有的数据库--current-db 列出当前数据库--tables 列出当前的表--columns 列出当前的列-D 选择使用哪个数据库-T 选择使用哪个表-C 选择使用哪个列--dump 获取字段中的数据--…

破解mysql用户的密码

假如mysql数据库中有一个 prod_blb 用户&#xff0c;你作为root管理员&#xff0c;想知道它的密码&#xff0c;又不想修改它的密码。这个时候就只能通过获取到 prod_blb 用户加密的密码进程破译 1、MYSQL加密方式 MYSQL数据库的认证密码有两种方式&#xff0c;MYSQL 4.1版本之…

《Spring Guides系列学习》guide6 - guide10

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…