- 標識性參數——Android ID、IMEI、OAID
- 非標識性參數
- 非標識性參數——手機運營商
1 設備指紋
簡單來講,設備指紋是指用于標識出該設備的設備特征。可以是單一設備特征,也可以是多種設備特征的組合,以方便風控系統對設備的唯一性進行識別。設備指紋是風控系統里一個重要的控制維度。
設備指紋應該保證同一臺設備生成的設備指紋具有唯一性、不重復性和不易篡改性。
1.1 設備指紋的應用
在黑產對抗、反欺詐等領域中,設備指紋已經成為了基礎技術。
例如,網絡支付公司的風險管理系統引入設備指紋指紋技術,可貫穿于所有需要風險判斷的場景。比如,垃圾注冊,如果同一設備注冊次數過多或注冊時間異常,即發出風險警報或進入二次驗證過程,防止拖庫撞庫的風險行為;當支付時,同一設備支付金額過大或頻繁交易,那么就要警惕是否有洗錢的風險。支付環節需求嚴格管控,傳統的IP容易偽造代理等,并且精度不夠細,設備指紋完美地補充了這一風險漏洞。
問題1:既然最終使用的設備控制權在用戶(黑產)手上,那設備風控到底還有什么意義?
設備風控不僅僅包含設備指紋這一項,還有例如對設備是否ROOT、設備是否被修改(Xposed/Frida/定制ROM)、設備運行狀態、設備網絡狀態等等更全面的信息采集。
設備指紋在高強度對抗的情況下,確實意義不大。從定制Hook框架到定制ROM,以致于到了更底層Linux內核的修改后,設備指紋其實已經失去了原本的意義。因為從理論上來說一切可以采集的參數均是來自于系統接口、內核接口以及特定的行為痕跡,綜上所述一切參數在特定情況下都是可偽造的。但不可否認的是,設備指紋對于增加黑產對抗難度和某些特定場景的標識,還是具有一定作用的。
任何一層均有黑產作案的可能性
1.2 設備指紋常見技術
在設備風控領域,從最初簡單的設備指紋、存儲ID到本地文件這種簡單方法,到后來出現的采集很多ID參數云端識別,再到現在的基于設備的非標識性參數進行關聯分析的方案,黑產和風控的對抗是一步步不斷進化和不斷迭代的過程。
問題2:什么是基于非標識性參數的關聯分析識別?
所謂的基于非標識性參數的關聯分析識別,就是基于多個不帶標識類的參數進行配合識別的技術,行業內常稱為‘關聯檢測’。
標識符類參數:IMEI、MAC地址、oaid這一類本身對設備的具有唯一性、標識性的參;
非標識類參數:除了上述類型以外的,不具有唯一性或者標識性的設備參數;如,網絡類型(WiFi/4G/3G)、電池電量信息、內存大小等
1.單一/簡單組合特征
最開始應用設備指紋大概應該是廣告行業。在廣告行業里很早就開始收集瀏覽器的cookie、安卓系統的IMEI和MAC來識別設備的唯一性以便過濾假量刷量。
特點:收集客戶端可以收集的唯一標識,只要有一個標識相同就視為同一臺設備
缺點:方法比較原始,只需要簡單篡改標識就可以輕松過掉
2.關聯檢測:基于設備的非標識性參數進行關聯分析
從設備上收集多種多維度的設備信息和特征符,通過云端對比識別設備差異度,設定一個差異度閥值,當差異度比較低時則視為同一個設備。
特點:多種維度配合,不依賴于某一個特征或者標識符
市面上大多數的產品均是采用這種方式,具體效果決定于特征的多樣性和對比算法的準確性
2 如何獲取設備信息?
2.1 設備唯一標識符 UDID
設備唯一標識符 UDID(Unique Device Identifier):可以唯一標識設備的標識符都可稱為UDID。
2.1.1 Android ID
16進制字符串(64bit 16*4)不具備一致性;
設備首次啟動時,系統會隨機生成一個64位16進制字符串,這個16進制的字符串就是ANDROID_ID,當設備被恢復出廠設置后該值會被重置。
- Android低板本可以作為候補;
- Android O( Android8.O以上)時,ANDROID_ID的行為將發生變化。每個用戶在手機上的每個應用的ANDROID_ID都不同。ANDROID_ID根據應用簽名和用戶的不同而不同。 ANDROID_ID的唯一決定于應用簽名、用戶和設備三者的組合。
獲取方法:
//不需要任何權限
public static String getAndroidID(Context context) {String androidID = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);Log.i("Identifier", "AndroidID:" + androidID);return "AndroidID:" + androidID;
}
2.1.2 IMEI、MEID
IMEI和MEID其實都是用來標識設備的識別碼,可通過撥打*#06# 查詢。?具有一致性;
不同的是IMEI標識的是支持GSM網絡制式的設備,MEID標識的是支持CDMA網絡制式的設備。
什么是GSM和CDMA呢? CDMA和GSM簡單點說其實就是使用了不同的通信技術,以下表格顯示了各大運營商所使用的通信技術
IMEI、MEID是設備相當于我們手機的身份證號碼,是寫在主板上的,除非更換主板,否則只要有權限獲取,任意APP、任意系統版本下獲取的IMEI都是一致的。而現在我們的手機大都是雙卡雙待,可以同時插入兩張同時支持GSM網絡、CDMA網絡的卡,所以就出現一部手機有兩個IMEI號,兩個MEID號碼。所以這些手機IMEI和MEID號碼都有。
注意:IMEI和MEID是標識手機設備,跟我們手機插什么卡沒有關系。
獲取方法:
/**
Android版本小于6.0,安卓APP需要申請用戶電話授權,才獲取: getDeviced()
Android [6.0,10.0],安卓APP需要動態申請用戶電話授權,才能獲取IMEI。<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />Android [6.0,8.0) : telManager.getDeviceId();Android [8.0,10.0): telManager.getImei(0)、 telManager.getImei(0);
Android 10以上無法獲取;(即使申請了 READ_PHONE_STATE 權限)
**///telManager.getDeviceId();該方法得到的并不一定是IMEI。對于只有GSM制式的手機是得到的是IMEI,對于只有CDMA制式的手機,返回的是ESN或MEID。public static String getIMEI(Context context){TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {//Android 8: This method was deprecated in API level 26.String IMEI = telManager.getDeviceId();Log.i("Identifier", "IMEI:" + IMEI);return "IMEI:" + IMEI;} else if(Build.VERSION.SDK_INT>Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){//Android 8: These methods were added in API level 26.String imei1 = telManager.getImei(0);String imei2 = telManager.getImei(1);Log.i("Identifier", "IMEI卡槽1:" + imei1);Log.i("Identifier", "IMEI卡槽2:" + imei2);String meid1 = telManager.getMeid(0);String meid2 = telManager.getMeid(1);Log.i("Identifier", "MEID卡槽1為:" + meid1);Log.i("Identifier", "MEID卡槽2為:" + meid2);return "IMEI卡槽1:" + imei1 + "IMEI卡槽2:" + imei2 + "MEID卡槽1為:" + meid1 + "MEID卡槽2為:" + meid2;} else {try{String imei1 = telManager.getImei(0);String imei2 = telManager.getImei(1);Log.i("Identifier", "IMEI卡槽1:" + imei1);Log.i("Identifier", "IMEI卡槽2:" + imei2);String meid1 = telManager.getMeid(0);String meid2 = telManager.getMeid(1);Log.i("Identifier", "MEID卡槽1為:" + meid1);Log.i("Identifier", "MEID卡槽2為:" + meid2);return "IMEI卡槽1:" + imei1 + "IMEI卡槽2:" + imei2 + "MEID卡槽1為:" + meid1 + "MEID卡槽2為:" + meid2;}catch (Exception e){Log.i("Identifier", e + "Android10及以上版本禁止獲取IMEI");return e + "Android10及以上版本禁止獲取IMEI";}}}
2.1.3 OAID
匿名設備標識符:16進制字符串(256bit 64*4)具有一致性;
OAID字段是由中國信通院聯合華為、小米等廠商共同推出的設備識別字段,具有唯一性和權威性,可滿定用戶行為統計的使用場景。一種在國行系統內使用的、應對 Android 10 限制讀取 IMEI 的廣告跟蹤標識符。
(同一設備不同應用的OAID相同)發生幾種情況發生時,OAID重置:
- 用戶在系統設置中手動重置,匿名設備標識符將重置;
- 移動智能終端恢復出廠設置時,匿名設備標識符將重置;
- 匿名設備標識符自身可定期重置。
另外,用戶還可以自主關閉匿名設備標識符,關閉后返回值的值是NO。
獲取方法:
在這里插入代碼片
2.1.4 SN號(設備序列號)?
SN號(設備序列號)?:可通過撥打*#06# 查詢(華為)。
在Android 7.1或更早系統(SDK<=25),可通過android.os.Build.SERIAL獲得,由廠商提供。?
如果廠商比較規范的話,設備序列號+Build.MANUFACTURER應該能唯一標識設備UDID。但現實是并非所有廠商都按規范來,尤其是早期的設備。?最致命的是,Android 8.0及 以上(SDK>=26),android.os.Build.SERIAL 總返回 “unknown”;若要獲取序列號,可調用Build.getSerial() ,但是需要申請 READ_PHONE_STATE 權限。?
到了Android 10.0(SDK>=29)以上,則和IMEI一樣,也被禁止獲取了。?
2.1.5 Mac地址
大多android設備都有wifi模塊,因此,wifi模塊的MAC地址就可以作為設備標識。基于隱私考慮,官方不建議獲取
獲取MAC地址也是越來越困難了,Android 6.0以后通過 WifiManager 獲取到的mac將是固定的:02:00:00:00:00:00
7.0之后讀取 /sys/class/net/wlan0/address 也獲取不到了(小米6)。
獲取MAC地址的方法有兩種:
(1). 通過Linux命令查詢
public String getMacAddress() {String macAddress = null ;String str = "" ;try {//linux下查詢網卡mac地址的命令Process pp = Runtime.getRuntime().exec( "cat /sys/class/net/wlan0/address" );InputStreamReader ir = new InputStreamReader(pp.getInputStream());LineNumberReader input = new LineNumberReader(ir);for (; null != str;) {str = input.readLine();if (str != null ) {macAddress = str.trim(); // 去空格break ;}}} catch (IOException ex) {ex.printStackTrace();}return macAddress;
}
缺點:在當前沒打開WiFi的情況下獲取得到的MAC地址值為空,即使在執行這段代碼前是有打開過WiFi,而執行這段代碼時WiFi狀態是關閉的,也不能獲取到MAC地址。
(2). 通過Android官方的WifiManager類獲取
public String getMacAddress() {String macAddress = null ;WifiManager wifiManager =(WifiManager)MyApplication.getContext().getSystemService(Context.WIFI_SERVICE);WifiInfo info = ( null == wifiManager ? null : wifiManager.getConnectionInfo());macAddress = info.getMacAddress();return macAddress;
}需要加入權限
< uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" />
缺點:這種方法雖然能在當前Wifi狀態為關閉的情況下獲取到MAC地址,但前提是在手機開機后要打開過一次Wifi,如果在某次開機后沒打開過Wifi就調用這段代碼,獲取地址也是為空。
網上給出的解釋是:WiFi的Mac address是一個被動資訊。一般在開機后,不會主動上報到系統裡。要待WiFi硬件啟動后,才會把有關Mac address資料記載入系統去。
轉載鏈接
AndroidID、IMEI、OAID獲取:https://blog.csdn.net/Myfittinglife/article/details/121520111
Android風控知識:https://bbs.kanxue.com/thread-279619.htm、https://bbs.kanxue.com/thread-275202.htm
常見參數講解:https://bbs.kanxue.com/thread-265169.htm