目录

Secure Image Compression and Cropping

Use Cases

In the secure image compression and cropping scenario, you can create an attestation key and initialize an attestation session to compress, crop, and re-sign the image data obtained from the camera in secure mode. This helps reduce the size of the original image captured by the camera in secure mode while ensuring the authenticity and integrity of the image data.

Constraints

This feature requires that the device supports the secure camera mode. So the devices supported by this feature are the same as those supported by the image security verification feature. You can refer to the Constraints section of the secure camera mode to determine whether a device supports the secure camera mode.

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.
procSecImageTransform(srcSecImage: ArrayBuffer, Options: SecImageProcOptions): Promise<SecImageBuffer> Compresses and crops a secure image.

Development Procedure

  1. Import the trustedAppService module and dependent modules.

    import { trustedAppService } from '@kit.DeviceSecurityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import hilog from '@ohos.hilog';
    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    import { util } from '@kit.ArkTS';
    import { cert } from '@kit.DeviceCertificateKit';
  2. Obtain a secure image by referring to Image Security Verification.

  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.

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

    • Create an attestation key for secure image compression and cropping:
      private async creatSecureImageProcAttestKey(): 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 secure image compression and cropping:
      private async initSecureImageProcAttestContext(): Promise<number> {
        try {
          // Parameters for initializing an attestation session.
          const deviceId = 0;
          const initProperties: Array<trustedAppService.AttestParam> = [
            {
              tag: trustedAppService.AttestTag.ATTEST_TAG_DEVICE_TYPE,
              value: trustedAppService.AttestType.ATTEST_TYPE_SECIMAGE_PROCESS
            },
            {
              tag: trustedAppService.AttestTag.ATTEST_TAG_DEVICE_ID,
              value: BigInt(deviceId) // This parameter does not take effect in the secure image compression and cropping scenario.
            }
          ];
          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}, errMsg: ${businessError.message}`);
          const finalNumericCode = Number(String(businessError.code ?? '').replace('n', '').trim());
          return Number.isNaN(finalNumericCode) ? -1 : finalNumericCode;
        }
      }
  4. Send a request to compress and crop the secure image.

    • Image compression:

      private async procSecImageCompression(compressQuality: number, srcSecureImage: ArrayBuffer): Promise<ArrayBuffer> {
        try {
          let properties: Array<trustedAppService.SecImageProcParams> = [
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_PROC_OPERATION,
              value: trustedAppService.SecImageProcOperation.SECIMAGE_COMPRESSION,
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_SRC_IMAGE_FORMAT,
              value: trustedAppService.SecImageProcFormat.SECIMAGE_FORMAT_YUV_NV21, // The input image format is YUV420 NV21 for both the secure image compression and cropping commands.
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_DEST_IMAGE_FORMAT,
              value: trustedAppService.SecImageProcFormat.SECIMAGE_FORMAT_JPEG, // The image format returned by the secure image compression command is JPEG.
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_COMPRESSION_QUALITY,
              value: compressQuality, // Replace it with the compression quality required by the service scenario.
            },
          ];
          const procParams: trustedAppService.SecImageProcParamsArray = {
            properties: properties
          };
          // srcSecureImage: Replace it with the secure image buffer obtained from Camera Engine.
          return (await trustedAppService.procSecImageTransform(srcSecureImage, procParams)).secImage;
        } catch (err) {
          const businessError = err as BusinessError;
          hilog.error(0x0000, 'TrustedAppService',
            `procSecImageTransform failed, code: ${businessError.code}, msg: ${businessError.message}`);
          throw new Error(businessError.message);
        }
      }
    • Image cropping:

      private async procSecImageCropping(cropRegion: trustedAppService.CropRegion,
        srcSecureImage: ArrayBuffer): Promise<ArrayBuffer> {
        try {
          let properties: Array<trustedAppService.SecImageProcParams> = [
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_PROC_OPERATION,
              value: trustedAppService.SecImageProcOperation.SECIMAGE_CROPPING,
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_SRC_IMAGE_FORMAT,
              value: trustedAppService.SecImageProcFormat.SECIMAGE_FORMAT_YUV_NV21, // The input image format is YUV420 NV21 for both the secure image compression and cropping commands.
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_DEST_IMAGE_FORMAT,
              value: trustedAppService.SecImageProcFormat.SECIMAGE_FORMAT_YUV_NV21, // The image format returned by the secure image cropping command is YUV420 NV21.
            },
            {
              tag: trustedAppService.SecImageProcTag.SECIMAGE_TAG_CROP_REGION,
              value: {
                // Replace it with the cropping area range required by the service scenario.
                x: cropRegion.x,
                y: cropRegion.y,
                width: cropRegion.width,
                height: cropRegion.height
              },
            },
          ];
          let procParams: trustedAppService.SecImageProcParamsArray = {
            properties: properties,
          };
          // srcSecureImage: Replace it with the secure image buffer obtained from Camera Engine.
          return (await trustedAppService.procSecImageTransform(srcSecureImage, procParams)).secImage;
        } catch (err) {
          const businessError = err as BusinessError;
          hilog.error(0x0000, 'TrustedAppService',
            `procSecImageTransform failed, code: ${businessError.code}, msg: ${businessError.message}`);
          throw new Error(businessError.message);
        }
      }
  5. End the attestation session.

    private async finalizeSecureImageProcAttestContext(): 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_SECIMAGE_PROCESS
        }
      ];
      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.