DeviceId в KMP - какие есть варианты?

Как известно, в Android есть такая штука как ANDROID_ID - некий уникальный идентификатор, который генерируется в недрах ОС как функция юзера, идентификатора приложения подписи приложения. Извлекается через:

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);

В целом, считается довольно надежным способом идентификатора конкретного устройства, которое доступно только собственно самому приложению - сторонние пакеты (в нормальных условиях разумеется) - не имеют к нему доступа. Чем обычно и пользуются часто используя его как ключ шифрования (после соления и проч.)

Ближе к делу: есть обычное Android приложение в котором сей ключик используется как ключ шифрования. Приложение решено переписать под KMP (Android + JVM + WASM + iOS).

Внимание вопрос: какие есть варианты генерации/использования ключа/идентификатора для указанных платформ. Ну то есть имеем:

expect fun getUniqueId(any: Any): String

Ожидаем:

actual fun getUniqueId(any: Any): String = ???

Если можно, то без традиционного флейма: а зачем вам ANDROID_ID в качестве ключа и т.д.


Ответы (1 шт):

Автор решения: schmidt9

Создал тестовый проект для проверки возможностей генерации уникального идентификатора на указанных Вами платформах, поскольку данный вопрос меня тоже в перспективе интересует (https://github.com/schmidt9/GetDeviceID)

Краткое резюме и субъективная оценка:

  • Для Андроида использовал упомянутый Вами способ с Secure.ANDROID_ID, способ достаточно надежный, хотя и не одобряется Гуглом
  • Для iOS использовал библиотеку FCUUID (ссылка), способ достаточно надежный с оговоркой касательно сброса устройства (подробнее)
  • Для JVM использовал библиотеку OSHI (ссылка), способ отсюда. Надежность субъективно ниже чем для мобильных платформ в силу того, что способ основан на произвольных идентификаторах, которые могут меняться, код из ответа
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

class ComputerIdentifier
{
    static String generateLicenseKey()
    {
        SystemInfo systemInfo = new SystemInfo();
        OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
        HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
        CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
        ComputerSystem computerSystem = hardwareAbstractionLayer.getComputerSystem();

        String vendor = operatingSystem.getManufacturer();
        String processorSerialNumber = computerSystem.getSerialNumber();
        String processorIdentifier = centralProcessor.getIdentifier();
        int processors = centralProcessor.getLogicalProcessorCount();

        String delimiter = "#";

        return vendor +
                delimiter +
                processorSerialNumber +
                delimiter +
                processorIdentifier +
                delimiter +
                processors;
    }
}

Зависимость:

implementation("com.github.oshi:oshi-core:6.5.0")
  • Для WASM использовалась генерация UUID window.crypto.randomUUID() и его сохранение в браузере, кажется самый ненадежный способ из всех платформ в силу ограничений браузера, каких-то принципиально иных достаточно надежных способов не обнаружилось
→ Ссылка