【harmonyOS】TOTP 實現

七夜i發表於2024-03-12

鴻蒙TOTP 實現:

import cryptoFramework from '@ohos.security.cryptoFramework';
import { util } from '@kit.ArkTS';

export class HmacSHA1{

  static async hmacSHA1(data: string, secret: string): Promise<Uint8Array> {
    let mac = cryptoFramework.createMac("SHA1")
    let key_data = new util.TextEncoder().encodeInto(secret);
    let symKey = await cryptoFramework.createSymKeyGenerator("HMAC").convertKey({ data: key_data })
    await mac.init(symKey)
    await mac.update({ data: new util.Base64Helper().decodeSync(data)})
    let result = await mac.doFinal()
    return result.data
  }
}
import { buffer, util } from '@kit.ArkTS';
import { HmacSHA1 } from './HmacSHA1';
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG = '[TotpGenerator]';

export class TotpGenerator{
  //步長 1800 s
  private static STEP:number = 1800;
  // totp code 長度 8, 如果需要六位,可以改成 6
  private static TOTP_SIZE:number = 8;

  static async generate(key:string): Promise<string>{
    let t = Date.now() / 1000 / TotpGenerator.STEP;
    try {
      let buff = buffer.alloc(8);
      buff.writeBigInt64BE(BigInt(Math.floor(t)));
      let data:Uint8Array = new Uint8Array(buff.buffer);
      const hmacData = await HmacSHA1.hmacSHA1(new util.Base64Helper().encodeToStringSync(data),key);
      const offset = hmacData[hmacData.length - 1] & 0x0f;
      const binCode = (hmacData[offset] & 0x7f) << 24
        | (hmacData[offset + 1] & 0xff) << 16
        | (hmacData[offset + 2] & 0xff) << 8
        | (hmacData[offset + 3] & 0xff);

      const code = String(binCode);
      const startIndex = ((code.length - TotpGenerator.TOTP_SIZE) < 0) ? 0 : (code.length - TotpGenerator.TOTP_SIZE);
      return code.substring(startIndex);
    } catch (e) {
      hilog.warn(0x0000, TAG, '%{public}s', "generate error:" + e);
    }
    return ""
  }
}

相關文章