Artykuł

freeimages.com freeimages.com
lut 06 2015
0

Universal apps - jak zidentyfikować urządzenie?

Ostatnio w pracy miałem do rozwikłania pewien banalny problem (przynajmniej tak mi się pierwotnie wydawało). Moim zadaniem było znalezienie programowego rozwiązania, które w sposób jednoznaczny pozwoli zidentyfikować smartfon z systemem Windows Phone. Aplikacja wykorzystywała architekturę WinRT (Universal Apps).

Na potencjalne rozwiązanie wpadłem stosunkowo szybko. Postanowiłem skorzystać z adresu MAC (odbiornik WiFi/moduł GSM). I wszystko byłoby w porządku, gdyby nie fakt, że nie można tego adresu w żaden normalny sposób wyciągnąć za pomocą kodu.. Musiałem więc poszukać innego rozwiązania. Na szczęście się udało, a wszystko to dzięki klasie HardwareIdentification.

App Specific Hardware ID

Klasa HardwareIdentification to statyczna klasa, która posiada tylko jedną, ale niezwykle ważną metodę GetPackageSpecificToken. Za pomocą tej konstrukcji możemy pobrać tzw. App Specific Hardware Id (id urządzenia specyficzny dla aplikacji). ASHID składa się z maksymalnie 9 komponentów:

  1. Id procesora
  2. Wielkość pamięci
  3. Numer seryjny dysku twardego
  4. Adapter sieciowy (adres MAC)
  5. Adapter audio
  6. Stacja dokująca
  7. Bluetooth
  8. Id urządzenia mobilnego
  9. BIOS

Ich dostępność uzależniona jest w praktyce od samego urządzenia. Warto również zwrócić uwagę, że niektóre z nich mogą zmieniać się w czasie - np. stacja dokująca (podłączenie/odłączenie takowej), czy bluetooth (podłączenie/odłączenie urządzenia bezprzewodowego). Oczywiście większe ryzyko zmiany komponentów, mamy w przypadku komputera stacjonarnego.

Każdy z komponentów zapisywany jest za pomocą 4 bajtów. 2 pierwsze bajty identyfikują rodzaj komponentu, natomiast dwa kolejne określają wartość tego elementu. Poniższy zapis przechowuje informację o dysku twardym:

3,0,136,162

Tyle teorii. Sprawdźmy teraz jak ten mechanizm funkcjonuje w praktyce.

ASHID w praktyce

Wywołanie metody GetPackageSpecificToken jest całkiem proste. Wystarczy bowiem wywołać tą konstrukcję z parametrem null, bądź też przekazać tzw. parametr nounce - przydatny w sytuacji gdy usługa weryfikacji tokenu wystawiona jest do chmury (zabezpieczenie przed tzw. replay attacks).

W praktyce bardzo często wykorzystuje się odrobinę rozszerzone rozwiązanie, które przekształca pobrany token do postaci stringa, który później można łatwo zapisać np. w bazie danych, czy ustawieniach lokalnych aplikacji. Poniżej kod (znaleziony na stackoverflow)

private string GetPackageSpecificTokenString()
{
    var token = HardwareIdentification.GetPackageSpecificToken(null);
    var hardwareId = token.Id;
    var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);

    byte[] bytes = new byte[hardwareId.Length];
    dataReader.ReadBytes(bytes);

    return BitConverter.ToString(bytes);
}

Takie rozwiązanie zwraca token w postaci, które jest odrobinę bardziej czytelna dla przeciętnego człowieka:

03-00-88-A2-08-00-0A-41-05-00-47-67-05-00-3A-78-05-00-64-7B-05-00-B8-8C-05-00-04-D1-
06-00-01-00-04-00-22-D6-04-00-F2-E9-04-00-12-FB-01-00-B0-67-02-00-EA-B7-09-00-AA-C2

Taki token dużo łatwiej jest zapisać;-)

ASHID - dobre praktyki

ASHID jest bardzo podatny na zmiany, dlatego też jeśli używamy tej wartości do jednoznacznej weryfikacji urządzenia, możemy powziąć pewne kroki, które przyczynią się do pewnej stałości tego tokenu.

Jednym z wariantów jest zignorowanie niektórych sekcji. Np. w sytuacji gdy użytkownik korzysta z hybrydy, istnieje duże prawdopodobieństwo, że nasza metoda może zostać wywołana zarówno w sytuacji gdy ma on podłączoną stację dokującą oraz gdy z niej nie korzysta. Podobnie będzie z bluetooth - dlatego też w moim odczuciu można te dwie sekcje pominąć - sprowadzając token do stringa, wystarczy wywołać odpowiedni Regex (tutaj przykład dla bluetooth):

string token = this.GetPackageSpecificTokenString();
// usunięcie myślników
token = token.Replace("-", "");
token = Regex.Replace(token, @"0800\w{4}", string.Empty);

Alternatywnie możemy zapisywać token do lokalnych ustawień użytkownika. Dzięki temu, token pobierzemy tylko raz i będziemy mogli z niego korzystać do czasu, aż użytkownik nie usunie aplikację. Więcej na ten temat przeczytacie w tym artykule MSDN.

Oczywiście nic nie stoi na przeszkodzie, żeby obie te metody połączyć;-)

Uwaga!

Korzystając z tego mechanizmu warto zwrócić uwagę jeszcze na dwie rzeczy:

  • Jeśli mamy więcej niż jedno urządzenie określonego typu, to metoda zwróci osobne 4 bajty dla każdego takiego urządzenia
  • Wartości zwrócone przez metodę mogą być nieuporządkowane. Zawsze będą to 4 bajty, aczkolwiek najpierw może pojawić się informacja o karcie sieciowej, później o bluetooth, a następnie o drugiej karcie itd.

Źródła

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus