安全相机(ArkTS)
===========

安全相机主要为银行等有活体检测等安全诉求的应用提供，安全相机的使用需要加密算法框架及可信应用服务。

应用具体使用步骤如下：

*   通过Camera Kit打开安全摄像头，成功打开安全摄像头后，Camera Kit会返回给应用一个**安全摄像头序列号**。
*   通过[Device Security Kit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/devicesecurity-introduction)来创建证明密钥（安全摄像头序列号会作为入参）、初始化证明会话。Device Security Kit初始化证明会话完成后会返回给应用**匿名证书链**。
*   通过Camera Kit配置安全相机输入输出流，重点是配置**安全数据流**，注册安全数据流每帧安全图像回调监听。
*   解析安全数据流每帧安全图像，在服务器侧完成安全图像的签名验证。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/7d/v3/8qHdbIRKTPGrL7-MHcXXlg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073515Z&HW-CC-Expire=86400&HW-CC-Sign=2BC58A5399EF8C49892EBED95E003394185499BA7B0925A151FAF16F04AC7445)

当前文档主要说明通过Camera Kit完成的步骤，证明会话相关步骤需通过Device Security Kit完成，具体可参考[可信应用服务-安全摄像头](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/devicesecurity-taas-securecamera)。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6a/v3/ebFnSxzUSDypqo_6__BXug/zh-cn_image_0000002625108357.png?HW-CC-KV=V1&HW-CC-Date=20260612T073515Z&HW-CC-Expire=86400&HW-CC-Sign=B507E489A66EEDBF8800CFF47C34EE62F648DE28524817F69EB548AAB1A094D4)

#### 开发步骤

详细的API说明请参考[Camera API参考](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-camera)。

1.  导入依赖，需要导入相机框架相关领域依赖。
    
    import { camera } from '@kit.CameraKit';
    import { image } from '@kit.ImageKit';
    
2.  选择支持安全相机的设备。
    
    通过[CameraManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-cameramanager)中的[getSupportedSceneModes](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-cameramanager#getsupportedscenemodes11)方法，可以获取当前设备支持的所有模式，如果当前设备支持安全相机模式，即可使用该设备做后续安全相机操作。
    
    当前安全相机仅支持手机前置镜头。
    
    function isSecureCamera(cameraManager: camera.CameraManager, cameraDevice: camera.CameraDevice): boolean {
      let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(cameraDevice);
      const secureMode = sceneModes.find(mode => mode === camera.SceneMode.SECURE\_PHOTO);
      if (secureMode) {
        console.info('current device support secure camera!');
        return true;
      } else {
        console.info('current device not support secure camera!');
        return false;
      }
    }
    
    let secureCamera: camera.CameraDevice;
    
    function getSecureCamera(cameraManager: camera.CameraManager): void {
      let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
      for (let index = 0; index < cameraArray.length; index++) {
        if (isSecureCamera(cameraManager, cameraArray\[index\])) {
          secureCamera = cameraArray\[index\];
        }
      }
    }
    
3.  查询相机设备在安全模式下支持的输出能力。
    
    通过[CameraManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-cameramanager)的[getSupportedOutputCapability](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-cameramanager#getsupportedoutputcapability11)方法，可获取设备在安全模式下支持的输出能力。
    
    当前安全相机仅支持输出预览流，推荐预览流使用640 \* 480分辨率。
    
    function getSupportedOutputCapability(cameraManager: camera.CameraManager, secureCamera: camera.CameraDevice): void {
      let outputCap: camera.CameraOutputCapability =
        cameraManager.getSupportedOutputCapability(secureCamera, camera.SceneMode.SECURE\_PHOTO);
      let previewProfilesArray: Array<camera.Profile> = outputCap.previewProfiles;
    }
    
4.  创建设备输入输出。
    
    安全相机需要创建两路输出流：
    
    *   一路是普通的预览流，用于界面显示，普通预览流的创建流程请参考[预览开发指导](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/camera-preview)。
        
    *   一路是安全数据流，用于安全服务校验，安全数据流需要通过[image.createImageReceiver](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-f#imagecreateimagereceiver11)创建图像接收类[ImageReceiver](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-imagereceiver)，再通过其[getReceivingSurfaceId](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-imagereceiver#getreceivingsurfaceid9)方法获取surfaceId。
        
        ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d3/v3/1r8Jvw9MSaCps0kBRD8KPg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073515Z&HW-CC-Expire=86400&HW-CC-Sign=998A38B6946A9782D9F35D118586604BD6916788DF281751998879C01269EECB)
        
        安全数据流没有单独的数据类型，同属于预览流，输出能力与预览流保持一致，创建ImageReceiver仅支持JPEG格式。
        
    
    async function createInputAndOutputs(cameraManager: camera.CameraManager,
                                         secureCamera: camera.CameraDevice,
                                         previewProfile: camera.Profile,
                                         previewSurfaceId: string): Promise<void> {
      // 创建输入流
      let cameraInput: camera.CameraInput = cameraManager.createCameraInput(secureCamera);
      // 创建普通预览输出流
      let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfile, previewSurfaceId);
      // 创建安全数据输出流
      const receiver: image.ImageReceiver =
        image.createImageReceiver({ width: previewProfile.size.width, height: previewProfile.size.height },
                                  image.ImageFormat.JPEG, 8);
      const secureSurfaceId: string = await receiver.getReceivingSurfaceId();
      let secureOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfile, secureSurfaceId);
    }
    
