色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

HarmonyOS開發案例:【字符串加解密】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-21 21:36 ? 次閱讀

介紹

本Codelab針對用戶隱私安全,使用加密算法API對密碼進行加密存儲,模擬開發一個用戶注冊登錄應用。實現如下功能:

  1. 實現登錄、注冊、登錄成功頁面。
  2. 注冊的用戶數據保存到關系型數據庫。
  3. 登錄時通過查詢數據庫校驗用戶是否存在、密碼是否正確。
  4. 密碼通過加密算法保存和使用。

相關概念

  • [加解密算法庫框架]:為屏蔽底層硬件和算法庫,向上提供統一的密碼算法庫加解密相關接口
  • [關系型數據庫]:關系型數據庫(Relational Database,RDB)是一種基于關系模型來管理數據的數據庫。

環境搭建

軟件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 開發板類型:[潤和RK3568開發板]。
  • OpenHarmony系統:3.2 Release。

環境搭建

完成本篇Codelab我們首先要完成開發環境的搭建,本示例以RK3568開發板為例,參照以下步驟進行:

  1. [獲取OpenHarmony系統版本]:標準系統解決方案(二進制)。以3.2 Release版本為例:
  2. 搭建燒錄環境。
    1. [完成DevEco Device Tool的安裝]
    2. [完成RK3568開發板的燒錄]
  3. 搭建開發環境。
    1. 開始前請參考[工具準備],完成DevEco Studio的安裝和開發環境配置。
    2. 開發環境配置完成后,請參考[使用工程向導]創建工程(模板選擇“Empty Ability”)。
    3. 工程創建完成后,選擇使用[真機進行調測]。
    4. 鴻蒙開發指導文檔:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md點擊或者復制轉到。

代碼結構解讀

HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿

搜狗高速瀏覽器截圖20240326151547.png

本篇Codelab只對核心代碼進行講解,對于完整代碼,我們會在gitee中提供。

├──entry/src/main/ets                   // 代碼區
│  ├──common
│  │  ├──constants
│  │  │  └──CommonConstants.ets         // 公共常量類
│  │  └──utils
│  │     ├──AesUtil.ets                 // 加解密工具類
│  │     ├──DataTransformUtil.ets       // 數據轉換工具類
│  │     ├──Logger.ets                  // 日志打印工具類
│  │     └──PromptUtil.ts               // 彈窗工具類
│  ├──entryability
│  │  └──EntryAbility.ts                // 程序入口類
│  ├──model
│  │  ├──RdbModel.ets                   // 數據庫業務處理文件
│  │  └──UserTableApi.ets               // 用戶表具體業務文件
│  ├──pages
│  │  ├──Login.ets                      // 登錄頁
│  │  ├──Register.ets                   // 注冊頁
│  │  └──Welcome.ets                    // 歡迎頁
│  └──viewmodel
│     └──User.ets                       // 用戶實體類
└──entry/src/main/resources             // 資源文件目錄

關系型數據庫

首先編寫創建表的SQL語句,其中user為表名、id為主鍵并自動遞增、username為用戶名、password為加密后的密碼、authTag為加解密認證信息

// CommonConstants.ets
  /**
   * 創建表的SQL語句
   */
  static readonly CREATE_TABLE_SQL: string = 'CREATE TABLE IF NOT EXISTS user(' +
    'id INTEGER PRIMARY KEY AUTOINCREMENT, ' +
    'username TEXT NOT NULL, ' +
    'password TEXT NOT NULL, ' +
    'authTag TEXT NOT NULL)';

在RdbModel的構造方法中,調用getRdbStore方法創建數據庫。其中STORE_CONFIG為數據庫相關配置,sqlCreateTable為創建user用戶表所需的SQL語句。

