欢迎

这是一个专注于讨论风控的博客。

May 7, 2025 · 1 min · Lotty

Random Access

随机访问和内存地址连续性 在对集合的访问中,一般会有两种访问方式:随机访问和顺序访问,不同的底层数据结构,在使用这两种访问方式时,效率是有区别的。一般来讲,内存地址连续的数据结构,在随机访问时的效率比内存地址不连续的要高。因为内存地址连续,可以通过下标很快的检索出对应的元素,反之由于内存地址不连续,在随机访问时,需要从内存地址起始位置按照链接关系一个一个的扫描,效率自然就降低了。典型的例子就是数组和链表。数组是一种内存地址连续的结构,对它的随机访问,效率比较高;链表是一种内存地址不连续的结构,对它的随机访问效率就比较低。 RandomAccess接口 在java语言中,为了方便开发者选择高效的访问方式,系统提供了一个RandomAccess接口,该接口用来标识对应的数据结构是否支持高效的随机访问。大多数以数组为底层结构的数据结构都实现了该接口。比如常见的ArrayList。在官方声明中,也对该接口进行了很详细的描述,原文如下: * Marker interface used by <tt>List</tt> implementations to indicate that * they support fast (generally constant time) random access. The primary * purpose of this interface is to allow generic algorithms to alter their * behavior to provide good performance when applied to either random or * sequential access lists. * * <p>The best algorithms for manipulating random access lists (such as * <tt>ArrayList</tt>) can produce quadratic behavior when applied to * sequential access lists (such as <tt>LinkedList</tt>). Generic list * algorithms are encouraged to check whether the given list is an * <tt>instanceof</tt> this interface before applying an algorithm that would * provide poor performance if it were applied to a sequential access list, * and to alter their behavior if necessary to guarantee acceptable * performance. * * <p>It is recognized that the distinction between random and sequential * access is often fuzzy. For example, some <tt>List</tt> implementations * provide asymptotically linear access times if they get huge, but constant * access times in practice. Such a <tt>List</tt> implementation * should generally implement this interface. As a rule of thumb, a * <tt>List</tt> implementation should implement this interface if, * for typical instances of the class, this loop: 该声明对于RandomAccess接口进行很详细的描述,大致包括: ...

May 8, 2025 · 3 min · Lotty

关于设备指纹,你想了解的都在这里

