2010-12-13 16 views
55

Po prostu zaciemniłem mój kod Android za pomocą proguard, a następnie go zhakowałem. Jest wiele strun, które chciałbym ukryć przed wzrokiem ciekawskich. Kiedy dekompilowałem kod, istniały ciągi znaków, które każdy mógł zobaczyć ... i zmienić. Jeden z ciągów jest adresem URL do mojego serwera licencjonowania i może w efekcie zmienić adres URL, tak aby wskazywał na fałszywy serwer (ponieważ będę wydawał kod serwera publicznie). Jaki jest najlepszy sposób ukrywania tego rodzaju informacji?Ukrywanie ciągów w zakodowanym kodzie

Zauważyłem również, że ciągi w klasie R są liczbami losowymi, ale nie mogę znaleźć klasy R w dekompilowanym kodzie. Gdzie to jest?

przykład Foe widzę: new SimpleCursorAdapter(localActivity, 2130903058, localCursor, arrayOfString, arrayOfInt);

2130903058 plik jest układ, ale co to jest odwołanie? Liczba nic nie znaczy, chyba że wskazuje na jakiś adres.

Odpowiedz

31

Zakładając, że jesteś zadowolony z niejasnych, a nie bezpiecznych, istnieje wiele mechanizmów, których możesz użyć, ale obfuscaters jak proguard nie będą w stanie Ci pomóc.