// RdbModel.ets
import dataRdb from '@ohos.data.relationalStore';
...
export class RdbModel {
  private rdbStore: dataRdb.RdbStore | null = null;
  private tableName: string = '';
  private sqlCreateTable: string = '';
  ...
  constructor(tableName: string, sqlCreateTable: string, columns: Array< string >) {
    this.tableName = tableName;
    this.sqlCreateTable = sqlCreateTable;
    this.columns = columns;
    this.getRdbStore();
  }

  /**
   * 獲取數據庫操作對象rdbStore.
   */
  getRdbStore() {
    let getPromiseRdb = dataRdb.getRdbStore(getContext(), { name: CommonConstants.DATABASE_NAME, securityLevel: dataRdb.SecurityLevel.S1 });
    getPromiseRdb.then(rdbStore = > {
      this.rdbStore = rdbStore;
      this.rdbStore.executeSql(this.sqlCreateTable);
    }).catch((err: Error) = > {
      Logger.error(`getRdbStore err ${JSON.stringify(err)}`);
    });
  }

創建UserTableApi.ets文件,實例化RdbModel創建userTable對象。并對外提供可操作用戶數據表的API接口,包括插入數據、根據用戶名查詢用戶信息等方法。

// UserTableApi.ets
export class UserTableApi {
  private userTable = new RdbModel(TABLE_NAME, CREATE_USER_TABLE, COLUMNS);

  /**
   * 將數據保存到數據庫中
   *
   * @param user 需要保存的User類型的數據對象
   */
  insertUserData(user: User) {
    this.userTable.insertData(user);
  }

  /**
   * 根據用戶名查詢用戶信息
   *
   * @param username 查詢的用戶名
   * @returns 查詢結果集
   */
  async queryUserByUsername(username: string): Promise< User[] > {
    let resultList: Array< User >;
    // 過濾條件
    let predicates = new dataRdb.RdbPredicates(TABLE_NAME);
    predicates.equalTo('username', username);
    // 將查詢到的結果封裝成User對應的用戶信息
    let ret = await this.userTable.query(predicates);
    resultList = this.getListFromResultSet(ret);
    return resultList;
  }
  ...
}

密碼加解密

創建AesUtil工具類,封裝加解密相關邏輯。首先引入@ohos.security.cryptoFramework包,在構造方法中初始化加解密算法框架所需的環境,包括密鑰規格的選擇、加解密規格的選擇等。本示例采用對稱AES加解密算法,密鑰長度為256位,分組模式為GCM。具體有以下步驟:

  1. 創建對稱密鑰生成器。
  2. 通過密鑰生成器生成對稱密鑰。
  3. 創建加解密生成器。
  4. 通過加解密生成器加密或解密數據。

說明: 對于對稱密鑰、非對稱密鑰、加解密算法模式。

// AesUtil.ets
import cryptoFramework from '@ohos.security.cryptoFramework';
...
class AesUtil {
  private globalCipher: cryptoFramework.Cipher = cryptoFramework.createCipher(CommonConstants.GENERATOR_NAME;
  private globalKey: cryptoFramework.SymKey = null;

  /**
   * 構造函數初始化加解密環境、生成密鑰
   */
  constructor() {
    let symAlgName = CommonConstants.ENCRYPTION_MODE;
    // 創建對稱密鑰生成器
    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
    // 通過密鑰生成器和keyMaterialBlob生成256位長度的對稱密鑰
    let keyMaterialBlob = this.genKeyMaterialBlob(CommonConstants.KEY_DATA);
    symKeyGenerator.convertKey(keyMaterialBlob, (err, symKey) = > {
      if (err) {
        Logger.error(`Convert symKey failed, ${err.code}, ${err.message}`);
        return;
      }
      this.globalKey = symKey;
      let cipherAlgName = CommonConstants.GENERATOR_NAME;
      try {
        // 生成加解密生成器
        this.globalCipher = cryptoFramework.createCipher(cipherAlgName);
      } catch (error) {
        Logger.error(`createCipher failed, error is ${JSON.stringify(err)}`);
      }
    });
  }

  // 加密
  async encrypt(content: string, authTag: string): Promise< string > {
    ...
  }

  // 解密 
  async decrypt(content: string, authTag: string): Promise< string > {
    ...
  }
}

密碼加密

由于加密算法采用GCM分組模式,在加密前需要獲取GCM模式加解密所需的參數GcmParamsSpec。依次生成長度為12字節、8字節、16字節的DataBlob類型的數據,并封裝成GcmParamsSpec對象。

// AesUtil.ets
class AesUtil {
  ...
  /**
   * 獲取GCM分組加解密所需的參數
   *
   * @returns 返回加密所需參數的promise實例
   */
  async genGcmParamsSpec(): Promise< cryptoFramework.GcmParamsSpec > {
    let ivBlob: cryptoFramework.DataBlob = this.genKeyMaterialBlob(CommonConstants.GCM_IV_DATA);
    let aadBlob: cryptoFramework.DataBlob = this.genKeyMaterialBlob(CommonConstants.GCM_AAD_DATA);
    let tagBlob: cryptoFramework.DataBlob = this.genKeyMaterialBlob(CommonConstants.GCM_TAG_DATA);
    let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {
      iv: ivBlob,
      aad: aadBlob,
      authTag: tagBlob,
      algName: `GcmParamsSpec`
    };
    return gcmParamsSpec;
  }

