• # 鸿蒙ArkTS Api9 AES ECB 加密


    鸿蒙ArkTS Api9 AES ECB 加密

    由于鸿蒙ArkTS是javascript编写的,因此总是感觉会被抓包破解了,不过这个问题通过提了个工单问了一下,目前鸿蒙编译完成之后的包是无法获取到其内部代码的。因此就能够放心的把加密的密钥给扔在里边了。
    所以研究了一下目前的鸿蒙加密算法怎么实现。
    以下以 AES 128位 ECB 模式 加密为例。
    密钥不足的时候以 0x00 填充。

    加解密算法库框架

    加解密算法库框架开发指导

    参考文档

    加密部分

    结合当前鸿蒙的编码方式,代码流程如下:

    1. 转换可用密钥
    2. 根据密钥生成加密器
    3. 加密

    整体代码如下:

    import cryptoFramework from '@ohos.security.cryptoFramework';
    import util from '@ohos.util';
    
    // 把密钥、明文等转换成输入数据需要的格式
    function stringToUint8Array(str, len=null) {
      let arr = [];
      if (len == null) {
        len = str.length
      }
      for (let i = 0; i < len; i++) {
        if (str.length > i) {
          arr.push(str.charCodeAt(i))
        } else {
          arr.push(0)
        }
      }
      return new Uint8Array(arr);
    }
    
    // promise形式调用
    function aesECBEncrypt(plaintext, key) {
      let cipherAlgName = 'AES128|ECB|PKCS7';
      let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128')
    
      var cipher;
    
      // 生成密钥
      return symKeyGenerator.convertKey({
        data: stringToUint8Array(key, 16)
      }).then(symKey => {
        // 创建加密器
        try {
          cipher = cryptoFramework.createCipher(cipherAlgName);
          console.info(`xx cipher algName: ${cipher.algName}`);
        } catch (error) {
          console.error(`xx createCipher failed, ${error.code}, ${error.message}`);
          return null
        }
        // 初始化加密器
        return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null)
          .then(() => {
            // 开始加密
            return cipher.doFinal({
              data: stringToUint8Array(plaintext)
            })
          })
          .then(output => {
            let base64 = new util.Base64Helper();
            let result = base64.encodeToStringSync(output.data);
            return new Promise((resolve) => {
              resolve(result)
            })
          }).catch(err => {
            return new Promise((_, reject) => {
              reject(err)
            })
          })
      }).catch(err => {
        return new Promise((_, reject) => {
          reject(err)
        })
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    调用方式:

    aesECBEncrypt('000','1111').then(res=>{
      console.log('aesECBEncrypt is ' + res)
    }).catch(err => {
      console.log('aesECBEncrypt catch ' + err)
    })
    
    // ===> v0ADs4+sKsM2FOdqz9rCQw==
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    解密部分

    结合当前鸿蒙的编码方式,代码流程如下:

    1. 转换可用密钥
    2. 根据密钥生成加密器
    3. 解密

    整体代码如下:

    import cryptoFramework from '@ohos.security.cryptoFramework';
    import util from '@ohos.util';
    
    // 解密内容转换成字符串
    function uint8ArrayToString(array) {
      let arrayString = '';
      for (let i = 0; i < array.length; i++) {
        arrayString += String.fromCharCode(array[i]);
      }
      return arrayString;
    }
    
    function aesECBDecrypt(encrypttext, key) {
      let cipherAlgName = 'AES128|ECB|PKCS7';
      let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128')
    
      var cipher;
    
      return symKeyGenerator.convertKey({
        data: stringToUint8Array(key, 16)
      }).then(symKey => {
        try {
          cipher = cryptoFramework.createCipher(cipherAlgName);
          console.info(`xx cipher algName: ${cipher.algName}`);
        } catch (error) {
          console.error(`xx createCipher failed, ${error.code}, ${error.message}`);
          return null
        }
        return cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null)
          .then(() => {
            let base64 = new util.Base64Helper();
            let result = base64.decodeSync(encrypttext);
            return cipher.doFinal({
              data: result
            })
          })
          .then(output => {
            let result = uint8ArrayToString(output.data)
            return new Promise((resolve) => {
              resolve(result)
            })
          }).catch(err => {
            return new Promise((_, reject) => {
              reject(err)
            })
          })
      }).catch(err => {
        return new Promise((_, reject) => {
          reject(err)
        })
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    调用方式如下:

    aesECBDecrypt('v0ADs4+sKsM2FOdqz9rCQw==','1111').then(res=>{
      console.log('aesECBDecrypt is ' + res)
    }).catch(err => {
      console.log('aesECBDecrypt catch ' + err)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    行所当行@背包扔过墙
    一文了解Nginx及其基本配置
    大学时光仅四年,疫情反反复复占几年
    基于51单片机八路电压表采集系统波形发生器
    ionic+vue+capacitor系列笔记--常用操作代码合集(图片引用,axios跨域配置,去除按钮波纹)
    Android 11源码——驱动设备节点的权限问题
    ELK日志分析系统的详细介绍与部署
    数据结构--字典树(trie)
    Spring的xml配置和Java配置
    【RocketMQ】消息的存储总结
  • 原文地址:https://blog.csdn.net/xo19882011/article/details/133879750