目录

Image Security Verification

Use Cases

Image data captured by a camera in secure mode is signed by creating an attestation key and initializing an attestation session, to ensure authenticity and integrity of the image data.

Constraints

This feature requires that the device supports the secure camera mode.

You can call the getSupportedSceneModes method to check whether the current device supports the secure camera mode. If the return value is camera.SceneMode.SECURE_PHOTO, the device supports the secure camera mode. If other values are returned, the device does not support the secure camera mode. The following is an example:

private getSecureCameraDevice(cameraManager: camera.CameraManager): camera.CameraDevice {
  // Obtain the list of cameras supported by the device.
  const cameraDevices = cameraManager.getSupportedCameras();
  if (cameraDevices.length < 1) {
    throw new Error('no camera devices');
  }
  // Obtain the front camera object. Currently, the secure camera must be a front camera.
  const frontCamera: camera.CameraDevice | undefined = cameraDevices.find((profile: camera.CameraDevice) => {
    return profile.cameraPosition != camera.CameraPosition.CAMERA_POSITION_BACK;
  });
  if (frontCamera === undefined) {
    throw new Error('no front cameras');
  }
  // Check whether the front camera supports the secure camera mode. If yes, the front camera can be used for subsequent secure camera operations.
  const modes = cameraManager.getSupportedSceneModes(frontCamera);
  if (modes.indexOf(camera.SceneMode.SECURE_PHOTO) === -1) {
    throw new Error('current device not support secure camera');
  }
  return frontCamera;
}

Service Process

API Description

For details about the APIs and their usage, see API Reference.

API Description
createAttestKey(options: AttestOptions): Promise<void> Creates an attestation key.
initializeAttestContext(userData: string, options: AttestOptions): Promise<AttestReturnResult> Initializes an attestation session.
finalizeAttestContext(options: AttestOptions): Promise<void> Ends an attestation session.
destroyAttestKey(): Promise<void> Destroys an attestation key.

Development Procedure

  1. Import the camera module, trustedAppService module, and dependent modules.

    import { camera } from '@kit.CameraKit';
    import { trustedAppService } from '@kit.DeviceSecurityKit';
    import { image } from '@kit.ImageKit';
    import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
    import hilog from '@ohos.hilog';
    import { common } from '@kit.AbilityKit';
    import { util } from '@kit.ArkTS';
    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    import { cert } from '@kit.DeviceCertificateKit';
  2. Initialize the secure camera by referring to the secure camera development guide.

    You need to:

    • Select a camera that supports the secure mode.
    • Check the output capability supported by the camera in secure mode.
    • Create the input and output streams.
    • Turn on the camera in secure mode and obtain the device serial number.
  3. Create an attestation key and initialize an attestation session.

    • An attestation session can be initialized only after an attestation key is successfully created.

    • An attestation key is valid for seven days. To avoid repeated creation of attestation keys, you are advised to call the attestation session initialization API first. If the initialization fails, destroy and create the attestation key, and initialize the attestation key again.

    • The device serial number needs to be obtained each time the secure mode is enabled for a camera, and passed for initializing an attestation session for the camera in secure mode. In other scenarios, the value 0 can be passed.

    • When initializeAttestContext is called to initialize an attestation session, the value of userData must contain 16 to 127 bytes.

    • Create an attestation key for image security verification:

      private async creatSecureCameraAttestKey(): Promise<void> {
        // Parameters for creating an attestation key.
        const createProperties: Array<trustedAppService.AttestParam> = [
          {
            tag: trustedAppService.AttestTag.ATTEST_TAG_ALGORITHM,
            value: trustedAppService.AttestKeyAlg.ATTEST_ALG_ECC
          },
          {
            tag: trustedAppService.AttestTag.ATTEST_TAG_KEY_SIZE,
            value: trustedAppService.AttestKeySize.ATTEST_ECC_KEY_SIZE_256
          }
        ];
        const createOptions: trustedAppService.AttestOptions = {
          properties: createProperties
        };
        // Create an attestation key.
        try {
          await trustedAppService.createAttestKey(createOptions);
          hilog.info(0x0000, 'TrustedAppService', 'createAttestKey successfully');
        } catch (error) {
          const err = error as BusinessError;
          hilog.error(0x0000, 'trustedappservice', `createattestkey failed, errCode: ${err.code}, errMsg: ${err.message}`);
          throw new Error(err.message);
        }
      }
    • Initialize an attestation session for image security verification:

      private async initSecureCameraAttestContext(cameraInput: camera.CameraInput): Promise<number> {
        try {
          // Parameters for initializing an attestation session.
          const deviceId = await cameraInput.open(true);
          const initProperties: Array<trustedAppService.AttestParam> = [
            {
              tag: trustedAppService.AttestTag.ATTEST_TAG_DEVICE_TYPE,
              value: trustedAppService.AttestType.ATTEST_TYPE_CAMERA
            },
            {
              tag: trustedAppService.AttestTag.ATTEST_TAG_DEVICE_ID,
              value: BigInt(deviceId) // Obtain the actual value from Camera Kit.
            }
          ];
          const initOptions: trustedAppService.AttestOptions = {
            properties: initProperties
          };
          let userData = 'trusted_app_service_default_userdata'; // Example value. Generate a value on your own, which contains 16 to 127 bytes.
          // Initialize an attestation session.
          const certChainResult = await trustedAppService.initializeAttestContext(userData, initOptions);
          if (certChainResult.certChains.length < 1) {
            throw new Error('empty returned cert chain');
          }
          // ...
          return 0;
        } catch (err) {
          const businessError = err as BusinessError;
          hilog.error(0x0000, 'TrustedAppService',
            `initializeAttestContext failed. errCode: ${businessError.code}, message: ${businessError.message}`);
          const finalNumericCode = Number(String(businessError.code ?? '').replace('n', '').trim());
          return Number.isNaN(finalNumericCode) ? -1 : finalNumericCode;
        }
      }
  4. Create a secure camera session, configure the input and output streams, and start the preview stream and secure data stream by referring to the secure camera development guide.

  5. End the attestation session.

    private async finalizeSecureCameraAttestContext(): Promise<void> {
      // Parameters for ending the attestation session.
      const finalProperties: Array<trustedAppService.AttestParam> = [
        {
          tag: trustedAppService.AttestTag.ATTEST_TAG_DEVICE_TYPE,
          value: trustedAppService.AttestType.ATTEST_TYPE_CAMERA
        }
      ];
      const finalOptions: trustedAppService.AttestOptions = {
        properties: finalProperties,
      };
      // End the attestation session.
      try {
        await trustedAppService.finalizeAttestContext(finalOptions);
      } catch (err) {
        const error = err as BusinessError;
        hilog.error(0x0000, 'TrustedAppService',
          'Failed to finalize attest context, code:${error.code}, message:${error.message}');
      }
    }

    To destroy an attestation key, call the destroyAttestKey API after the attestation session ends. Image security verification, location security verification, and secure image compression and cropping share the same attestation key. Before destroying an attestation key, ensure that the other functions are not using the attestation key.