  /**
   * 根據數據組生成DataBlob類型的數據
   *
   * @param data 需要封裝的數據
   * @returns Blob DataBlob類型的數據
   */
  genKeyMaterialBlob(data: Array< number >): cryptoFramework.DataBlob {
    let keyMaterial = new Uint8Array(data);
    return { data: keyMaterial };
  }
}

在AesUtil.ets的encrypt方法中實現密碼加密邏輯。由于本示例加密數據量較小,所以這里直接使用update一步完成加密操作。若數據量較大,可通過update方法分段加密。主要實現以下步驟:

  1. 調用Cipher的init方法初始化加密環境。設置mode為ENCRYPT_MODE,傳入密鑰和生成的gcmParams。
  2. 將用戶輸入的密碼轉換為Uint8Array數組,進而封裝成DataBlob對象。
  3. 將封裝好的plainTextBlob傳入update方法中完成加密。
  4. 調用doFinal方法,傳入null,取出加密后的認證信息authTag。
  5. 取出Uint8Array類型的加密數據和authTag,轉換成Base64類型的字符串,封裝成User類型返回。
// AesUtil.ets
class AesUtil {
  ...
  /**
   * 加密
   *
   * @param content 加密內容
   * @returns 返回攜帶密文User對象的promise實例
   */
  async encrypt(content: string): Promise< User > {
    // 初始化加密環境
    let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
    let gcmParams = await this.genGcmParamsSpec();
    await this.globalCipher.init(mode, this.globalKey, gcmParams);
    let plainTextBlob = {
      // 字符串轉Uint8Array
      data: DataTransformUtil.stringToUint8Array(content)
    };
    // 加密
    let updateOutput: cryptoFramework.DataBlob = await this.globalCipher.update(plainTextBlob);
    if (!updateOutput) {
      return Promise.reject('encrypt updateOutput is null');
    }
    let authTag: cryptoFramework.DataBlob = await this.globalCipher.doFinal(null);
    // Uint8Array轉base64
    let encryptContent: string = DataTransformUtil.uint8ArrayToBase64(updateOutput.data);
    let authTagContent: string = DataTransformUtil.uint8ArrayToBase64(authTag.data);
    let user = new User(null, ``, encryptContent, authTagContent);
    return user;
  }
}

密碼解密

解密操作與加密類似,主要實現以下步驟:

