美文网首页
android_id 生成原理

android_id 生成原理

作者: that_is_this | 来源:发表于2020-04-16 23:01 被阅读0次

android_id 的生成原理是由系统生成的随机数,并与应用 app 签名,经过 HmacSHA256 算法生成的;
从 android 8 以后开始就是随机的了,每个应用获取到的简要步骤;

下面是追踪代码:

2423          public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) {
2424              // Read the user's key from the ssaid table.
2425              Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2426              if (userKeySetting == null || userKeySetting.isNull()
2427                      || userKeySetting.getValue() == null) {
2428                  // Lazy initialize and store the user key.
2429                  generateUserKeyLocked(userId);
2430                  userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2431                  if (userKeySetting == null || userKeySetting.isNull()
2432                          || userKeySetting.getValue() == null) {
2433                      throw new IllegalStateException("User key not accessible");
2434                  }
2435              }
2436              final String userKey = userKeySetting.getValue();
2437  
2438              // Convert the user's key back to a byte array.
2439              final byte[] keyBytes = ByteStringUtils.fromHexToByteArray(userKey);
2440  
2441              // Validate that the key is of expected length.
2442              // Keys are currently 32 bytes, but were once 16 bytes during Android O development.
2443              if (keyBytes == null || (keyBytes.length != 16 && keyBytes.length != 32)) {
2444                  throw new IllegalStateException("User key invalid");
2445              }
2446  
2447              final Mac m;
2448              try {
2449                  m = Mac.getInstance("HmacSHA256");
2450                  m.init(new SecretKeySpec(keyBytes, m.getAlgorithm()));
2451              } catch (NoSuchAlgorithmException e) {
2452                  throw new IllegalStateException("HmacSHA256 is not available", e);
2453              } catch (InvalidKeyException e) {
2454                  throw new IllegalStateException("Key is corrupted", e);
2455              }
2456  
2457              // Mac each of the developer signatures.
2458              for (int i = 0; i < callingPkg.signatures.length; i++) {
2459                  byte[] sig = callingPkg.signatures[i].toByteArray();
2460                  m.update(getLengthPrefix(sig), 0, 4);
2461                  m.update(sig);
2462              }
2463  
2464              // Convert result to a string for storage in settings table. Only want first 64 bits.
2465              final String ssaid = ByteStringUtils.toHexString(m.doFinal()).substring(0, 16)
2466                      .toLowerCase(Locale.US);

追踪看写入代码:


2724          public Setting getSettingLocked(int type, int userId, String name) {
2725              final int key = makeKey(type, userId);
2726  
2727              SettingsState settingsState = peekSettingsStateLocked(key);
2728              if (settingsState == null) {
2729                  return null;
2730              }
2731  
2732              // getSettingLocked will return non-null result
2733              return settingsState.getSettingLocked(name);
2734          } 


    
2860          @Nullable
2861          private SettingsState peekSettingsStateLocked(int key) {
2862              SettingsState settingsState = mSettingsStates.get(key);
2863              if (settingsState != null) {
2864                  return settingsState;
2865              }
2866  
2867              if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
2868                  return null;
2869              }
2870              return mSettingsStates.get(key);
2871          }



