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

news2025/1/12 21:55:55

介绍

应用签名系统主要负责鸿蒙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;
};

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

postman接口自动化测试

Postman除了前面介绍的一些功能&#xff0c;还有其他一些小功能在日常接口测试或许用得上。今天&#xff0c;我们就来盘点一下&#xff0c;如下所示&#xff1a; 1.数据驱动 想要批量执行接口用例&#xff0c;我们一般会将对应的接口用例放在同一个Collection中&#xff0c;然…

上周,又劝退了10几个...

最近看了很多简历&#xff0c;很多候选人年限不小&#xff0c;但是做的都是一些非常传统的项目&#xff0c;想着也不能通过简历就直接否定一个人&#xff0c;何况现在大环境越来 越难&#xff0c;大家找工作也不容易&#xff0c;于是就打算见一见。 在沟通中发现&#xff0c;由…

chatgpt赋能Python-openpyxl_批注

Openpyxl 批注简介 Openpyxl 是一个用于操作 Microsoft Excel 文件的 Python 库&#xff0c;它提供了许多方便的功能来读取、写入和修改 Excel 文件。其中一个功能是批注&#xff0c;可以在单元格中添加注释或提醒。 Openpyxl 批注的具体用途 Openpyxl 批注在 Excel 工作表中…

应届毕业生第一份C++程序员工作看重什么?我聊聊自己的看法

大家知道应届毕业生的第一份工C程序员工作看重什么&#xff0c;我相信那位同学可能他那个想去做的时候就说啊&#xff0c;因为第二家公司是世界杯公司吗&#xff0c;是单休哈对吧&#xff0c;而且待遇没有另一家高。我相信我们大部分人其实都看中一个&#xff0c;是累不累啊&am…

(浙大陈越版)数据结构 第三章 树(上) 3.1 树和树的表示

目录 3.1.1 引子&#xff08;顺序查找&#xff09; 什么是树 查找 3.1.2 引子 二分查找例子(BinarySearch) 二分查找 3.1.3 引子 二分查找实现 二分查找代码 二分查找的启示 3.1.4 树的定义 一些基本术语&#xff1a; 3.1.5 树的表示 3.1.1 引子&#xff08;顺序查找…

学习Se-net和Sk-net 附网络简单代码(pytorch)

&#xff08;一&#xff09;Se-net的原理和思路     Se-net严格来说是一个小结构&#xff0c;它可以直接插入已有的网络结构中&#xff0c;帮助原有结构获得更好的效果&#xff0c;如插入Resnet网络中。 Se-net的整个流程如下&#xff1a;     &#xff08;1&#xf…

chatgpt赋能Python-opencv_python打开摄像头

OpenCV Python打开摄像头&#xff1a;一种简单的图像处理方式 OpenCV是一种常用的图像处理库&#xff0c;可以用Python编程轻松进行图像和视频处理。其中&#xff0c;打开摄像头也是OpenCV中常用的一种方法。在这篇文章中&#xff0c;我们将介绍OpenCV Python打开摄像头的原理…

chatgpt赋能Python-numpy开根

NumPy开根 在科学计算中&#xff0c;开根运算是一个经常需要进行的操作&#xff0c;它非常有用&#xff0c;可以用来求解方程、计算距离或者简单地将数据压缩成更容易理解的形式等。NumPy是一个强大的库&#xff0c;被广泛地用于Python编程中&#xff0c;它提供了用于开根的特…

chatgpt赋能Python-mofan_python

Mofan Python&#xff1a;一个优秀的入门编程网站 介绍 Mofan Python 是一个致力于帮助人们快速入门 Python 编程的网站。该网站提供了各种编程资源&#xff0c;包括 Python 相关的教程、实例、项目&#xff0c;以及机器学习和深度学习课程等。它的特点在于提供了详细的代码解…

华为OD机试真题 Java 实现【投篮大赛】【2023Q1 100分】