  1. 調用Cipher的init方法初始化解密環境,設置mode為DECRYPT_MODE,傳入攜帶authTag認證信息的gcmParams。
  2. 將Base64類型密文轉換為Uint8Array數組,進而封裝成DataBlob對象。
  3. 將封裝好的plainTextBlob傳入doFinal方法中完成解密。
  4. 取出Uint8Array類型的解密數據,轉換成字符串并返回。
// AesUtil.ets
class AesUtil {
  ...

  /**
   * 解密
   *
   * @param content 解密內容
   * @param authTag GCM 解密所需認證信息內容
   * @returns 返回解密內容的promise實例
   */
  async decrypt(content: string, authTag: string): Promise< string > {
    // 初始化解密環境
    let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
    let gcmParams = await this.genGcmParamsSpec();
    let authTagBlob: cryptoFramework.DataBlob = {
      data: DataTransformUtil.base64ToUint8Array(authTag)
    };
    gcmParams.authTag = authTagBlob;
    await this.globalCipher.init(mode, this.globalKey, gcmParams);
    let plainTextBlob: cryptoFramework.DataBlob = {
      // base64轉Uint8Array
      data: DataTransformUtil.base64ToUint8Array(content)
    };
    // 解密
    let finalOutput: cryptoFramework.DataBlob = await this.globalCipher.doFinal(plainTextBlob);
    if (!finalOutput) {
      return Promise.reject('decrypt finalOutput is null');
    }
    // Uint8Array轉字符串
    let decryptContent = DataTransformUtil.uint8ArrayToString(finalOutput.data);
    return decryptContent;
  }
}

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 字符串
    +關注

    關注

    1

    文章

    578

    瀏覽量

    20508
  • 鴻蒙
    +關注

    關注

    57

    文章

    2339

    瀏覽量

    42811
  • HarmonyOS
    +關注

    關注

    79

    文章

    1973

    瀏覽量

    30143
  • OpenHarmony
    +關注

    關注

    25

    文章

    3713

    瀏覽量

    16256
收藏 人收藏

    評論

    相關推薦

    十六進制字符串AES是如何分組的?

    文章目錄產生的疑問十六進制字符串AES是如何分組的?AES是目前最流行的分組對稱加密算法,在開發的過程中,無處不在。Intel甚至在他們的芯片中定制了底層指令來讓AES更快地執行,所以AES加解密
    發表于 07-22 08:25

    字符串的表示

    字符串的表示  隨著計算機在文字處理與信息管理中的廣泛應用, 字符串已成為最常用的數據類型之一, 許多計算機中都提供字符串操作功能, 一些計算機還給出讀寫字
    發表于 10-13 17:11 ?3065次閱讀
    <b class='flag-5'>字符串</b>的表示

    C語言教程之字符串加密和解密

    C語言教程之字符串加密和解密,很好的C語言資料,快來學習吧。
    發表于 04-25 15:49 ?0次下載

    python字符串拼接方式了解

    python字符串拼接的方式 在Python的實際開發中,很多都需要用到字符串拼接,python中字符串拼接有很多,今天總結一下: 用+符號拼接 用%符號拼接 用join()方法拼接
    發表于 12-06 10:09 ?1032次閱讀

    什么是復制字符串?Python如何復制字符串

    連續幾篇文章都在寫 Python 字符串,這出乎我的意料了。但是,有的問題,不寫不行,特別是那種靈機一動想到的問題,最后你發現,很多人根本不懂卻又誤以為自己懂了。那就繼續刨根問底,探究個明白吧
    發表于 11-25 10:32 ?3011次閱讀

    strtok拆分字符串

    大家好,我是驚覺,今天聊聊字符串字符串的使用場景非常之多,人機交互和雙機通信都會用到。比如:通過串口向單片機發送指令,以執行操作或配置參數。單片機讀取傳感器數據,數據格式是字符串。一般GPS數據
    發表于 01-13 15:46 ?8次下載
    strtok拆分<b class='flag-5'>字符串</b>

