HarmonyOS 私密相册实战一张照片移入保险箱后怎样让普通相册真的看不见真机环境ALN-AL80OpenHarmony 7.0.0.32Beta2API 26。验证覆盖移入保险箱、系统身份认证、二级密码解锁、普通相册隔离和恢复原相册。私密相册不只是多一个带锁页面很多私密相册 Demo 只做了一个密码页输入正确就跳到另一组图片。真正接入相册后风险往往出现在入口之外——首页缩略图、搜索结果、地图回忆、最近照片和视频选片都可能继续显示同一条记录应用切到后台时任务缩略图还可能保留私密画面。双镜记忆相机的目标是把一张公开照片移入保险箱后普通相册立刻不再展示进入保险箱必须经过系统身份认证或本地二级密码离开保险箱再次锁定恢复照片后它才重新回到普通相册。本次使用一张虚构成年旅行者公开测试图完整走一遍“公开—私密—解锁—隐藏—恢复—重新出现”的状态变化。先划清实现的安全边界User Authentication Kit 官方能力页明确支持锁屏密码、人脸和指纹认证并把访问隐私相册列为用户操作授权场景认证凭据由系统安全隔离环境存储和处理。官方同时允许生物认证不方便时切换到业务自定义认证方式。二级密码使用 HarmonyOS SDK 中的 Asset Store Kit 保存。Asset Store Kit 面向密码、Token 等短敏感数据适合保存应用自己的 6 位解锁凭据。当前实现的边界分为四层相册记录的visibility决定公开或私密所有公开入口统一过滤User Authentication Kit 负责系统人脸、指纹和锁屏密码认证Asset Store Kit 保存应用二级密码作为可控的备用入口私密照片详情开启窗口隐私模式离开保险箱立即锁定。照片文件位于应用沙箱本文验证的是应用内可见性、访问授权和窗口保护。若业务需要独立文件加密、密钥轮换或跨设备密文同步还要在文件层增加专门的加密方案。第一步从真实照片详情移入保险箱操作前人物照片位于普通相册详情页面可以直接看到“移入保险箱”入口。移动操作不复制第二份数据库记录而是更新同一条记录的可见性并持久化privateasyncmoveRecordToVault(recordId:string):Promisevoid{constwasViewingDetailthis.galleryViewModedetail;awaitthis.updateRecordVisibility(recordId,private);this.vaultSelectedIdrecordId;this.vaultUnlockedfalse;if(wasViewingDetail){this.galleryViewModealbum;this.switchTab(vault);this.vaultStatusText照片已移入保险箱验证身份后可查看;}}updateRecordVisibility()同步更新相册记录、地图标记和持久化数据。状态写入成功后才关闭详情避免页面先消失而写盘失败。图 1真机提示照片已经移入保险箱当前页面仍处于锁定状态。这一步完成了数据归类没有自动解锁保险箱。即使操作来自照片详情查看私密内容仍需要重新验证身份。第二步优先调用系统身份认证系统认证同时请求 PIN、人脸和指纹三种本地认证类型并为本次认证生成 16 字节随机 challenge。不同设备支持的安全等级可能不同因此从 ATL3 依次回退到 ATL2、ATL1只有返回“不支持当前等级”或“不支持认证类型”时才继续回退普通认证失败不会被当作降级理由。constauthParam:userAuth.AuthParam{challenge:createRandomChallenge(),authType:[userAuth.UserAuthType.PIN,userAuth.UserAuthType.FACE,userAuth.UserAuthType.FINGERPRINT],authTrustLevel:userAuth.AuthTrustLevel.ATL3};constinstanceuserAuth.getUserAuthInstance(authParam,{title:验证身份});instance.on(result,callback);instance.start();真机固定在测试支架上前置摄像头没有正对已录入人脸本次系统认证明确返回“未识别成功”。系统面板同时给出指纹和锁屏密码出口。图 2真机 User Authentication Kit 返回人脸未识别成功并提供指纹和锁屏密码入口。认证失败不会打开保险箱。页面保留锁定状态用户可以重试系统认证也可以使用应用的二级密码。第三步用 Asset Store Kit 保存二级密码首次使用二级密码时页面要求输入并确认 6 位数字。截图中的输入内容已经由密码框隐藏。图 3系统认证失败后进入二级密码设置密码内容不显示在页面和文章中。保存时不使用 Preferences 明文写入。Asset Store 条目设置为设备解锁后可访问、要求设备已经设置锁屏密码、禁止同步到其他设备constattributes:asset.AssetMapnewMap();attributes.set(asset.Tag.SECRET,toBytes(pin));attributes.set(asset.Tag.ALIAS,toBytes(vault.pin.v1));attributes.set(asset.Tag.ACCESSIBILITY,asset.Accessibility.DEVICE_UNLOCKED);attributes.set(asset.Tag.REQUIRE_PASSWORD_SET,true);attributes.set(asset.Tag.SYNC_TYPE,asset.SyncType.NEVER);attributes.set(asset.Tag.CONFLICT_RESOLUTION,asset.ConflictResolution.OVERWRITE);awaitasset.add(attributes);验证时按别名查询唯一条目并使用固定时间比较避免在第一位不同时过早返回functionconstantTimeEqual(left:Uint8Array,right:Uint8Array):boolean{letdifferenceleft.length^right.length;constlengthMath.max(left.length,right.length);for(letindex0;indexlength;index){difference|(left[index]??0)^(right[index]??0);}returndifference0;}二级密码保存成功后保险箱在当前会话中解锁刚刚移入的照片作为唯一私密记录出现。图 4真机保险箱已经解锁私密照片数量为 1。第四步所有普通入口统一过滤私密记录相册首页不能只在 UI 层隐藏某一张卡片。双镜记忆相机先从记录集合生成公开视图再把这份集合交给相册、语义搜索、地图、最近照片和视频选片。constpublicRecordsrecords.filter(recordrecord.visibility!private);constvaultRecordsrecords.filter(recordrecord.visibilityprivate);语义搜索返回图片路径后还会再次查找公开记录。这样即使系统索引尚未完成删除私密照片也不会绕过当前业务权限重新出现在结果页。从保险箱返回普通相册后测试照片已经从公开记录集合中消失相册计数同步减少一张。页面离开保险箱时还会执行lockVault()清空当前选择并关闭私密详情。再次进入必须重新认证不能依赖上一次解锁状态长期驻留。第五步窗口隐私模式保护任务缩略图打开私密照片详情时应用为当前窗口打开隐私模式constcurrentWindowawaitwindow.getLastWindow(context);awaitcurrentWindow.setWindowPrivacyMode(true);关闭私密详情时恢复普通窗口状态离开保险箱则同时关闭详情并重新锁定。窗口隐私模式负责系统截屏和任务缩略图层面的保护业务记录过滤负责应用内部入口两者解决的是不同问题不能互相替代。第六步恢复照片并确认重新出现在已解锁保险箱中点击“恢复到相册”同一条记录的visibility改回public。写入成功后页面提示“已恢复到相册”。图 5恢复操作已经完成保险箱中的私密记录被移回公开集合。返回相册后人物照片重新进入公开记录集合相册数量也恢复到移动前的值。至此公开—私密—公开的状态闭环完成。真机过程里最值得保留的两个细节系统认证失败也必须有完整路径固定支架导致人脸识别失败正好验证了异常路径系统面板没有被应用绕过保险箱保持锁定用户仍可选择指纹、锁屏密码或应用二级密码。真实产品不能只验证“人脸一次成功”的理想情况。“看不见”要覆盖所有数据消费者只修改相册首页会留下搜索、地图、最近照片和成片选片等旁路。把公开/私密过滤放到记录层所有功能域得到的都是已经过权限判断的集合搜索结果还要在跳转详情前重新检查可见性。最终效果这次 ALN-AL80 真机验证完成了完整状态闭环公开照片进入保险箱保险箱保持锁定系统人脸认证失败且没有放行二级密码安全保存并成功解锁私密照片在保险箱可见普通记录集合不再包含这张照片执行恢复操作后照片重新回到公开记录集合。User Authentication Kit 提供可信的系统认证界面Asset Store Kit 保存应用备用凭据记录层控制全部业务入口的可见性窗口隐私模式保护私密照片详情。四层组合以后保险箱不再只是一个带密码的页面而是从数据访问到系统窗口都能保持一致状态的完整功能。