首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
HarmonyOS
发新帖
0
0
[原创]【FAQ】HarmonyOS SDK 闭源开放能力 — Device Security Kit
发表于: 2026-1-22 09:55
7615
[原创]【FAQ】HarmonyOS SDK 闭源开放能力 — Device Security Kit
HarmonyOS SDK
2026-1-22 09:55
7615
**1.问题描述:** 请问有没有C接口(NDK)直接读取CPU型号、主板UUID、硬盘序列号、网卡MAC等信息(比如udev)?或者有没有可靠的设备唯一ID接口可供调用? **解决方案:** 常见设备的标识有OAID、ODID、AAID、UDID等,定义和用途如下: OAID(开放匿名设备标识符)一种非永久性设备标识符,基于OAID,可在保护用户个人数据隐私安全的前提下,媒体App、广告平台、三方监测平台等开发者,可获取设备上的OAID,进行个性化广告推荐或广告转化归因分析。 ODID(开发者匿名设备标识符):用于识别同一设备上运行的同一个开发者的应用,标识应用身份。帮助开发者更好地理解用户在不同应用间的行为,从而提供更个性化的服务和推荐。 AAID(应用匿名标识符):标识应用的身份,主要用于应用的消息推送。 UDID(设备唯一标识符):标识设备的属性,可作为设备唯一识别码。 只有UDID才能作为设备的唯一标识符,不会随设备重置或应用卸载而发生变化,但UDID只允许系统应用及企业定制应用申请特殊权限才能获取。当前设备重置时还无法保证标识符不发生改变,但有方案可以实现应用卸载时标识符不发生改变。 为了保证及时在应用卸载后仍能有效的确保获取的设备标识符不发生变化,间接达到“唯一标识符”的目的,华为提供了关键资产存储服务,开发者可以将设备标识符放在asset里,设置IS_PERSISTENT()为true,实现在应用卸载时保留关键资产,达到标识符不清除的效果。如获取ODID后配合使用Asset Store Kit能力,保持ODID不变的效果,示例代码如下: ``` import { asset } from '@kit.AssetStoreKit'; import util from '@ohos.util'; import { deviceInfo } from '@kit.BasicServicesKit'; function stringToArray(str: string): Uint8Array { let textEncoder = new util.TextEncoder(); return textEncoder.encodeInto(str); } function setAttr(id: string) { let attr: asset.AssetMap = new Map(); attr.set(asset.Tag.SECRET, stringToArray(id)); attr.set(asset.Tag.ALIAS, stringToArray('demo_device_id')); attr.set(asset.Tag.IS_PERSISTENT, true); try { asset.add(attr).then(() => { console.info(`Asset added successfully.`); }).catch(() => { console.error(`Failed to add Asset.`); }) } catch (error) { console.error(`Failed to add Asset.`); } } function arrayToString(arr: Uint8Array): string { let textDecoder = util.TextDecoder.create("utf-8", { ignoreBOM: true }); let str = textDecoder.decodeWithStream(arr, { stream: false }) return str; } async function getAttr(): Promise<string> { let query: asset.AssetMap = new Map(); query.set(asset.Tag.ALIAS, stringToArray('demo_device_id')); // 指定了关键资产别名,最多查询到一条满足条件的关键资产 query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL); // 此处表示需要返回关键资产的所有信息,即属性+明文 try { const res: Array<asset.assetmap> = await asset.query(query) // 解析密钥 let secret: Uint8Array = res[0].get(asset.Tag.SECRET) as Uint8Array; // 将uint8array解析为字符串 let secretStr: string = arrayToString(secret); return secretStr; } catch (error) { console.error(`Failed to query Asset.`); return ''; } } @Entry @Component struct AttrTest { build() { Column() { Button('获取设备ID').onClick(async (event: ClickEvent) => { let deviceId: string = await getAttr(); if (deviceId === undefined || deviceId === null || deviceId.length === 0) { deviceId = deviceInfo.ODID; setAttr(deviceId); } console.log('设备ID为:' + deviceId) }) .height(100) .width('100%') } } } ``` **2.问题描述:** 如何使用DSA算法实现签名验签的功能? **解决方案:** 1. 配置DSA1024公钥和私钥中包含的公共参数dsaCommonSpec。 2. 设置DSA1024密钥对中包含的全参数。 3. 调用createAsyKeyGeneratorBySpec方法生成DSA算法的非对称密钥生成器。 4. 通过密钥生成器生成DSA非对称密钥对。 5. 使用DSA私钥对数据进行签名。 6. 使用DSA公钥对签名数据进行验签。 完整示例代码如下: ```TypeScript import { cryptoFramework } from '@kit.CryptoArchitectureKit'; import { buffer } from '@kit.ArkTS'; let input: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from("This is Sign test plan", 'utf-8').buffer) }; // 配置DSA1024公钥和私钥中包含的公共参数 function genDsa1024CommonSpecBigE() { let dsaCommonSpec: cryptoFramework.DSACommonParamsSpec = { algName: "DSA", specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, p: BigInt("0xed1501551b8ab3547f6355ffdc2913856ddeca198833dbd04f020e5f25e47c50e0b3894f7690a0d2ea5ed3a7be25c54292a698e1f086eb3a97deb4dbf04fcad2dafd94a9f35c3ae338ab35477e16981ded6a5b13d5ff20bf55f1b262303ad3a80af71aa6aa2354d20e9c82647664bdb6b333b7bea0a5f49d55ca40bc312a1729"), q: BigInt("0xd23304044019d5d382cfeabf351636c7ab219694ac845051f60b047b"), g: BigInt("0x2cc266d8bd33c3009bd67f285a257ba74f0c3a7e12b722864632a0ac3f2c17c91c2f3f67eb2d57071ef47aaa8f8e17a21ad2c1072ee1ce281362aad01dcbcd3876455cd17e1dd55d4ed36fa011db40f0bbb8cba01d066f392b5eaa9404bfcb775f2196a6bc20eeec3db32d54e94d87ecdb7a0310a5a017c5cdb8ac78597778bd"), } return dsaCommonSpec; } // 设置DSA1024密钥对中包含的全参数 function genDsa1024KeyPairSpecBigE() { let dsaCommonSpec = genDsa1024CommonSpecBigE(); let dsaKeyPairSpec: cryptoFramework.DSAKeyPairSpec = { algName: "DSA", specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, params: dsaCommonSpec, sk: BigInt("0xa2dd2adb2d11392c2541930f61f1165c370aabd2d78d00342e0a2fd9"), pk: BigInt("0xae6b5d5042e758f3fc9a02d009d896df115811a75b5f7b382d8526270dbb3c029403fafb8573ba4ef0314ea86f09d01e82a14d1ebb67b0c331f41049bd6b1842658b0592e706a5e4d20c14b67977e17df7bdd464cce14b5f13bae6607760fcdf394e0b73ac70aaf141fa4dafd736bd0364b1d6e6c0d7683a5de6b9221e7f2d6b"), } return dsaKeyPairSpec; } async function signMessagePromise(priKey: cryptoFramework.PriKey) { let signAlg = "DSA1024|SHA256"; let signer = cryptoFramework.createSign(signAlg); await signer.init(priKey); let signData = await signer.sign(input); return signData; } async function verifyMessagePromise(signMessageBlob: cryptoFramework.DataBlob, pubKey: cryptoFramework.PubKey) { let verifyAlg = "DSA1024|SHA256"; let verifier = cryptoFramework.createVerify(verifyAlg); await verifier.init(pubKey); let res = await verifier.verify(input, signMessageBlob); console.info('DSA verify result is ' + res); return res; } function main() { let asyKeyPairSpec = genDsa1024KeyPairSpecBigE(); let asyKeyGeneratorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(asyKeyPairSpec); // 异步获取非对称密钥生成器生成的密钥 asyKeyGeneratorBySpec.generateKeyPair(async (err, keyPair) => { if (err) { console.error('generateKeyPair: error.'); return; } console.info('generateKeyPair: success.'); // 签名 let signData = await signMessagePromise(keyPair.priKey) // 验签 let verifyResult = await verifyMessagePromise(signData, keyPair.pubKey); if (verifyResult === true) { console.info('verify success'); } else { console.error('verify failed'); } }) } ``` **3.问题描述:** 从应用设置页跳转至系统设置显示没有权限。 **解决方案:** 应用在权限管理界面的操作,未先进行相关权限申请,则根据系统设计,无法在系统隐私设置权限页面设置,可以参考以下步骤: 1. 通过<a href="elink@e35K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3q4T1K9h3I4A6N6s2W2S2j5$3y4W2M7%4y4U0N6s2u0D9i4K6t1K6k6$3g2@1M7$3g2D9k6Y4m8W2M7X3#2A6M7%4y4A6L8$3&6K6N6r3q4@1N6i4x3J5x3l9`.`.">getSelfPermissionStatus</a>接口查询应用权限状态,参考代码: ```TypeScript getPermissionStatus(permission: string) { try { let data: abilityAccessCtrl.PermissionStatus = this.atManager.getSelfPermissionStatus(permission); console.info(`data->${data}`); } catch (err) { console.error(`catch err->${err}`); } } ``` 2. 当结果为NOT_DETERMINED时,表示未操作。应用声明用户授权权限,暂未调用requestPermissionsFromUser接口请求用户授权,此时可以调用请求用户授权接口进行授权,参考代码: ```TypeScript reqPermissionFromUser(permissionList: Array<permissions>) { let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext; atManager.requestPermissionsFromUser(context, permissionList, (err: BusinessError, data: PermissionRequestResult) => { if (err) { console.error(`requestPermissionsFromUser fail, err->${err}`); } else { console.info('data permissions:' + data.permissions); console.info('data authResults:' + data.authResults); } }); } ``` 3. 当前结果为已授权或未授权时,可以跳转到系统权限设置页面调整,或者使用<a href="elink@08dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3q4T1K9h3I4A6N6s2W2S2j5$3y4W2M7%4y4U0N6s2u0D9i4K6t1K6M7X3g2I4N6h3g2K6N6s2m8W2M7X3#2A6M7%4y4A6L8$3&6G2L8Y4y4W2N6s2c8A6L8X3M7I4x3R3`.`.">requestPermissionOnSetting</a>拉起权限设置弹框。参考代码: ```TypeScript applyPermissions(permissionList: Array<permissions>) { if (!this.atManager || !this.context) { return } this.atManager.requestPermissionOnSetting(this.context, permissionList) .then((data: Array<abilityaccessctrl.grantstatus>) => { console.info(`data: ${data}`); }) .catch((err: BusinessError) => { console.error(`data: ${err}`); }); } ``` </abilityaccessctrl.grantstatus></permissions></permissions></asset.assetmap></string>
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
1
)
mb_eekvgidg
雪 币:
249
活跃值:
(175)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
28
粉丝
0
关注
私信
mb_eekvgidg
2
楼
很有内涵,能联系我吗137334010(企鹅
2026-4-7 19:00
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
HarmonyOS SDK
258
发帖
190
回帖
0
RANK
关注
私信
他的文章
[原创]HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
270
[原创]AI 赋能 Push Kit 场景化消息开发,高效完成鸿蒙应用推送能力接入
472
[原创]HarmonyOS Push Kit 自分类权益 Skill,助力提升权益申请通过率
521
[原创]基于增强QUIC协议优化弱网下的直播观看体验
697
[原创]焕新鸿蒙应用权限管理方案,应用授权体验再升级
609
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部