2585          private void ensureSettingsStateLocked(int key) {
2586              if (mSettingsStates.get(key) == null) {
2587                  final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
2588                  SettingsState settingsState = new SettingsState(getContext(), mLock,
2589                          getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
2590                  mSettingsStates.put(key, settingsState);
2591              }
2592          }


252      public SettingsState(Context context, Object lock, File file, int key,
253              int maxBytesPerAppPackage, Looper looper) {
254          // It is important that we use the same lock as the settings provider
255          // to ensure multiple mutations on this state are atomicaly persisted
256          // as the async persistence should be blocked while we make changes.
257          mContext = context;
258          mLock = lock;
259          mStatePersistFile = file;
260          mStatePersistTag = "settings-" + getTypeFromKey(key) + "-" + getUserIdFromKey(key);
261          mKey = key;
262          mHandler = new MyHandler(looper);
263          if (maxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_LIMITED) {
264              mMaxBytesPerAppPackage = maxBytesPerAppPackage;
265              mPackageToMemoryUsage = new ArrayMap<>();
266          } else {
267              mMaxBytesPerAppPackage = maxBytesPerAppPackage;
268              mPackageToMemoryUsage = null;
269          }
270  
271          mHistoricalOperations = Build.IS_DEBUGGABLE
272                  ? new ArrayList<>(HISTORICAL_OPERATION_COUNT) : null;
273  
274          synchronized (mLock) {
275              readStateSyncLocked();
276          }
277      }


跳到创建成功时,获取代码

337      // The settings provider must hold its lock when calling here.
338      @GuardedBy("mLock")
339      public Setting getSettingLocked(String name) {
340          if (TextUtils.isEmpty(name)) {
341              return mNullSetting;
342          }
343          Setting setting = mSettings.get(name);
344          if (setting != null) {
345              return new Setting(setting);
346          }
347          return mNullSetting;
348      }


157      @GuardedBy("mLock")
158      private final ArrayMap<String, Setting> mSettings = new ArrayMap<>();


新 setting 元素来自于新的插入;
384      // The settings provider must hold its lock when calling here.
385      @GuardedBy("mLock")
386      public boolean insertSettingLocked(String name, String value, String tag,
387              boolean makeDefault, boolean forceNonSystemPackage, String packageName) {
388          if (TextUtils.isEmpty(name)) {
389              return false;
390          }
391  
392          Setting oldState = mSettings.get(name);
393          String oldValue = (oldState != null) ? oldState.value : null;
394          String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null;
395          Setting newState;
396  
397          if (oldState != null) {
398              if (!oldState.update(value, makeDefault, packageName, tag, forceNonSystemPackage)) {
399                  return false;
400              }
401              newState = oldState;
402          } else {
403              newState = new Setting(name, value, makeDefault, packageName, tag);
404              mSettings.put(name, newState);




3602                  if (currentVersion == 136) {
3603                      // Version 136: Store legacy SSAID for all apps currently installed on the
3604                      // device as first step in migrating SSAID to be unique per application.
3605  
3606                      final boolean isUpgrade;
3607                      try {
3608                          isUpgrade = mPackageManager.isDeviceUpgrading();
3609                      } catch (RemoteException e) {
3610                          throw new IllegalStateException("Package manager not available");
3611                      }
3612                      // Only retain legacy ssaid if the device is performing an OTA. After wiping
3613                      // user data or first boot on a new device should use new ssaid generation.
3614                      if (isUpgrade) {
3615                          // Retrieve the legacy ssaid from the secure settings table.
3616                          final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE,
3617                                  userId, Settings.Secure.ANDROID_ID);
3618                          if (legacySsaidSetting == null || legacySsaidSetting.isNull()
3619                                  || legacySsaidSetting.getValue() == null) {
3620                              throw new IllegalStateException("Legacy ssaid not accessible");
3621                          }
3622                          final String legacySsaid = legacySsaidSetting.getValue();
3623  
3624                          // Fill each uid with the legacy ssaid to be backwards compatible.
3625                          final List<PackageInfo> packages;
3626                          try {
3627                              packages = mPackageManager.getInstalledPackages(
3628                                  PackageManager.MATCH_UNINSTALLED_PACKAGES,
3629                                  userId).getList();
3630                          } catch (RemoteException e) {
3631                              throw new IllegalStateException("Package manager not available");
3632                          }
3633  
3634                          final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
3635                          for (PackageInfo info : packages) {
3636                              // Check if the UID already has an entry in the table.
3637                              final String uid = Integer.toString(info.applicationInfo.uid);
3638                              final Setting ssaid = ssaidSettings.getSettingLocked(uid);        // 这里呢?
3639  
3640                              if (ssaid.isNull() || ssaid.getValue() == null) {
3641                                  // Android Id doesn't exist for this package so create it.
3642                                  ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
3643                                          info.packageName);
3644                                  if (DEBUG) {
3645                                      Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
3646                                  }
3647                              }
3648                          }
3649                      }
3650  
3651                      currentVersion = 137;





这个插入代码?

http://www.aospxref.com/android-10.0.0_r2/xref/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java#2400

3002          @GuardedBy("secureSettings.mLock")
3003          private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) {
3004              Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID);
3005  
3006              if (!value.isNull()) {
3007                  return;
3008              }
3009  
3010              final int userId = getUserIdFromKey(secureSettings.mKey);
3011  
3012              final UserInfo user;
3013              final long identity = Binder.clearCallingIdentity();
3014              try {
3015                  user = mUserManager.getUserInfo(userId);
3016              } finally {
3017                  Binder.restoreCallingIdentity(identity);
3018              }
3019              if (user == null) {
3020                  // Can happen due to races when deleting users - treat as benign.
3021                  return;
3022              }
3023  
3024              String androidId = Long.toHexString(new SecureRandom().nextLong());       // 这里就是了
3025              secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
3026                      null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3027  
3028              Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
3029                      + "] for user " + userId);
3030  
3031              // Write a drop box entry if it's a restricted profile
3032              if (user.isRestricted()) {
3033                  DropBoxManager dbm = (DropBoxManager) getContext().getSystemService(
3034                          Context.DROPBOX_SERVICE);
3035                  if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
3036                      dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
3037                              + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n");
3038                  }
3039              }
3040          }


2400          private void generateUserKeyLocked(int userId) {
2401              // Generate a random key for each user used for creating a new ssaid.
2402              final byte[] keyBytes = new byte[32];
2403              final SecureRandom rand = new SecureRandom();
2404              rand.nextBytes(keyBytes);
2405  
2406              // Convert to string for storage in settings table.
2407              final String userKey = ByteStringUtils.toHexString(keyBytes);
2408  
2409              // Store the key in the ssaid table.
2410              final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
2411              final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null,      //这个 userkey 就是 value
2412                      true, SettingsState.SYSTEM_PACKAGE_NAME);
2413  
2414              if (!success) {
2415                  throw new IllegalStateException("Ssaid settings not accessible");
2416              }
2417          }





1417          // Retrieve the ssaid from the table if present.
1418          final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
1419                  name);
1420          // If the app is an Instant App use its stored SSAID instead of our own.
1421          final String instantSsaid;
1422          final long token = Binder.clearCallingIdentity();
1423          try {
1424              instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName,         // 这个就是 value ,怎么通过 intent 传递到的呢?
1425                      owningUserId);
1426          } catch (RemoteException e) {
1427              Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e);
1428              return null;
1429          } finally {
1430              Binder.restoreCallingIdentity(token);
1431          }
1432  
1433          final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
1434                  SETTINGS_TYPE_SSAID, owningUserId);
1435  
1436          if (instantSsaid != null) {
1437              // Use the stored value if it is still valid.
1438              if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
1439                  return mascaradeSsaidSetting(ssaidSettings, ssaid);
1440              }
1441              // The value has changed, update the stored value.
1442              final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
1443                      true, callingPkg.packageName);
1444              if (!success) {

相关文章

网友评论

      本文标题:android_id 生成原理

      本文链接:https://www.haomeiwen.com/subject/yxgjvhtx.html