设备标识符 在移动安全领域,设备唯一标识符策略,也就是设备指纹是一种比较常见的安全手段。设备指纹安全是一种实现简单、门槛较低、安全性较高的安全手段。在国内,有不少安全公司都推出了设备指纹产品,主要覆盖android、ios、js等平台。事实上,为了确保自身数据的安全性和保密性,很多大型企业都会有自身的设备指纹团队。作者在此仅讨论下移动端android平台的设备指纹特性。 设备唯一标识符 在安卓端,原生系统其实已经提供了很多标识性比较强的设备ID字段,比如说:androidId、imei、imsi、serialNo等。在仅仅只需要对设备进行简单的分类的场景下,以上字段就足以满足业务需求了。不管是较低版本的android设备,还是最新版本的android设备,以上字段中都会有部分字段是可以采集得到的。在设备指纹领域,系统的目的是根据设备信息来生成低碰撞的设备ID。在初期的设备指纹系统中,基本都是采集系统的环境信息和设备的软硬件信息来构造设备ID,由于这些方案是在本地生成的设备ID,在设备进行一些刷机、恢复出厂设置后,设备ID就会发生改变,并且极容易被类似xposed等改机工具给绕过。因此、这种设备ID的生成方式很快就退出了舞台。 目前市场上的设备指纹方案,一般都是通过前端采集、后端生成来实现的。这种方案的好处是设备ID存储在后端,前端只负责数据采集,后端来校验设备ID,达到了前后端分离的目的。与此同时,设备ID生成策略被隐藏,不易被攻击,后端还可以通过长期演进的方式来保证较强能力的设备ID恢复能力。 关于数据采集 在安卓设备中,可以体现出一个设备的身份的特征还是很多的。比如:androidId、imei、medi等原生字段,还有类似brand、deviceName、host等设备构建信息,还有abi、cpu、camera等硬件信息,还有wifi、blue、ip等网络信息。从目前的形式来看,谷歌对原生系统的权限收紧会导致越来越多的标识无法采集,这也是对设备指纹系统的一个巨大挑战。也因此,国内几个大型的安卓设备厂商组织了移动联盟,该联盟旨在在设备中从rom的层面,提供设备的唯一标识符。这些标识符是可以作为较稳定的设备ID来使用的。 但是,我们必须得清楚,依靠某个单独的字段或者几个字段来标识设备的唯一性,是存在很大风险的。某些改机工具通过修改这些敏感的字段,就可以轻而易举的绕过我们方案。这也是设备指纹系统中一个很难解决的问题。当然这里面同样包括刷机、重启、恢复出厂设置等修改措施。 针对以上的异常情形(也可以说是正常情形),各个设备厂商也都研究了相应的措施,比如检测设备异常状态,多字段联合恢复等,这些手段在一定程度上提高了设备指纹的安全性。 关于对抗 客户端作为一种运行在用户设备中的系统,其面临的入侵风险是非常高的。也因此,客户端的对抗要求也会相对高很多。这些对抗手段主要集中在加解密、重打包、混淆策略、字符加密等常规手段,还包括一些逻辑本地化(Native c/c++)、虚拟化等强化手段。 在加解密方面主要是对秘钥的保护,常用的方案有秘钥交换策略、一次一密策略、白盒加密策略。这些技术手段的初衷都是为了隐藏对称加密的秘钥,从而对原始数据进行保护。 在重打包方面主要是对证书校验、原始重点方法堆栈信息的判断来实现的。目的是即时检测出应用中被注入的新代码和被删除的原始代码。 至于混淆和字符串加密,则是从逆向的角度来考虑的,目的是增加代码的阅读难度,其中字符加密也是为了保护系统的一些敏感的常量两字符信息。 当然,像系统本地化、虚拟化这些手段是在系统发展到一定程度必然要经历的。本地化代码可以极大地提高代码的破解难度和动态调试难度,间接的提高了破解成本。至于虚拟化,他虽然提高了系统的安全级别,但是多少也会降低系统的运行效率,该领域也是可以持续挖掘的区域之一。 关于风险识别 在很多场景,比如登录、注册、支付等敏感场景,设备ID不仅仅提供了设备验证和判定的功能,它还可以提供设备风险识别的能力。最简单的就是模拟器判定了。这在初期的一些设备指纹系统中就有体现。其他的还有类似改机、被hook、设备农场等等。设备指纹系统从设备数据的角度来对该设备所处网络环境、所属的软件运行环境进行多维度的解析,来输出对应的风险标签。这在一定程度上,扩展了设备指纹的业务能力,增强了业务方的产品安全。 关于设备恢复 在设备指纹系统中,设备恢复是极核心的能力,所谓的恢复其实就是针对同一个设备,在它的环境、状态等发生改变时,设备指纹系统仍然能够将之恢复成之前的设备。在上文提到过,设备本身就具有很多稳定的指标,比如:imei、wifimac等。通过这些指标的对比,我们就可以实现一套不错的设备恢复逻辑。但是,需要指出的是,这种方案需要对全版本的安卓设备进行适配,并且在不同的版本中,采用不同的组合,这样才能达到一个相对靠谱的恢复能力。相比这种方案,我们还可以通过一些被动式的方式,来获取其他应用的设备层面的指标,来间接的对设备进行恢复。不管哪种方式,都需要开发者及时的适配版本、从版本特性中找到可以使用的信息。 在这里,我们提供一种可以长期演进的恢复方案。通过对设备的总体信息进行分析匹配,来进行设备ID的恢复。大致策略是对设备的一些重要字段进行对比,综合设备间的对比结果来判定是否可以获取到相似度极高的设备。通过这种方式来对设备进行一个概率性的恢复。 这种方案的优点很明显,不是依赖一个或者一组数据来进行恢复,而是依靠一个设备的全量(或者大部分)指标来进行恢复的,并且这种相似性的计算规则可以进行迭代华的持续演进,及时适用新环境;它的缺点就是可能产生碰撞,而且无法对数据修改较多的设备进行恢复。 完美方案 在笔者看来,设备指纹的完美解决方案是由系统提供者来处理的。底层系统提供者(谷歌、ROM厂商、硬件厂商等)可以在系统底层设定不可更改的标识信息,在硬件层烧制不可更改的标识符。在最底层,它们一方面拥有极高的系统权限,另一方面可以在系统层面上抵抗绝大部分侵入。由这些底层系统提供者提供的标识信息相对来说会靠谱得多。

May 8, 2025 · 1 min · Lotty