2011-12-28 13 views
7

Pobieram dane z zewnętrznego serwera do użytku z moją aplikacją na Androida. Chciałbym, aby te dane były dostępne tylko dzięki mojej aplikacji. Używam standardowego połączenia HTTP do pobierania danych z serwera apache/php w formacie json. Wysyłam także kilka parametrów do serwera, aby pobrać odpowiednie dane. Teraz, co mam zamiar zrobić, to:Sprawdź, czy żądanie http pochodzi z mojej aplikacji na Androida

  1. Wyślij params
  2. wysłać coś podobnego md5 ("someSecretPhrase" + params).
  3. Sprawdź, czy tajne wyrażenie jest poprawne po stronie serwera.

Teraz pytanie brzmi - czy jest to bezpieczne podejście do inżynierii wstecznej? Na razie nie mogę wymyślić żadnej innej możliwości uzyskania tych danych. Ale jeśli ktoś jest w stanie zdekompilować mój apk, będzie mógł również odzyskać tę "someSecretPhrase" (raczej trudne do zrobienia po stronie serwera), a następnie uzyskać dostęp do serwera, prawda? Czy to prawdziwe zagrożenie? Czy jest jakaś inna możliwość uwierzytelnienia mojej aplikacji przez serwer?

Spojrzałem na forach, np. Identify whether HTTP requests from Android App or not? and then respond appropriately, ale nie wyjaśniają problemu dekompilacji.

Odpowiedz

7

Jedną z podstawowych zasad bezpieczeństwa: nie ufasz danym klienta. Zawsze.

Należy rozważyć aplikacja dekompilować, wszystkie „tajne” klucze znane atakujący itp

Można jednak utrudnić próby atakującego do wypracowania swoich żądań. Wysyłanie (i weryfikacja) sumy kontrolnej twojego żądania jest jedną z metod (twój pomysł na MD5(secret_key + params)).

Można również przełączyć na binarny protokół szyfrowany. Ale wymaga to DUŻO więcej pracy i całkiem innej architektury serwera.

+0

Zaczynam od udostępnionego hostingu, więc inna architektura na serwerze prawdopodobnie nie jest dla mnie opcją. Te dane nie są podatne na zagrożenia (bez numerów kart kredytowych klienta), ale będzie to wymagało dużo pracy, aby je zebrać (i będzie ono gromadzone w sposób ciągły), więc byłoby naprawdę źle, gdyby ktoś mógł po prostu skopiować mój pomysł i wykorzystać dane. .. –

+1

Cóż, jeśli twój serwer odpowiada pewnymi danymi, powinieneś uznać to za publiczne. Oprócz dekompilowania aplikacji i fałszowania próśb, osoba atakująca może po prostu użyć serwera proxy i przesłać dane, które wyślesz do legalnej aplikacji. –

+0

Tak więc, jeśli dobrze cię zrozumiałem, jedyną opcją, aby zrobić to bezpiecznie, jest użycie szyfrowanego połączenia między serwerem a aplikacją. Https byłoby ok? Rozumiem, że nie jest tak łatwy w użyciu. Ale jakie są inne wady? To znacznie wolniej, prawda? Po prostu próbuję sprawdzić, czy bezpieczeństwo tych danych jest warte wysiłku. –

1

Niestety, jeśli ktoś dekompiluje twój apk, wtedy może łatwo zobaczyć twoje struny.

EDIT: Nie sądzę, istnieje lepszy sposób to zrobić .. może tylko opublikować swoją aplikację na Android Market z android Ochrony kopiowania włączone ...

+0

Dziękuję za szybką odpowiedź. Zdaje się, że dekompilacja jest dość prostym procesem? Chodzi mi o to, że nie powinienem opierać się na założeniu, że nie zostanie on zdekompilowany? Hmm, musi istnieć inne rozwiązanie ... –

+1

Możesz uwierzytelniać użytkowników, nie możesz uwierzytelniać aplikacji, możesz zrobić to trudniej, ale pod koniec dnia wysyłasz kod i tajemnice do złych . – superfell

+0

Tak, prawdopodobnie przejdę przez to lub zainwestuję w szyfrowanie, gdy dane potwierdzą jego wartość. To powiedziawszy, jestem zaskoczony, że tak trudno jest to osiągnąć –

2

Twoja aplikacja wykonuje uzgadnianie z serwerem, więc algorytm to nie tylko ciąg znaków, ale cały proces. Zastosowanie Sesje/baz danych do śledzenia handshake

+1

A handshake jest wykonywany przez ssl, prawda? Więc byłoby to dokładnie to samo, o czym wspomnieliśmy w komentarzach eralier (nie chodzi tu o sumę kontrolną). Ale dobrze jest wiedzieć, że to się nazywa uścisk dłoni, dzięki! –

1

Można ukryć linki przez ustawić wszystkie linki URL i nazw Parametrów w strings.xml na przykład: http://wwww.yourdomain.com/yourpage.any nazwa_użytkownika i dostać url takich adresem:

String serverUrl = Resources.getsystem().getstring(R.strings.name_your_link_id); String parameterKey = Resources.getsystem().getstring(R.strings.name_your_parameter_id); Uri url = Uri.parse(serverUrl+"?"+parameterKey+"=" + yorusername);

i wykonaj dowolne żądanie http: HttpURLConnection con = (HttpURLConnection) url.openConnection();

gdy ktoś próbować dekompilować aplikacji pokaże jedynym identyfikatorem tak długo całkowitą w pliku R.java uzyskać taki kod to String serverUrl = Resources.getsystem().getstring(12346546564); String parameterKey = Resources.getsystem().getstring(123321321132);

+1

Ale myślę, że to tylko sprawi, że będzie to trochę bardziej uciążliwe, niemożliwe do zdobycia. Zasoby ciągów znajdują się wewnątrz pliku resources.arsc po rozpakowaniu pliku * .apk. Są więc nadal związane z tymi liczbami. Ale +1 za interesujący pomysł –

1

Android wymaga, że ​​należy sign swoją aplikację (organ zalogowaniem lub własnym znakiem) zanim będzie można go zainstalować. Możemy to wykorzystać, aby sprawdzić, czy żądania pochodzą z Twojej aplikacji, czy nie.

  1. Podpisz swoją aplikację za pomocą swojego certyfikatu.
  2. Find podpis certyfikatu i zapisz go na serwerze zaplecza.
  3. Dla każdego wniosku należy oczekiwać, że ten podpis zostanie wysłany przez aplikację.
  4. sprawdź podpis wysłany przez aplikację na poziomie serwera i akceptuj tylko wtedy, gdy są zgodne.

Nawet w takim przypadku, gdy ktoś narusza twoją aplikację, musi ją podpisać ponownie, zanim będzie można ją zainstalować, co zmieniłoby podpis aplikacji, a nasz mechanizm walidacji odrzuciłby wszystkie takie żądania.

Ta odpowiedź jest oparta na blogu this. Użyj https dla aplikacji < -> komunikacja z serwerem.

+1

Ale każdy może użyć kodu podpisu, aby znaleźć hasz aplikacji za pomocą nazwy pakietu aplikacji i może rozpocząć wysyłanie tego skrótu w przyszłym żądaniu. W jaki sposób ten podpis czyni aplikację bezpieczną? –

+0

Jak zrobić krok 3, czy jest to domyślne zachowanie systemu operacyjnego Android? –

Powiązane problemy