2

HarmonyOS门锁品类的临时密码、照片编解码工具技术

 1 year ago
source link: https://os.51cto.com/article/712714.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
e49362039acef587d8435991360c9b558e3363.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

随着智能家居的普及,方便快捷的智能门锁受到广大消费者的欢迎,成为家居应用领域的一大热门。在接入鸿蒙智联智能门锁领域时,我们的技术人员发现用户在通过手机给智能门锁设置临时密码,APP给门锁下发加密后的密码时,设备固件目前尚无与之对应的解密工具,并且智能门锁都具备拍照功能用于保存异常情况的现场照片,所用模组无法直接将照片发送到三方服务保存,这些还处于空白技术领域。

技术人员通过了解行业情况,查阅大量相关技术资料,自研出专用的解密工具,成功实现了临时密码设置功能;自研出照片编解码工具,利用智能家居云作为中转,实现了手机App照片实时查看功能。接下来我们看所述技术难点是如何实现的。

部分截图展示:

#夏日挑战赛#HarmonyOS门锁品类的临时密码、照片编解码工具技术-开源基础软件社区

一、临时密码设置流程

#夏日挑战赛#HarmonyOS门锁品类的临时密码、照片编解码工具技术-开源基础软件社区

流程说明:

1.智慧生活APP生成临时密码发送到智能家居云保存,APP加密算法采用RSA的PKSC8加密算法。

2.智能家居云下发密文给门锁设备。

3.门锁解密密文,获取临时密码、有效时间,然后保存到锁内,临时密码有效时间最长为7天,最短为30分钟。

4.临时密码设备设置成功,门锁主动上报设置成功状态。

5.智能家居云收到状态后转发状态给APP。

H5代码实现片段:

data() {
    return {
      TemporarypasswordObj: {
        Creationtime: '',
        action: '1',
        id: '001',
        sixteenbitSN: '',
        userpassword: '123456', // 管理员密码        
        Temporarypassword: '888888', // 临时密码
        Availabletime: '', // 使用次数
        effectivedate: '',
        Failuretime: ''
      },
      publicKey: '',
    }
  },
  methods: {
      saveTemporaryPassword()  {
      // 构建密码hash数据字符串
      let hashedData = this.TemporarypasswordObj.sixteenbitSN + 
                       this.TemporarypasswordObj.userpassword + 
                       this.TemporarypasswordObj.Creationtime    
      // 进行哈希混淆
      let hashedDatastr = window.hilink.sha256Encrypt(hashedData)    
      // 构建临时密码密文
      let encryptionstringstr =
        this.TemporarypasswordObj.Creationtime +
        this.TemporarypasswordObj.action +
        this.TemporarypasswordObj.id +
        hashedDatastr +
        this.TemporarypasswordObj.Temporarypassword +
        this.TemporarypasswordObj.Availabletime +
        this.TemporarypasswordObj.effectivedate +
        this.TemporarypasswordObj.Failuretime      
      // 调用hilink接口进行RSA加密
      let cipherText = window.hilink.rsaEncrypt(encryptionstringstr, this.publicKey)    
      // 发送临时密码
      this.sendCiphertext(cipherText)
    },
    sendCiphertext(cipherText) {
      try {
        let data = { remoteCode: { cipherText: cipherText } }
        window.hilink.setDeviceInfo('0', JSON.stringify(data), 'setInfocallback');
        window.setInfocallback = res => {
          let data = JSON.parse(res);
          if (data.errcode === 0) {
            console.log('临时密码发送成功');
          } else {
            console.log('临时密码发送失败');
          }
        }
      } catch (e) {
        console.log(e)
      }
    }
  }
}

固件代码片段:

{
    int ret;
    size_t olen = 0;
    size_t dec_len = 0;
    const char *pers = "simple_rsa";
    unsigned char *base_dec = NULL;
    mbedtls_rsa_context rsa;
    mbedtls_rsa_context tempctx;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);  // 初始化RSA结构体
    mbedtls_rsa_init(&tempctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);  // 初始化RSA结构体
    mbedtls_entropy_init(&entropy);         // 初始化熵结构体
    mbedtls_ctr_drbg_init(&ctr_drbg);       // 初始化随机数结构体
    ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
                                    (const uint8_t *) pers, strlen(pers));  // 根据个性化字符串更新种子1
    assert_exit(ret == 0, ret);
    base_dec = rsa_global_hooks.rsa_allocate(BASE_DEC_LEN);
    if(base_dec == NULL){
        rsa_print_dbg("malloc base64 buff failed \r\n");
        goto err_exit;
    }
    memset(base_dec,0,BASE_DEC_LEN);
    ret = smartlock_rsa_readkeys(&tempctx);
    assert_exit(ret == 0, ret);
    ret = mbedtls_rsa_import( &rsa, &tempctx.N, &tempctx.P, &tempctx.Q, &tempctx.D, &tempctx.E);
    assert_exit(ret == 0, ret);
    ret = mbedtls_rsa_complete( &rsa );
    assert_exit(ret == 0, ret);
    mbedtls_base64_decode(base_dec,BASE_DEC_LEN,&dec_len,pchipertext,chiperlen);
    ret = mbedtls_rsa_pkcs1_decrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
                                MBEDTLS_RSA_PRIVATE, &olen, base_dec, text, textlen);
    assert_exit(ret == 0, ret);
    text[olen] = 0;
    rsa_global_hooks.rsa_deallocate(base_dec);
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    mbedtls_rsa_free(&tempctx);
    mbedtls_rsa_free(&rsa);
    return 0;
err_exit:
    rsa_global_hooks.rsa_deallocate(base_dec);
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    mbedtls_rsa_free(&tempctx);
    mbedtls_rsa_free(&rsa);
    return -1;
}

二、照片上报展示

由于门锁模组无法将图片上报到三方服务器,只能利用智能家居云进行中转,而智能家居云profile字符串类型有长度限制,因此需要将数据拆包后分包发送,APP在收到数据后进行数据包合并,最后完成图片显示。

工作流程:

#夏日挑战赛#HarmonyOS门锁品类的临时密码、照片编解码工具技术-开源基础软件社区

代码实现片段:

<img :src="picSrc" width="400" height="300" />
</template>
<script>
export default {
  data() {
    return {
      picSrc: '',
      picBase64: '',
      index: 0,
    }
  },
  created() {
    this.deviceEvent()
  },
  method: {
    deviceEvent() {
      try {
        window.deviceEventCallback = event => {
          let eventJson = JSON.parse(event)
          if (eventJson.sid.indexOf('imagePack') > -1) {
            this.picBase64 += eventJson.data['image']
            this.index ++
          }
          if (this.index === 6) {
            this.picSrc = 'data:image/jpg;base64,' + this.picBase64
          }
        }
      } catch (e) {
        console.log(e)
      }
    }
  },
}
</script>

以上为智能门锁的解决方案,该方案已转化为鸿蒙智联标准化认证,可广泛应用于门锁、保险箱等产品。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK