湖南省网站建设_网站建设公司_Oracle_seo优化
2026/1/22 10:33:22 网站建设 项目流程

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(() =&gt; {console.info(`Asset added successfully.`);}).catch(() =&gt; {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@Componentstruct AttrTest {build() {Column() {Button('获取设备ID').onClick(async (event: ClickEvent) =&gt; {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公钥对签名数据进行验签。

完整示例代码如下:


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) =&gt; {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. 通过getSelfPermissionStatus接口查询应用权限状态,参考代码:

getPermissionStatus(permission: string) {try {let data: abilityAccessCtrl.PermissionStatus = this.atManager.getSelfPermissionStatus(permission);console.info(`data-&gt;${data}`);} catch (err) {console.error(`catch err-&gt;${err}`);}}
  1. 当结果为NOT_DETERMINED时,表示未操作。应用声明用户授权权限,暂未调用requestPermissionsFromUser接口请求用户授权,此时可以调用请求用户授权接口进行授权,参考代码:

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) =&gt; {if (err) {console.error(`requestPermissionsFromUser fail, err-&gt;${err}`);} else {console.info('data permissions:' + data.permissions);console.info('data authResults:' + data.authResults);}});}
  1. 当前结果为已授权或未授权时,可以跳转到系统权限设置页面调整,或者使用requestPermissionOnSetting拉起权限设置弹框。参考代码:

applyPermissions(permissionList: Array<permissions>) {if (!this.atManager || !this.context) {return}this.atManager.requestPermissionOnSetting(this.context, permissionList).then((data: Array<abilityaccessctrl.grantstatus>) =&gt; {console.info(`data: ${data}`);}).catch((err: BusinessError) =&gt; {console.error(`data: ${err}`);});}

</abilityaccessctrl.grantstatus></asset.assetmap>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询