本文为个人博客备份文章,原文地址:

http://validvoid.net/solutions-get-device-id-for-uwp/

通过生成唯一的设备 ID 进行数据统计是应用开发中一个非常常见的需求,然而自从 WP 7.8 开始,WP 平台上就无法再获得一个唯一的,不变的,且不同应用间一致的设备 ID 了。本文总结了几种在 Windows Store 平台上用于统计设备 ID 的方案,开发时可以根据具体需求进行选用。

1. 广告 ID

广告 ID 主要用于通过分析用户安装了哪些应用并如何使用来优化广告推送的相关性和频率等行为,同时也用于检测广告欺诈以及其它一些安全问题。

public static string AdvertisingId { get; }

特点

  • 每用户、每设备唯一
  • 应用间一致

缺点

  • 广告 ID 并非持续可用,用户可以在系统设置的隐私选项或组策略中关闭广告 ID。
  • 广告 ID 并非永久唯一,以下情况会导致广告 ID 发生变化:
    • 用户关闭广告 ID 后重新开启广告 ID,广告 ID 会重新生成。
    • 用户重置或升级设备(手机、PC等)操作系统后,广告 ID 会重新生成。
  • 由于广告 ID 是每用户、每设备唯一的,故广告 ID 不会随着用户账户在不同设备间漫游。
  • 广告 ID 无法在儿童账户中开启。

使用方法

var advertisingId = Windows.System.UserProfile.AdvertisingManager.AdvertisingId;

广告 ID 关闭时,使用上述 API 获得广告 ID 的返回值为空。

MSDN 文档

AdvertisingManager.AdvertisingId | advertisingId property

2. EasClientDeviceInformation

EasClientDeviceInformation 类用于获取本地 ExchangeActiveSync 设备的信息。其中有一个 Guid 类型的 Id 属性,可以获得设备 Id。

public Guid Id { get; }

返回本地计算机的标识符。Id 属性表示 DeviceId(使用从 MachineID、用户 SID1 和包系列名称 (PFN)2 的 SHA256 哈希值截断的前 16 个字符 GUID,其中 MachineID 使用本地用户组的 SID)。GUID 的每个组件以网络字节顺序返回。

特点

  • 每用户、每设备、每应用唯一

缺点

  • 每应用唯一

由于构成 EAS 客户端设备信息 ID 的元素中包含包系列名称 (PFN),故 EAS 客户端设备信息 ID 是每应用间唯一的。假设你有多款应用均要通过设备唯一 ID 进行数据统计,那么同一台设备上的两个应用返回的将是两个不同的 ID。

使用方法

var easId = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation().Id;

MSDN 文档

EasClientDeviceInformation class

3. 应用特定硬件 ID (ASHWID)

应用特定硬件 ID(缩写为 ASHWID)通过表现设备硬件特征实现唯一设备的识别。ASHWID 适用于限制应用分发目标设备的数量,或者限制每设备使用唯一的授权。

特点

  • 每设备、每应用唯一
  • 用户间一致
  • 不会因以下操作而发生改变:
    • 操作系统重新安装
    • 推送按钮重置
    • 操作系统 SKU 升级
    • 应用的版本更新
    • 在同一设备上更改用户
  • 可验证真实性

缺点

  • 值会随着设备硬件的改变而改变

ASHWID 的构成

ASHWID 由当前设备的组成硬件以及当前应用包名称生成。

ASHWID 会根据以下九种可能的硬件组件进行生成,每个硬件组件都对应 ASHWID 返回的字节流的一部分:

  1. 处理器的 CPU ID
  2. 内存大小
  3. 磁盘设备的序列号
  4. 网络适配器(例如 NIC MAC 地址)
  5. 音频适配器
  6. 扩展坞
  7. Bluetooth 地址
  8. 移动宽带设备 ID
  9. BIOS

ASHWID 可能并不恰好包含 9 个组件 ID。可能的原因包括:

  • 目标硬件可能不是恰好具备 9 个独立组件。例如,桌面可能没有扩展坞。
  • 设备可能具备相同类型的多个组件。例如,可能有两个音频适配器。
  • 每个物理磁盘驱动器都对应一个组件 ID。具有 3 个物理磁盘驱动器的桌面系统会返回 3 个组件 ID。
  • 当平板电脑设备连接到扩展坞时,会返回其他网络 (Ethernet) 适配器和音频适配器(来自 HDMI 或模拟音频输出端口)的组件 ID。

ASHWID 的字节流标识了硬件组件的类型和值,参加下表:

字节流表示 组件
1,0 处理器
2,0 内存
3,0 磁盘设备
4,0 网络适配器
5,0 音频适配器
6,0 扩展坞
7,0 移动宽带
8,0 Bluetooth
9,0 系统 BIOS

以上表格摘自 MSDN 文档。

出于隐私安全的考虑,ASHWID 生成时会考虑应用包名称,因而在同一台设备上的两个应用获取到的 ASHWID 是不同的。而只要设备硬件不发生改变,同一台设备上的同一个应用多次获得的 ASHWID 总是相同的。

ASHWID 示例

不同组件 ID 的枚举顺序没有必要连续。以下流显示少量 ASHWID 示例。注意,在流中,组件 ID 的数字及其顺序会不同。

7,0,124,215,3,0,206,143,8,0,128,55,5,0,12,222,5,0,128,255,6,0,1,0,4,0,20,22,4,0,48,155,1,0,250,155,2,0,162,217,9,0,92,101

Samsung Intel Core i5 平板电脑上发现的移动宽带。

7,0,124,215,3,0,206,143,8,0,128,55,5,0,126,129,5,0,12,222,5,0,128,255,6,0,1,0,4,0,20,22,4,0,48,155,4,0,178,193,1,0,250,155,2,0,162,217,9,0,92,101

当靠接时同一设备上有三个不同音频适配器和当靠接时同一设备上有三个不同网络适配器。

3,0,188,97,3,0,76,128,3,0,250,138,5,0,220,130,6,0,1,0,4,0,20,164,1,0,204,49,2,0,226,37,9,0,22,72

桌面上发现三个不同磁盘。

3,0,24,211,5,0,182,46,5,0,54,49,6,0,1,0,4,0,203,9,1,0,148,99,2,0,162,255,9,0,140,234

Nvidia Tegra 3 设备。你可能会注意到流“6,0,1,0”与扩展坞对应,不论设备或外形规格如何。

以上示例摘自 MSDN 文档。

使用方法

要获得 ASHWID,可以使用 HardwareIdentification.GetPackageSpecificToken 方法。

该方法接受一个参数 IBuffer noncenonce 为仅使用一次的数字。通常此数实现为随机数,该数足够大,可降低数字重复使用的可能性。nonce 用在身份验证协议中,可防止重播攻击。

该方法返回一个 HardwareToken 类型。HardwareToken 类型表示包含了一个足够唯一的基于硬件的标识的标记。

HardwareToken 类型包含以下三个属性(均为 IBuffer ):

  • Certificate:获得用以签名硬件特定 Id 的证书以验证 Id 真实性。
  • Id:获得硬件特定 Id。
  • Signature:获得硬件特定 Id 的签名以验证 Id 真实性。
HardwareToken packageSpecificToken;

packageSpecificToken =  Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(nonce);

IBuffer hardwareId  = packageSpecificToken.Id;
IBuffer signature = packageSpecificToken.Signature;
IBuffer certificate = packageSpecificToken.Certificate; var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId); byte[] bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes); string id = BitConverter.ToString(bytes);

验证 ASHWID 有效性

若要使用 ASHWID 实现正版授权验证、限制应用分发等需求,可以通过使用可选的 nonce、签名以及证书结合应用的云端进行验证。

在调用 GetPackageSpecificToken 方法时,可以传入 IBuffer 类型的 nonce 参数。通过每次提供不同的 nonce,云端可以据此来验证所返回的 ASHWID 实际上来自 Windows 且未由用户重播。

除非云端不关心重播攻击或 ASHWID 的处理仅在客户端完成,则不推荐为 GetPackageSpecificToken 方法传递空的 nonce。

由于 ASHWID 会随着设备硬件的改变而改变,故云端在验证 ASHWID 时,需要响应地计算 ASHWID 的变化量,在容许的范围内判断许可授权的有效性。

有关在云端验证 ASHWID 的更多说明,可以参阅 MSDN 文档 《有关使用应用特定硬件 ID (ASHWID) 实现每设备应用逻辑的指南》


  1. SID 全称 Security Identifier,即“安全标识符”。 SID 由 Windows 域控制器等权威方发布,用于标识用户、用户组和计算机账户。每创建一个账户,系统都会为该账户分配一个唯一的 SID。即便删除某账户,再以完全相同的名称创建一个新账户,新账户的 SID 也是不同于旧有账户的。用户登录时,SID 作为用户访问凭据的一部分由系统使用来判断当前用户是否有执行某项操作的权限。有关 SID 的更多信息,可以参阅文档 Security Identifiers。 

  2. 即 Package family name (PFN),指与经过哈希的发布者名称连结的程序包名称。 