5.  打开安全设备。
    
    [CameraInput](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-camerainput)提供了[open(isSecureEnabled)](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-camerainput#open12)方法用于打开安全相机并返回安全摄像头序列号，该序列号是安全模块创建证明会话的必需参数。
    
    仅当isSecureEnabled为true时，才会打开安全相机，并有安全序列号返回。
    
    async function openCamera(cameraInput: camera.CameraInput) {
      const seqId: bigint = await cameraInput.open(true);
    }
    
6.  使用Device Security Kit的能力，创建证明密钥、打开证明会话。请参考Device Security Kit（设备安全服务）的开发指导：[可信应用服务-安全摄像头](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/devicesecurity-taas-securecamera)。
    
7.  创建安全相机会话，配流启流。
    
    创建安全相机模式的会话，将输入流、输出流加入会话，需要将安全数据流通过[SecureSession](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-securesession)的[addSecureOutput](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-securesession#addsecureoutput12)方法标记成安全输出。
    
    async function openSession(cameraManager: camera.CameraManager,
                               cameraInput: camera.CameraInput,
                               previewOutput: camera.PreviewOutput,
                               secureOutput: camera.PreviewOutput): Promise<void> {
      try {
        let secureSession: camera.SecureSession = cameraManager.createSession(camera.SceneMode.SECURE\_PHOTO);
        if (secureSession === undefined) {
          console.error('create secureSession failed!');
        }
        secureSession.beginConfig();
        secureSession.addInput(cameraInput);
        secureSession.addOutput(previewOutput);
        secureSession.addOutput(secureOutput);
        secureSession.addSecureOutput(secureOutput); // 把secureOutput标记成安全输出
        await secureSession.commitConfig();
        await secureSession.start();
      } catch (err) {
        console.error('openSession failed!');
      }
    }
    
8.  安全模式会话正常启动后，预览流和安全数据流数据逐帧上报，安全数据流每帧数据可以通过[ImageReceiver](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-imagereceiver)注册[imageArrival](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-imagereceiver#on9)回调获取。
    
    function onBuffer(receiver: image.ImageReceiver): void {
      receiver.on('imageArrival', () => {
        // 从ImageReceiver读取下一张图片
        receiver.readNextImage().then((img: image.Image) => {
          // 从图像中获取组件缓存
          img.getComponent(image.ComponentType.JPEG).then((component: image.Component) => {
            // 安全数据流内容，应用通过解析该buffer内容完成签名认证
            const buffer = component.byteBuffer;
            console.info('Succeeded in getting component byteBuffer.');
          })
        })
      })
    }
    
    解析安全数据流每帧安全图像，在服务器侧完成安全图像的签名验证。
    
    如果有在端侧验证图像数据或地理位置数据签名的需求，可参考[验证签名](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/devicesecurity-taas-verifysignature)中与安全图像相关的部分。
    
9.  释放安全相机，使用[Session](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-session)的[release](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-camera-session#release11-1)方法。