# 系统安全性检测

#### 问题现象

当前使用系统安全性检测的日志结果并不符合接口文档预期，另外，是否可以在客户端解析JWS？

#### 背景知识

系统完整性检测：应用通过调用Device Security Kit的checkSysIntegrity接口获取系统完整性检测结果，用于判断设备环境是否安全，比如是否被越狱、被模拟等。

#### 问题定位

根据系统完整性检测开发步骤打印result，日志格式如下：\*\*\*\*\*\*.\*\*\*\*\*\*\*\*\*，复现问题。对日志内容进行Base64解码，结果为Header的一部分。

#### 分析结论

由于日志打印长度有限，result内容被日志截断，所以日志里面的result确实不符合预期，但是可以直接对result进行解析，符合官网结果预期。

#### 修改建议

直接对返回结果进行解析，分段打印，可以避免日志内容被截断。以下为客户端直接解析JWS的核心判断逻辑，可根据需求添加相应的业务代码：

```
import { safetyDetect } from '@kit.DeviceSecurityKit';
import { BusinessError } from '@ohos.base';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { JSON, util } from '@kit.ArkTS';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';

let base64 = new util.Base64Helper();
const TAG = 'SafetyDetectJsTest';

class Payload {
  hapCertificateSha256: string = '';
  hapBundleName: string = '';
  appId: string = '';
  basicIntegrity: boolean = false;
  nonce: boolean = false;
  timestamp: number = 0;
  detail: Array<string> = [];
}

function checkSysIntegrityPromise(): Promise<String> {
  return new Promise(async (resolve, reject) => {
    let strLen: number = 16;
    let srcStr: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefhijklmnopqrstuvwxyz0123456789';
    let randomStr: string = '';
    let rand = cryptoFramework.createRandom();
    for (let i = 0; i < strLen; i++) {
      let randData = rand.generateRandomSync(1);
      randomStr += srcStr.charAt(Math.floor(randData.data[0] * srcStr.length / 255));
    }
    let sysIntegrityRequest: safetyDetect.SysIntegrityRequest = {
      nonce: randomStr
    };
    try {
      hilog.info(0x0000, TAG, 'CheckSysIntegrity begin.');
      let sysIntegrityResponse: safetyDetect.SysIntegrityResponse =
        await safetyDetect.checkSysIntegrity(sysIntegrityRequest);
      let result: string = sysIntegrityResponse.result;
      resolve(result);
      hilog.info(0x0000, TAG, 'Succeeded in checkSysIntegrity: %{public}s', result);
    } catch (err) {
      hilog.error(0x0000, TAG, 'CheckSysIntegrity failed: %{public}d %{public}s', err.code, err.message);
      reject(err);
    }
  });
}

async function analysis(): Promise<boolean> {
  // 请求系统完整性检测，并处理结果
  let ret = false;
  await checkSysIntegrityPromise().then((result) => {
    let resultArray: string[] = result.split('.');

    // 解析JWS，获取header、payload、signature。
    let headerUint = base64.decodeSync(resultArray[0], util.Type.BASIC_URL_SAFE);
    let decoder = util.TextDecoder.create('utf-8');
    let headerStr = decoder.decodeToString(headerUint);
    hilog.info(0x0000, TAG, 'analysis Succeeded in Header: %{public}s', headerStr);

    let payloadUint = base64.decodeSync(resultArray[1], util.Type.BASIC_URL_SAFE);
    let payloadStr = decoder.decodeToString(payloadUint);
    hilog.info(0x0000, TAG, 'analysis Succeeded in Payload: %{public}s', payloadStr);
    let payload: Payload = JSON.parse(payloadStr) as Payload;
    ret = payload.basicIntegrity;

    let signatureUint = base64.decodeSync(resultArray[2], util.Type.BASIC_URL_SAFE);
    let signatureStr = decoder.decodeToString(signatureUint);
    hilog.info(0x0000, TAG, 'analysis Succeeded in Signature: %{public}s', signatureStr);

  }).catch((err: BusinessError) => {
    ret = false;
    hilog.error(0x0000, TAG, 'analysis failed: %{public}d %{public}s', err.code, err.message);
  });
  return ret;
}

@Entry
@Component
struct Index {
  build() {
    RelativeContainer() {
      Button('检测系统完整性')
        .onClick(async () => {
          let ret = await analysis();
          hilog.info(0x0000, TAG, 'Succeeded in Signature: %{public}s', ret);
        });
    }
    .height('100%')
    .width('100%');
  }
}
```

其中result为eyAgICAiYW\*\*.\*\*.\*Jxse，split分离三段数据后可解析出Header（头部），Payload（负载），Signature（签名）。

#### 总结

发现日志过长时可考虑日志不全的情况。