Windows Store 应用获得设备 ID 的几种方案的更多相关文章

  1. 在桌面程序上和Metro/Modern/Windows store app的交互(相互打开,配置读取)

    这个标题真是取得我都觉得蛋疼..微软改名狂魔搞得我都不知道要叫哪个好.. 这边记录一下自己的桌面程序跟windows store app交互的过程. 由于某些原因,微软的商店应用的安全沙箱导致很多事情 ...

  2. 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用

    协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...

  3. wp8 入门到精通 虚拟标示符 设备ID

    //获得设备虚拟标示符 wp8 public string GetWindowsLiveAnonymousID() { object anid = new object(); string anony ...

  4. Unity3D开发Windows Store应用程序 注意事项

    原地址:http://blog.csdn.net/jbjwpzyl3611421/article/details/12704491 针对最近在移植window store项目中遇到的问题,我整理了官方 ...

  5. 【转】获取android设备 id

    关于本文档 Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID.例如,跟踪应用程序的安装,生成用于复制保护的DRM时需要使用设备的唯一ID.在本文档结尾处提供了作为参考的示例代码片段 ...

  6. Windows Store Javascript项目使用高德地图、谷歌地图、百度地图API

    原文 Windows Store Javascript项目使用高德地图.谷歌地图.百度地图API 在Win8 Store 项目中可以使用的地图主要有微软的Bing Map,目前高德地图sdk也支持Wi ...

  7. Windows Store 手势编程小结

    Windows Store 手势编程小结 最近完成了一个Windows Store上面的手势操作的页面.在这里总结了一下经验和心得,希望能和大家一起分享和讨论一下. 首先,要纠正一个误区,在Windo ...

  8. 设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识 zz

    原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...

  9. [转]设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识

    原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...

随机推荐

  1. 利用python下载视频

    我们知道,有些网页上的视频,没有下载的按钮,并且有些视频需要付费下载,很多同学因此很苦恼.不怕,有问题找我,我试试用程序员的方式通俗易懂教会大家. 1.你先下载一个Python,不会下载的同学可以看这 ...

  2. 3分钟实现iOS语言本地化/国际化(图文详解)

    前言 语言本地化,又叫做语言国际化. 是指根据用户操作系统的语言设置,自动将应用程序的语言设置为和用户操作系统语言一致的语言. 往往一些应用程序需要提供给多个国家的人群使用,或者一个国家有多种语言,这 ...

  3. 【图灵学院09】RPC底层通讯原理之Netty线程模型源码分析

    1. dubbo 2.5.3 netty 3.2.5.Final

  4. centos7安装配置时间服务器

    前言: 时间服务器是S/C模型服务,需要配置服务端和客户端 NTP服务端配置:(服务端的IP为1.1.1.14)安装ntp服务:# yum -y install ntp查询网络中的NTP服务器:# n ...

  5. 如何进bat

    既然是要谈如何进入BAT,那么咱们就从面试的角度来谈学习这件事,会谈谈一流互联网公司对于Java后端程序员的要求,相应的,也会谈谈如何达到这样的要求. 为了简单起见,这些要求分为三个层次,分别为基本要 ...

  6. POJ1054 The Troublesome Frog

    题目来源:http://poj.org/problem?id=1054 题目大意: 有一种青蛙在晚上经过一片稻田,在庄稼上跳跃,会把庄稼压弯.这让农民很苦恼.我们希望通过分析青蛙跳跃的路径,找出对稻田 ...

  7. day27 粘包及粘包的解决方案

    1.   粘包现象 先了解一个词MTU MTU是Maximum Transmission Unit的缩写.意思是网络上传送的最大数据包.MTU的单位是字节. 大部分网络设备的MTU都是1500个字节, ...

  8. AD域账号验证

    public partial class _Default : Page { [DllImport("advapi32.dll")] private static extern b ...

  9. ubuntu14.04&matlab2015b 测试caffe的Matlab接口

    Step1: 修改caffe-master中的Makefile.config 提示:可以到文件中直接“ctrl+f”,键入相应大写字母即可查找到相应位置. Step2:编译接口.如果之前编译caffe ...

  10. 如何 将下载离线 nupkg 文件 安装到VS2017

      https://www.cnblogs.com/cncc/articles/8276878.html   --------------------------------------------- ...