【HarmonyOS NEXT】關鍵資產存儲開發案例

在 iOS 開發中?Keychain 是一個非常安全的存儲系統,用于保存敏感信息,如密碼、證書、密鑰等。與文件系統不同,Keychain 提供了更高的安全性,因為它對數據進行了加密,并且只有經過授權的應用程序才能訪問存儲的數據。那么在鴻蒙里面對應的是什么呢?

1、關鍵資產(@ohos.security.asset)

在鴻蒙里面也有類似的東西,叫做關鍵資產(@ohos.security.asset),關鍵資產存儲服務提供了用戶短敏感數據的安全存儲及管理能力。其中,短敏感數據可以是密碼類(賬號/密碼)、Token類(應用憑據)、其他關鍵明文(如銀行卡號)等長度較短的用戶敏感數據。

關鍵資產的安全存儲,依賴底層的通用密鑰庫系統。具體來說,關鍵資產的加/解密操作以及訪問控制校驗,都由通用密鑰庫系統在安全環境(如可信執行環境)中完成,即使系統被攻破,也能保證用戶敏感數據不發生泄露。其中,關鍵資產的加/解密使用AES256-GCM算法。

2、關鍵資產使用與 asset 的常用操作

關鍵資產的訪問可分為 4 類(可查看本文第4章節),基于屬主的訪問控制、基于鎖屏狀態的訪問控制、基于鎖屏密碼設置狀態的訪問控制、基于用戶認證的訪問控制,業務可根據實際情況決定是否開啟(如掃臉驗證、解鎖驗證、密碼驗證等),本次文章舉例的開發案例均采用默認保護等級。

?2.1?使用關鍵資產需要導入模塊?AssetStoreKit:

import { asset } from '@kit.AssetStoreKit';

2.2 常用操作:

方法描述
asset.add新增一條關鍵資產。
asset.remove刪除符合條件的一條或多條關鍵資產。
asset.update更新符合條件的一條關鍵資產。
asset.query查詢一條或多條符合條件的關鍵資產。若查詢需要用戶認證的關鍵資產,則需要在本函數前調用asset.preQuery,在本函數后調用asset.postQuery。
asset.preQuery查詢的預處理,用于需要用戶認證的關鍵資產。在用戶認證成功后,應當隨后調用asset.query、asset.postQuery。
asset.postQuery查詢的后置處理,用于需要用戶認證的關鍵資產。需與asset.preQuery函數成對出現。

3、常規方法封裝

3.1 addSync 設置數據

