HarmonyOS 可信应用服务:让你的应用拍照和定位更安全
什么是可信应用服务
你有没有想过,怎么证明你拍的照片是真的?怎么证明你的位置没有被篡改?这就是可信应用服务要解决的问题。
可信应用服务(Trusted App Service)是 Device Security Kit 的一部分,它提供了两个很酷的功能:
- 安全摄像头:拍出来的照片带有数字签名,可以证明照片是真的,没有被篡改过
- 安全地理位置:获取的位置信息带有数字签名,可以证明位置是真的,没有被伪造
简单说,可信应用服务就是让你的应用能"自证清白"。拍的照片是真的,获取的位置也是真的。
核心功能
可信应用服务提供以下功能:
- 创建证明密钥:生成一对加密密钥,用来签名和验证。安全摄像头和安全地理位置共用同一个证明密钥,所以只需要创建一次。密钥创建后,会在设备的安全区域里保存,保证密钥不被窃取
- 初始化证明会话:创建一个安全会话,用来管理密钥的生命周期。证明会话会验证密钥的有效性,确保密钥没有被篡改。会话创建后,才能使用安全摄像头或安全地理位置功能
- 获取安全图像:拍出来的照片带有数字签名。签名包含了拍照时间、设备信息、照片哈希值等数据。服务器收到照片后,用公钥验证签名,就能确认照片是真的、没有被篡改过。比如执法人员拍照取证,照片的签名可以作为法律证据
- 获取安全地理位置:获取的位置信息带有数字签名。签名包含了定位时间、设备信息、坐标哈希值等数据。服务器收到位置后,用公钥验证签名,就能确认位置是真的、没有被伪造。比如员工打卡时,签名可以证明他确实在公司
环境搭建
硬件要求
- 设备类型:手机、平板、2in1 设备
- HarmonyOS 系统:HarmonyOS NEXT Developer Beta1 及以上
软件要求
- DevEco Studio 版本:DevEco Studio NEXT Developer Beta1 及以上
- HarmonyOS SDK 版本:HarmonyOS NEXT Developer Beta1 SDK 及以上
搭建步骤
- 安装 DevEco Studio:去华为开发者官网下载安装
- 配置开发环境:确保网络环境正常
- 设备调试:使用真机进行调试
项目结构
├── entry/src/main/ets
│ ├── common
│ │ ├── CertChain.ets // 证书链相关操作类
│ │ ├── Permission.ets // 权限相关操作类
│ │ └── TrustedServiceOption.ets // 可信应用服务接口参数
│ ├── entryability
│ │ └── EntryAbility.ets // 程序入口类
│ ├── model
│ │ ├── SecureCamera.ets // 安全相机类
│ │ └── SecureLocation.ets // 安全地理位置类
│ └── pages
│ └── Index.ets // 主页面
项目结构比较清晰,核心逻辑在 model 目录下的两个文件里。
第一步:配置权限
在 module.json5 中添加权限:
{
"requestPermissions": [
{
"name": "ohos.permission.CAMERA"
},
{
"name": "ohos.permission.APPROXIMATELY_LOCATION"
},
{
"name": "ohos.permission.LOCATION"
}
]
}
这里需要三个权限:
CAMERA:相机权限,用来拍照APPROXIMATELY_LOCATION:粗略位置权限LOCATION:精确位置权限
第二步:导入模块
import { trustedAppService } from '@kit.DeviceSecurityKit';
导入可信应用服务模块。
第三步:创建证明密钥
在使用安全摄像头或安全地理位置之前,需要先创建证明密钥。
async createAttestKey(): Promise<void> {
trustedAppService.createAttestKey(createOptions)
.then(() => {
this.message += '\n\n创建证明密钥成功';
})
.catch(() => {
this.message += '\n\n创建证明密钥失败';
});
}
调用 trustedAppService.createAttestKey 创建证明密钥。这个密钥是用来签名的,安全摄像头和安全地理位置共用同一个证明密钥。
在页面出现时创建密钥,页面消失时销毁密钥:
aboutToAppear(): void {
this.createAttestKey();
}
aboutToDisappear(): void {
trustedAppService.destroyAttestKey();
}
第四步:初始化安全摄像头
创建好证明密钥后,就可以初始化安全摄像头了。
async initCamera(surfaceId: string, callback: AsyncCallback<string>): Promise<void> {
try {
const cameraMgr = camera.getCameraManager(getContext(this) as common.UIAbilityContext);
// 获取前置摄像头
const frontCamera = this.getSecureCameraDevice(cameraMgr);
// 获取前置摄像头在安全模式下支持的能力
const capability = this.getSecureCameraOutputCapability(cameraMgr, frontCamera);
// 获取预览流配置信息
const previewProfile = this.getPreviewProfile(capability);
// 获取安全流配置信息
const photoProfile = this.getPreviewProfile(capability);
// 创建预览流输出对象
this.previewOutputObj = cameraMgr.createPreviewOutput(previewProfile, surfaceId);
// 创建安全流输出对象
const receiver = this.createSecurePhotoReceiver(callback);
const secureSurfaceId = await receiver.getReceivingSurfaceId();
this.photoOutputObj = cameraMgr.createPreviewOutput(photoProfile, secureSurfaceId);
// 创建相机输入对象
this.cameraInput = cameraMgr.createCameraInput(frontCamera);
// 初始化安全相机会话
await this.initSecureCameraAttestContext(this.cameraInput);
// 打开会话
await this.openSessionFlow(cameraMgr);
} catch (err) {
throw new Error((err as BusinessError).message);
}
}
这个函数做了很多事情:
- 获取相机管理器:通过
camera.getCameraManager获取 - 获取前置摄像头:选择安全模式的摄像头设备
- 获取摄像头能力:查看摄像头支持哪些功能
- 创建预览流:用来在屏幕上显示预览画面
- 创建安全流:用来接收带签名的照片
- 初始化证明会话:创建安全相机会话,验证密钥有效性
- 打开会话:开始使用摄像头
第五步:打开安全摄像头
用户点击"打开安全相机"按钮时,先检查权限,再初始化摄像头。
Button('打开安全相机').onClick(() => {
Permission.checkCameraPermission()
.then((hasPermission: boolean) => {
if (!hasPermission) {
return Permission.requestCameraPermission();
}
return Promise.resolve();
})
.then(() => {
CameraService.initCamera(this.xComponentController.getXComponentSurfaceId(), (err, msg) => {
this.message += `\n\n${msg}`;
});
})
.catch(() => {
this.message += `\n\n打开安全相机失败`;
this.createAttestKey();
});
});
先检查相机权限,如果没有权限就请求权限。权限通过后,调用 CameraService.initCamera 初始化安全摄像头。
第六步:获取安全地理位置
安全地理位置有两种获取模式:速度优先和精度优先。
Button('获取地理位置(速度优先)').onClick(() => {
Permission.checkLocationPermission()
.then((hasPermission: boolean) => {
if (!hasPermission) {
return Permission.requestLocationPermission();
}
return Promise.resolve();
})
.then(() => {
const priority = trustedAppService.LocatingPriority.PRIORITY_LOCATING_SPEED;
return LocationService.getVerifiedSecureLocation(priority);
})
.then((locationString: string) => {
this.message += `\n\n${locationString}`;
})
.catch(() => {
this.message += `\n\n获取地理位置失败`;
this.createAttestKey();
});
});
先检查位置权限,然后调用 LocationService.getVerifiedSecureLocation 获取安全位置信息。
public async getVerifiedSecureLocation(priority: trustedAppService.LocatingPriority): Promise<string> {
try {
await this.initSecureLocationAttestContext();
const secureLocation = await trustedAppService.getCurrentSecureLocation(this.timeout, priority);
// 最佳实践是在服务器端完成安全位置的签名验证
await this.verifySecureLocation(secureLocation);
return JSON.stringify(secureLocation.originalLocation);
} catch (err) {
throw new Error((err as BusinessError).message);
}
}
获取安全地理位置的步骤:
- 初始化证明会话:创建安全地理位置的证明会话
- 获取安全位置:调用
trustedAppService.getCurrentSecureLocation获取位置 - 验证位置:验证位置信息的签名是否有效
- 返回结果:返回位置信息
两种位置获取模式
可信应用服务支持两种位置获取模式:
速度优先(PRIORITY_LOCATING_SPEED)
- 获取速度快
- 精度相对较低
- 适合对速度要求高的场景,比如导航
精度优先(PRIORITY_ACCURACY)
- 获取速度慢
- 精度高
- 适合对精度要求高的场景,比如打卡签到
实际应用场景
可信应用服务在实际开发中有很多用途:
考勤打卡
// 员工打卡时,获取安全地理位置
async function checkIn() {
const priority = trustedAppService.LocatingPriority.PRIORITY_ACCURACY;
const location = await trustedAppService.getCurrentSecureLocation(timeout, priority);
// 把带签名的位置信息发送给服务器
await uploadCheckIn(location);
}
证据采集
// 执法人员拍照取证
async function collectEvidence() {
// 拍出来的照片带有数字签名
const photo = await takeSecurePhoto();
// 照片可以作为法律证据
await uploadEvidence(photo);
}
物流追踪
// 快递员签收时,获取安全位置
async function confirmDelivery() {
const priority = trustedAppService.LocatingPriority.PRIORITY_LOCATING_SPEED;
const location = await trustedAppService.getCurrentSecureLocation(timeout, priority);
// 确保签收位置是真实的
await confirmDeliveryAt(location);
}
适用场景
可信应用服务适合以下场景:
- 考勤应用:防作弊打卡
- 执法应用:证据采集
- 物流应用:签收确认
- 金融应用:远程开户的身份验证
- 政务应用:在线办事的身份验证
注意事项
- 权限要求:需要相机和位置权限
- 证明密钥:安全摄像头和安全地理位置共用同一个证明密钥
- 服务器验证:最佳实践是在服务器端完成签名验证
- 网络要求:需要联网才能完成验证
- 设备支持:需要设备支持安全摄像头功能
核心流程图
可信应用服务的整体使用流程:
可信应用服务的应用场景:
总结
可信应用服务让你的应用能"自证清白",核心流程:
- 创建证明密钥
- 初始化证明会话
- 获取安全图像或安全地理位置
- 在服务器端验证签名
掌握了这些,你就能让你的应用支持安全摄像头和安全地理位置功能,提升应用的安全性和可信度。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)