一、题目描述 你现在是一场采用特殊赛制投篮大赛的记录员。 这场比赛由若于回合组成&#xff0c;过去几回合的得分可能会影响以后几回合的得分&#xff0c;比赛开始时&#xff0c;记录是空白的。 你会得到一个记录操作的字符串列表 ops&#xff0c;其中 ops[i] 是你需要记录…

FastDDS安全机制1 - 安全配置

背景 OMG组织对于DDS的安全机制有着对应的定义&#xff0c;其定义在DDS-SECURITY文档中。 这其中主要包含了对应的身份认证、访问控制、通信加密和审计相关的插件。 资料来源&#xff1a;DDS-SECURITY 其实也主要保护了通信过程中的相关安全风险。 资料来源&#xff1a;DDS-S…

轻松保护文档安全:三种实用的PDF加密方法

在我们的日常工作中&#xff0c;经常会使用到PDF格式的文件。为了保护版权和隐私&#xff0c;有时候我们需要对文档进行加密处理。那么&#xff0c;如何对PDF进行加密呢&#xff1f;今天我将为大家介绍几种方法&#xff0c;其中包括记灵在线工具、迅捷PDF编辑器和Speedpdf。 方…

Debian11之 RKE2 部署 K8S 集群

官方地址 资源列表 主机IP主机名称主机角色软件192.168.111.50server1主节点1API Server、controller-manager 和 scheduler192.168.111.51server2主节点2API Server、controller-manager 和 scheduler192.168.111.52server3主节点3API Server、controller-manager 和 schedu…

SocketTools crack所有安全连接的默认安全协议

SocketTools crack所有安全连接的默认安全协议 在所有HTTP客户端组件中添加了对HTTP/2.0协议的支持。 更新了TLS 1.2(及更高版本)和SSH 2.0的安全选项&#xff0c;以使用Microsoft Windows 11和Windows Server 2022中提供的密码套件。较旧、安全性较低的密码套件已被弃用&#…

JavaScript 基础 DOM (二)

事件流 事件流是对事件执行过程的描述 事件捕获 从DOM的根元素开始去执行对应的事件 (从外到里) 事件冒泡 当一个元素的事件被触发时&#xff0c;同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒 泡 addEventListener 第3个参数决定了事件是在捕获阶…

(数据结构)栈的实现——再一次保姆级教学

目录 1. 栈 ​编辑 1.2 栈的实现 2. 代码的实现 2.1 初始化栈和销毁栈 2.2栈顶元素的插入 2.3栈顶元素的删除 栈元素删除 2.4栈顶元素的获取和栈元素的个数 1. 栈 1.1 栈的概念和结构 栈(Stack)是一种线性存储结构&#xff0c;它具有如下特点&#xff1a; &#xff0…

git的学习3

文章目录 一、git status 命令二、git diff 命令三、git commit 命令四、git reset 命令五、git rm 命令六、git mv 命令七、提交日志1、Git 查看提交历史2、git blame 总结 提交与修改部分 一、git status 命令 git status 命令用于查看在你上次提交之后是否有对文件进行再次…

jenkins集成sonarqube进行代码质量检测

Jenkins集成Sonar Qube实现代码扫描需要先下载整合插件 安装SonarQube scanner 插件&#xff0c;安装完后&#xff0c;插件展示如下 配置SonarQube 的配置信息 这里给名称取为&#xff1a;sonarqubeFirst&#xff0c; server Url设置为SonarQube的地址&#xff0c;为http:19…

类和对象【1】初识

全文目录 引言&#xff08;初识面向对象&#xff09;类和对象定义类访问限定及封装类定义的两种方式 类实例化与类对象大小this指针 总结 引言&#xff08;初识面向对象&#xff09; C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通…

如何使用Understand软件查看STM32单片机HAL库函数调用关系

在使用STM32单片机的HAL库函数编程时&#xff0c;会发现好多中断函数里面都有各种回调函数&#xff0c;还有好多函数的调用深度比较深&#xff0c;在编写代码的时候&#xff0c;有时候想查看某个函数是如何被调用的&#xff0c;查看起来非常麻烦。这时候就可以使用Understand软…