/*** 新增一條關鍵資產* @param key* @param value* @returns*/add(key: string, value: string) {let result: Booleanlet attr: asset.AssetMap = new Map();// 關鍵資產別名,每條關鍵資產的唯一索引。// 類型為Uint8Array,長度為1-256字節。attr.set(asset.Tag.SECRET, this.string2Array(value));// 關鍵資產明文。// 類型為Uint8Array,長度為1-1024字節attr.set(asset.Tag.ALIAS, this.string2Array(key))// 關鍵資產同步類型>THIS_DEVICE只在本設備進行同步,如僅在本設備還原的備份場景。attr.set(asset.Tag.SYNC_TYPE, asset.SyncType.THIS_DEVICE);//枚舉,新增關鍵資產時的沖突(如:別名相同)處理策略。OVERWRITE》拋出異常,由業務進行后續處理。// attr.set(asset.Tag.CONFLICT_RESOLUTION,asset.ConflictResolution.THROW_ERROR)// 在應用卸載時是否需要保留關鍵資產。// 需要權限: ohos.permission.STORE_PERSISTENT_DATA。// 類型為bool。// attr.set(asset.Tag.IS_PERSISTENT, true);//我項目里面沒有使用就先注釋了,后續有需要這個再打開,并且要設置對應權限if (this.isHasKey(key)) {result = this.updateAssetMap(attr);} else {try {if (canIUse("SystemCapability.Security.Asset")) {asset.addSync(attr);result = true}result = false} catch (error) {let err = error as BusinessError;LogUtil.e(`Failed to add Asset. Code is ${err.code}, message is ${err.message}`);result = false}}return result}

3.2?querySync 獲取數據

/*** 查詢* @param key* @returns*/query(key: string) {let query: asset.AssetMap = new Map();// 關鍵資產別名,每條關鍵資產的唯一索引。// 類型為Uint8Array,長度為1-256字節。query.set(asset.Tag.ALIAS, this.string2Array(key));//  關鍵資產查詢返回的結果類型。query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL);// query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ATTRIBUTES); // 此處表示僅返回關鍵資產屬性,不包含關鍵資產明文try {if (canIUse("SystemCapability.Security.Asset")) {let res: Array<asset.AssetMap> = asset.querySync(query);for (let i = 0; i < res.length; i++) {// parse the attribute.if (res[i] != null) {// parse the secret.let secret: Uint8Array = res[0].get(asset.Tag.SECRET) as Uint8Array;// parse uint8array to stringlet secretStr: string = this.array2String(secret);return secretStr;}}}} catch (error) {let err = error as BusinessError;LogUtil.e(TAG, `Failed to query Asset. Code is ${err.code}, message is ${err.message}`);return "";}return ""}

3.3?querySync 查詢 key 數據是否存在

/*** 查詢資產key是否存在* @param key* @returns*/isHasKey(key: string): Boolean {if (canIUse("SystemCapability.Security.Asset")) {let query: asset.AssetMap = new Map();// 關鍵資產別名,每條關鍵資產的唯一索引。// 類型為Uint8Array,長度為1-256字節。query.set(asset.Tag.ALIAS, this.string2Array(key));//  關鍵資產查詢返回的結果類型。query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL);const res = this.queryAssetMap(query);if (!res || res.length < 1) {return false;}return true;}return false;}
/*** 查詢資產 key 的 assetMaps 數據* @param query* @returns*/queryAssetMap(query: asset.AssetMap): Array<asset.AssetMap> {const assetMaps: asset.AssetMap[] = [];try {if (canIUse("SystemCapability.Security.Asset")) {const res: asset.AssetMap[] = asset.querySync(query);return res;}return assetMaps;} catch (error) {const err = error as BusinessError;LogUtil.e(TAG, `Failed to query Asset. Code is ${err.code}, message is ${err.message}`);return assetMaps;}}

3.4 updateSync 修改資產數據

/*** 修改資產數據* @param q* @returns*/updateAssetMap(q: asset.AssetMap): Boolean {try {if (canIUse("SystemCapability.Security.Asset")) {let query: asset.AssetMap = new Map();query.set(asset.Tag.ALIAS, q.get(asset.Tag.ALIAS)!);let attrsToUpdate: asset.AssetMap = new Map();attrsToUpdate.set(asset.Tag.SECRET, q.get(asset.Tag.SECRET)!);asset.updateSync(query, attrsToUpdate);return true}return false} catch (error) {const err = error as BusinessError;LogUtil.e(TAG, `Failed to update Asset. Code is ${err.code}, message is ${err.message}`);return false;}}

3.5 removeSync 刪除資產數據

/*** 刪除一條關鍵資產* @param key*/remove(key: string) {let query: asset.AssetMap = new Map();// 關鍵資產別名,每條關鍵資產的唯一索引。query.set(asset.Tag.ALIAS, this.string2Array(key));try {if (canIUse("SystemCapability.Security.Asset")) {asset.removeSync(query);return true;}return false;} catch (error) {let err = error as BusinessError;LogUtil.e(TAG, `Failed to remove Asset. Code is ${err.code}, message is ${err.message}`);return false;}}

3.6 string 與?Uint8Array 數據互轉換

  string2Array(str: string): Uint8Array {let textEncoder = new util.TextEncoder();return textEncoder.encodeInto(str);}array2String(str: Uint8Array): string {let textDecoder = new util.TextDecoder();return textDecoder.decodeToString(str);}

4、關鍵資產的訪問控制

  • 基于屬主的訪問控制:?所有的關鍵資產都受屬主訪問控制保護,業務無需設置。

    • 只允許關鍵資產被其屬主(寫入該關鍵資產的業務)訪問。
    • 關鍵資產屬主身份由ASSET從系統服務中獲取,即使業務身份被仿冒,仿冒者也無法獲取到其他業務的數據。
    • 關鍵資產加/解密時,其屬主身份參與了完整性保護,即使關鍵資產屬主身份被篡改,攻擊者也無法獲取到其他業務的數據。
  • 基于鎖屏狀態的訪問控制:?分為以下三種保護等級(安全性依次遞增),業務可根據實際情況設置任意一種,若不設置,則默認保護等級為“首次解鎖后可訪問”。

    • 開機后可訪問:關鍵資產在開機后被允許訪問。
    • 首次解鎖后可訪問:關鍵資產在首次解鎖后被允許訪問。
    • 解鎖時可訪問:關鍵資產僅在處于解鎖狀態時被允許訪問。
  • 基于鎖屏密碼設置狀態的訪問控制:?該訪問控制默認不開啟,業務可根據實際情況決定是否開啟。

    • 在用戶設置了鎖屏密碼后,關鍵資產才被允許訪問。
  • 基于用戶認證的訪問控制:?該訪問控制默認不開啟,業務可根據實際情況決定是否開啟。

    • 關鍵資產在用戶身份認證通過后被允許訪問。
    • 任意一種認證方式(指紋、人臉、PIN碼)通過,均可授權本次關鍵資產的訪問。
    • 業務可通過設置認證有效期,達成一次用戶認證、授權多個關鍵資產訪問的效果。認證有效期最長可設置10分鐘。

5、參考

華為官網:@ohos.security.asset (關鍵資產存儲服務)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73052.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ccfcsp1901線性分類器

//線性分類器 #include<iostream> using namespace std; int main(){int n,m;cin>>n>>m;int x[1000],y[1000];char z[1000];for(int i0;i<n;i){cin>>x[i]>>y[i];cin>>z[i];}int a[20],b[20],c[20];for(int i0;i<m;i){cin>>a[i…

Spring Boot 整合 OpenFeign 教程

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 Spring Boot 整合 OpenFeign 教程 一、OpenFeign 簡介 OpenFeign 是 Netflix 開源的聲明式 HTTP 客戶端&#xff0c;通過接口和注解簡化服務間 HTTP 調用。…

APM 仿真遙控指南

地面站開發了一段時間了&#xff0c;由于沒有硬件&#xff0c;所以一直在 APM 模擬器中驗證。我們已經實現了 MAVLink 消息接收和解析&#xff0c;顯示無人機狀態&#xff0c;給無人機發送消息&#xff0c;實現一鍵起飛&#xff0c;飛往指定地點&#xff0c;降落&#xff0c;返…

C語言入門教程100講(4)輸入輸出

文章目錄 1. 什么是輸入輸出&#xff1f;2. 標準輸入輸出函數2.1 printf 函數2.2 scanf 函數 3. 格式化占位符4. 示例代碼代碼解析&#xff1a;輸出結果&#xff1a; 5. 常見問題問題 1&#xff1a;scanf 中的 & 是什么作用&#xff1f;問題 2&#xff1a;printf 和 scanf …

《信息系統安全》(第一次上機實驗報告)

實驗一 &#xff1a;網絡協議分析工具Wireshark 一 實驗目的 學習使用網絡協議分析工具Wireshark的方法&#xff0c;并用它來分析一些協議。 二實驗原理 TCP/IP協議族中網絡層、傳輸層、應用層相關重要協議原理。網絡協議分析工具Wireshark的工作原理和基本使用規則。 三 實…

城市街拍人像自拍電影風格Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色教程 城市街拍人像自拍的電影風格 Lr 調色&#xff0c;是利用 Adobe Lightroom 軟件&#xff0c;對在城市街景中拍攝的人像自拍照片進行后期處理&#xff0c;使其呈現出電影畫面般獨特的視覺質感與藝術氛圍。通過一系列調色操作&#xff0c;改變照片的色彩、明暗、對比等元…

自學Python創建強大AI:從入門到實現DeepSeek級別的AI

人工智能&#xff08;AI&#xff09;是當今科技領域最熱門的方向之一&#xff0c;而Python是AI開發的首選語言。無論是機器學習、深度學習還是自然語言處理&#xff0c;Python都提供了豐富的庫和工具。如果你夢想創建一個像DeepSeek這樣強大的AI系統&#xff0c;本文將為你提供…

Qt/C++項目積累:4.遠程升級工具 - 4.1 項目設想

背景&#xff1a; 桌面程序一般都支持遠程升級&#xff0c;也是比較常用的場景設計。如酷狗音樂的升級&#xff0c;會提供兩個選項&#xff0c;自動幫助安裝或是新版本提醒&#xff0c;由用戶來決定是否升級&#xff0c;都屬于遠程升級的應用及策略。 看看經過這塊的功能了解及…

(一)丶Windows安裝RabbitMQ可能會遇到的問題

一丶可能會忘了配置ERLang的環境變量 二丶執行命令時報錯 第一步 rabbitmq-plugins enable rabbitmq_management 第二部 rabbitmqctl status 三丶修改.erlang.cookie 文件 1.找到C盤目下的.erlang.cookie文件 C:\Users\admin\.erlang.cookie C:\Windows\System32\config\sys…

Amdahl 定律

Amdahl 定律是用來表示&#xff0c;當提高系統某部分性能時對整個系統的影響&#xff0c;其公式如下&#xff1a; a表示我們提升部分初始耗時比例&#xff0c;k是我們的提升倍率&#xff0c;通過這個公式我們可以輕松的得知對每一部分的提醒&#xff0c;對整個系統帶來的影響…

HW華為流程管理體系精髓提煉華為流程運營體系(124頁PPT)(文末有下載方式)

資料解讀&#xff1a;HW華為流程管理體系精髓提煉華為流程運營體系&#xff08;124頁PPT&#xff09; 詳細資料請看本解讀文章的最后內容。 華為作為全球領先的科技公司&#xff0c;其流程管理體系的構建與運營是其成功的關鍵之一。本文將從華為流程管理體系的核心理念、構建…

Powershell WSL導出導入ubuntu22.04.5子系統

導出Linux子系統 導出位置在C盤下,根據自己的實際情況更改即可Write-Host "export ubuntu22.04.5" -ForegroundColor Green wsl --export Ubuntu-22.04 c:\Ubuntu-22.04.tar 導入Linux子系統 好處是目錄可用在任意磁盤路徑,便于遷移不同的設備之間Write-Host &quo…

【Attention】SKAttention

SKAttention選擇核注意力 標題&#xff1a;SKAttention 期刊&#xff1a;IEEE2019 代碼&#xff1a; https://github.com/implus/SKNet 簡介&#xff1a; 動機:增大感受野來提升性能、多尺度信息聚合方式解決的問題&#xff1a;自適應調整感受野大小創新性:提出選擇性內核…

解決Popwindow寬高的問題。

問題 在使用Popwindow進行自定義的過程中&#xff0c;需要設置popwindow的寬高。但是寬高很多時候容易出問題。比如下面的例子。 布局文件如下 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.andr…

MySQL數據庫精研之旅第二期:庫操作的深度探索

專欄&#xff1a;MySQL數據庫成長記 個人主頁&#xff1a;手握風云 目錄 一、查看數據庫 二、創建數據庫 2.1. 語法 2.2. 示例 三、字符集編碼和校驗(排序)規則 3.1. 查看數據庫支持的字符集編碼 3.2. 查看數據庫支持的排序規則 3.3. 不同的字串集與排序規則對數據庫的…

基于deepseek的智能語音客服【第四講】封裝milvus數據庫連接池封裝

通過工廠模式創建鏈接 static {// 創建連接池工廠BasePooledObjectFactory<MilvusServiceClient> factory new BasePooledObjectFactory<MilvusServiceClient>() {Overridepublic MilvusServiceClient create() throws Exception {return new MilvusServiceClient…

STM32基礎教程——定時器

前言 TIM定時器&#xff08;Timer&#xff09;:STM32的TIM定時器是一種功能強大的外設模塊&#xff0c;通過時基單元&#xff08;包含預分頻器、計數器和自動重載寄存器&#xff09;實現精準定時和計數功能。其核心原理是&#xff1a;內部時鐘&#xff08;CK_INT&#xff09;或…

OpenCV旋轉估計(4)生成一個字符串表示的匹配圖函數 matchesGraphAsString()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 matchesGraphAsString 函數是OpenCV庫中的一部分&#xff0c;位于 cv::detail 命名空間下。這個函數的主要作用是生成一個字符串表示的匹配圖&am…

Android 根據Url使用Retrofit框架進行文件下載

一、背景 根據后端返回的url下載地址,去執行文件下載&#xff0c;將文件保存到SD卡。這里使用Retrofit網絡框架。 二、代碼實現 2.1、定義一個DownloadFileService interface DownloadFileService {StreamingGETsuspend fun downloadFile(Url fileUrl: String):ResponseBody…