Aby to osiągnąć, należy wykonać kodowanie lub szyfrowanie samego struny, stosowane podejście zależy od tego, przed czym próbujesz się obronić, jeśli próbujesz ukryć się przed oczywistą inspekcją, kodowanie może być wystarczające (patrz android.util.Base64, http://developer.android.com/reference/android/util/Base64.html). Zauważ, że kodowanie jest BEZPIECZNE BEZPIECZNIE i wszystko, co trzeba, to usunięcie oczywistego odniesienia do twojej strony.

Jeśli próbujesz bronić przed czymś więcej, a następnie można przejść do rzeczywistości szyfrowanie ciąg, aby zrobić to byłoby użyć symetryczny szyfr AES jak poprzez javax.crypto.Cipher, http://www.androidsnippets.org/snippets/39/index.html zapewnia przyzwoitą Przykład użycia. Znowu jest to bardziej denerwujące, niż bezpieczne dla hakerów, ponieważ będziesz musiał przechowywać klucz gdzieś w swoim słoiku, negując w ten sposób zabezpieczenia kryptograficzne.

Aby to jaśniejsze, podstawowe kroki byłoby:

  1. ręcznie utworzyć zaszyfrować ciąg wykorzystaniem znanego klucza.
  2. Konwersja kodu użyć odszyfrowane wersję tego napisu, na przykład:

Przed:

public class Foo { 
    private String mySecret = "http://example.com"; 

    ... 
} 

Staje:

public class Foo { 
    private String encrypted = "<manually created encrypted string>"; 
    private String key = "<key used for encryption"; 
    private String mySecret = MyDecryptUtil.decrypt(encrypted, key); 

    ... 
} 

A (dobrze) alternatywa do tego wszystkiego rozważa użycie rozwiązania DRM innej firmy, takiego jak serwer licencyjny, google zapewnia http://android-developers.blogspot.com/2010/07/licensing-service-for-android.html. To może być bezpieczniejsze niż coś, co robisz sam, ale podlega bardzo podobnym ograniczeniom do tego, co opisałem powyżej.

+0

Co przechowywania pewnych plików klas na serwerze. Czy istnieje możliwość pobrania i zainstalowania nowych plików klas po zainstalowaniu aplikacji? Czy istnieje sposób, aby to zrobić w bezpieczny sposób, tj. Nie pozwalając komuś skopiować plików już zarejestrowanego urządzenia i po prostu je używać? – jax

+18

Możesz dodać kilka warstw, ale ostatecznie nie będziesz w stanie zapobiec ustalonemu hakerowi. W pewnym momencie lepiej zainwestować swój czas w resztę produktu, uczynić go wystarczająco dobrym (przeczytać wystarczająco wartościowo), a ludzie nie będą chcieli go ukraść. –

+3

"W końcu nie będziesz w stanie zapobiec ustalonemu hakerowi" -> To są najlepsze słowa w tym długim wątku.Mark ma rację, mówiąc, że najlepsze, co możemy zrobić, to zwolnić atakujących. – Krypton

0

Powinieneś google dla "Just another Perl hacker". Są to programy, które wypisują ciąg z zaciemnionym kodem. Istnieje również wiele przykładów w innych językach niż Perl w sieci.

Wikipedia entry

+0

tak, ale jeśli haker wie, że używał JAPH, to może łatwo odszyfrować klucz API? –

6

co zrobiłem było stworzyć długą listę ciągów statycznych w moim światowej klasy użytkowej. Gdzieś w długiej liście ciągów wprowadziłem mój klucz w wielu fragmentach.

z moim kodem łatwo zobaczyć, jakie są prawdziwe hasła - ale gdy obfuscator zacznie działać, wszystkie stany będą miały nazwy takie jak A, B, C itp. I nie będzie łatwo wykryć więcej .

+0

czy możesz podać przykładowy kod tego, co powiedziałeś. Dzięki – Sam

+2

Hi sam, po prostu stwórz publiczną klasę z całą masą publicznych statycznych zmiennych zmiennych1 = "fałszywych danych"; "kiedy mówię" cały bukiet "mam na myśli setkę tych Stringsów. Łatwo jest utworzyć taki plik za pomocą programu Excel. Następnie ukryj ważne dane wśród wszystkich "fałszywych" linii. Gdy obfuscator zacznie działać, wszystkie te dane będą wyglądać jak bałagan. Gdy chcesz użyć danych, połącz kilka pojedynczych Ciągów, aby odtworzyć to, co chcesz ukryć. Możesz pójść o krok dalej, zakodowując w pewien sposób te linie tekstu, aby wyglądał jeszcze bardziej jak bałagan. –

+0

chodzi o to, aby osoba, która wykonuje inżynierię wsteczną kodu, musi pracować nad tym. Im bardziej nie jesteś w stanie tego zrobić, tym większe prawdopodobieństwo, że nie jest to warte czasu. –

2

Użyłem ROT47. To nie jest bardzo bezpieczne, ale łatwe w użyciu i implementacji, ponieważ jest to symetryczny koder/dekoder

0

Możesz użyć DexGuard do szyfrowania ciągów, prawdopodobnie bardziej efektywnie niż można osiągnąć ręcznie, bez obciążania kodu źródłowego.

+6

, ale DexGuard nie jest bezpłatny –

+0

Myślę, że jest bezpłatny, możesz wysłać e-mail, aby uzyskać DexGuard –

+0

Czy możesz sprawdzić ponownie, ponieważ zgodnie z moją wiedzą nie jest on wolny? –

19

Witam wszystkich.

  1. Let secret być tekst chcesz ukryć

  2. Znajdź keyhash swojego debugowania/release.keystore. Niech ten klucz będzie oznaczony jako k1.

(narzędzi mechanicznych keytool + openssl: keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64 )

  1. Za pomocą narzędzia (na zewnątrz androidki kodzie) do szyfrowania secret z k1

    encrypted = encode (secret, k1)

(Na przykład: https://jwt.io, dla java: https://github.com/jwtk/jjwt).

  1. W swoim kodzie Java na Androida zapisz encrypted. Kiedy trzeba zakodowanej wersji encrypted (to, oryginalny secret) Napisać

original = decode(encrypted, get_my_keyhash_programmatically())

to wszystko. Działa to, ponieważ oryginalny kod secret nie jest wyświetlany w kodzie źródłowym java, ani nie jest kodowany przez k1. A jeśli haker chce wydrukować swój zdekodowany sekret, musi zmienić kod i skompilować, podpisując swój plik .apk swoim własnym magazynem kluczy, nie swoim, a tym samym nie uzyskując właściwego oryginalnego secret. ("Jedynym" punktem jest to, czy można uzyskać k1 z oryginalnego pliku .apk).

Uwaga: get_my_keyhash_programmatically():

try { 
    PackageInfo info = getPackageManager().getPackageInfo(
      "el nombre de su paquete por ejemplo com.tarea.u8", 
      PackageManager.GET_SIGNATURES); 
    for (Signature signature : info.signatures) { 
     MessageDigest md = MessageDigest.getInstance("SHA"); 
     md.update(signature.toByteArray()); 
     Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT)); 
    } 
} catch (PackageManager.NameNotFoundException e) { 

} catch (NoSuchAlgorithmException e) { 

} 
+0

Mówisz "Użyj narzędzia do zaszyfrowania sekretu przy użyciu k1 - na przykład: https://jwt.io." Jednak, gdy przejdę do jwt.io i spróbuję go użyć do utworzenia tokena z mojego własnego JSON-u, używając mojego własnego klucza (umieszczenie go w "tajnym" polu), po prostu mówi mi, że sekret jest nieważny. "secret" jest jedynym ciągiem, który akceptuje. W jaki sposób mogę utworzyć token za pomocą własnego klucza? – jkane001

+1

@Krypton jak co? daj mi przykład, proszę o sposób na przełamanie tego – Catalin

+4

Doświadczony haker powinien odwrócić kodowanie funkcji java() w ciągu około 5 minut, i mógł się domyślić, że jego skrót certyfikatu aplikacji jest używany do łatwego kodowania. Korzystając z frameworka hakowania, takiego jak XPosed, może on wyodrębnić wartość skrótu certyfikatu Twojej aplikacji w czasie wykonywania. Od tego momentu używa on tego skrótu do dekodowania wszystkich łańcuchów. – Krypton