    字符串函數重寫練習

    字符串函數重寫練習:字符串比較、字符串拼接、字符串查找、字符串拷貝、內存比較、內存拷貝、內存初始化、內存比較、二維數組定義及基本使用、位運算
    的頭像 發表于 05-05 15:02 ?1991次閱讀

    字符串操作

    labview字符串操作
    發表于 06-28 15:09 ?2次下載

    C語言總結_字符串全方位練習

    C語言字符串全方位練習,涉及知識點:字符串解析、大小寫判斷、字符串插入、字符串刪除、字符串排序、字符串
    的頭像 發表于 08-14 09:41 ?1486次閱讀

    一文詳解JavaScript字符串

    JavaScript字符串是原始值。此外,字符串是不可變的。這意味著如果你修改一個字符串,你總是會得到一個新的字符串。原始字符串不會被改變。
    的頭像 發表于 12-08 16:36 ?1196次閱讀

    python字符串有哪些特定方法

    python字符串序列操作也適用于列表和元組。 python字符串還有獨有方法,即字符串對象的函數,其他對象不可調用,只有字符串對象可調用。
    的頭像 發表于 02-23 15:02 ?703次閱讀

    C語言字符串的引用方式

    在C語言程序中,字符串是存放在字符數組中的。 2. 用字符數組存放一個字符串,可以通過數組名和下標引用字符串中的一個
    的頭像 發表于 03-10 14:57 ?1912次閱讀

    字符串的相關知識

    TCL 中的數據類型只有一種:字符串。這些字符串可以是字母、數字、布爾值、標點符號等特殊字符的組合。在某些特殊命令的作用下,字符串可以向其他數據類型轉換。下面將系統的講解或回顧下
    的頭像 發表于 03-29 11:41 ?1146次閱讀

    labview掃描字符串怎么用

    LabVIEW 是一種流程化編程語言和開發環境,主要用于控制、測量和監測系統。在 LabVIEW 中,掃描字符串是一項常見的任務,它允許用戶按照一定的模式從輸入字符串中提取所需的信息。下面我將詳細
    的頭像 發表于 12-29 10:12 ?1980次閱讀

    labview字符串如何轉換為16進制字符串

    在LabVIEW中,將字符串轉換為16進制字符串是一個常見的需求,尤其是在處理數據通信和硬件接口時。LabVIEW提供了多種方法來實現這一轉換,包括使用內置函數、編寫VI(Virtual
    的頭像 發表于 09-04 15:54 ?2308次閱讀
    主站蜘蛛池模板: 一个人免费观看完整视频日本| 精品人伦一区二区三区潘金莲 | 后式大肥臀国产在线| 7723手机游戏破解版下载| 无人区在线日本高清免费| 暖暖免费观看日本在线视频| 国产精品成人影院| 日日操天天操夜夜操| 亚洲精品福利在线| 99热久久这里只有精品| 国产成人综合95精品视频免费| 曰产无码久久久久久精品| 色色色999| 欧美人禽Zozo动人物杂交| 久久久中日AB精品综合| 国产人妻麻豆蜜桃色| 陈红下面又紧又小好爽| 最美白虎逼| 夜色女人香| 性生大片免费看| 色中色成人论坛| 青娱乐在线一区| 女人会操出水图| 麻豆国产原创中文AV网站| 精品无码一区二区三区不卡 | 精品粉嫩BBWBBZBBW| 国产精品永久AV无码视频| 成人免费观看www视频| 99re精品视频在线播放视频| 又亲又揉摸下面视频免费看| 亚洲免费人成 久久| 伊人在线视频| 国产亚洲视频在线观看| 成人网18免费韩国| YY600800新视觉理论私人| av天堂网站avtt2017| 99精品国产免费久久久久久下载 | 国产国拍精品AV在线观看| 冰山高冷受被c到哭np双性| babesvideos性欧美| a在线观看免费视频|