Securizarea comunicațiilor pe Android

Cu toate încălcările recente de date, viața privată a devenit un subiect important. Aproape fiecare aplicație comunică prin rețea, deci este important să țineți cont de securitatea informațiilor despre utilizatori. În acest post, veți afla cele mai bune practici curente pentru securizarea comunicațiilor aplicației dvs. Android.

Utilizați HTTPS

Pe măsură ce vă dezvoltați aplicația, este cea mai bună practică să limitați solicitările de rețea la cele care sunt esențiale. Pentru cele esențiale, asigurați-vă că sunt realizate prin HTTPS în loc de HTTP. HTTPS este un protocol care criptează traficul, astfel încât să nu poată fi interceptat cu ușurință de interlocutorii. Cel mai bun lucru despre Android este faptul că migrarea este la fel de simplă ca schimbarea adresei URL http la https

URL url = nou URL ("https://example.com"); HttpsURLConnecționare httpsURLConnection = (HttpsURLConnection) url.openConnection (); httpsURLConnection.connect ();

De fapt, versiunile Android N și versiuni superioare pot impune aplicarea HTTPS utilizând Configurația de securitate a rețelei Android.

În Android Studio, selectați app / res / XML pentru proiectul dvs. Creați xml dacă nu există deja. Selectați-l și faceți clic pe Fișier> Fișier nou. Sună-l network_security_config.xml. Formatul fișierului este după cum urmează:

   example.com  

Pentru a spune Android să folosească acest fișier, adăugați numele fișierului în eticheta aplicației în AndroidManifest.xml fişier:

Actualizați furnizorii Crypto

Protocolul HTTPS a fost exploatat de mai multe ori de-a lungul anilor. Când cercetătorii de securitate declară vulnerabilitățile, defectele sunt adesea patch-uri. Aplicarea patch-urilor asigură faptul că conexiunile de rețea ale aplicației dvs. utilizează cele mai actualizate protocoale standard industriale. Cele mai recente versiuni ale protocoalelor conțin mai puține deficiențe decât cele precedente. 

Pentru a actualiza furnizorii cripto, va trebui să includeți Servicii Google Play. În fișierul modulului build.grable, adăugați următoarea linie la secțiunea dependențe:

implementare "com.google.android.gms: play-services-safetynet: 15.0.1"

API-ul pentru servicii SafetyNet are multe alte caracteristici, inclusiv API-ul de navigare sigură, care verifică adresele URL pentru a vedea dacă acestea au fost marcate ca o amenințare cunoscută și un API reCAPTCHA pentru a proteja aplicația dvs. împotriva spam-urilor și a altui trafic rău intenționat.

După sincronizarea funcției Gradle, puteți apela ProviderInstaller„s installIfNeededAsync metodă:

clasa publică MainActivity se extinde Activitatea implementează ProviderInstaller.ProviderInstallListener @Override protejat void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); ProviderInstaller.installIfNeededAsync (acest lucru, acest lucru); 

onProviderInstalled () metoda se numește atunci când furnizorul este actualizat cu succes sau este deja actualizat. In caz contrar, onProviderInstallFailed (int errorCode, Intent recoveryIntent) se numește. 

Certificat și fixarea cheii publice

Când faceți o conexiune HTTPS la un server, un certificat digital este prezentat de server și validat de Android pentru a vă asigura că conexiunea este securizată. Certificatul poate fi semnat cu un certificat de la o autoritate de certificare intermediară. Acest certificat utilizat de autoritatea intermediară poate fi, la rândul său, semnat de altă autoritate intermediară și așa mai departe, care este de încredere atâta timp cât ultimul certificat este semnat de o autoritate de certificare a rădăcinilor care este deja de încredere de către sistemul de operare Android.

Dacă oricare dintre certificatele din lanțul de încredere nu este validă, conexiunea nu este sigură. În timp ce acesta este un sistem bun, nu este rezistent. Este posibil ca un atacator să instruiască sistemul de operare Android să accepte certificate personalizate. Interfata proxy poate avea un certificat de încredere, iar dacă dispozitivul este controlat de o companie, compania poate să fi configurat dispozitivul să accepte propriul certificat. Aceste scenarii permit un atac "om în mijloc", permițând traficul HTTPS să fie decriptat și citit. 

Certificarea de certificare vine la salvare, prin verificarea certificatului serverului care este prezentat împotriva unei copii a certificatului așteptat. Acest lucru împiedică efectuarea conexiunilor atunci când certificatul este diferit de cel așteptat.

Pentru a implementa fixarea pe Android N și mai mare, trebuie să adăugați un hash (numit pini) al certificatului în network_security_config.xml fişier. Iată un exemplu de implementare:

   duckduckgo.com  lFL47 + i9MZkLqDTjnbPTx2GZbGmRfvF3GkEh + J + 1F3g = w9MWhhnFZDSPWTFBjaoeGuClsrCs7Z70lG7YNlo8t + s =   

Pentru a găsi pini pentru un anumit site, puteți merge la SSL Labs, introduceți site-ul și faceți clic pe A depune. Sau, dacă dezvoltați o aplicație pentru o companie, puteți să o întrebați companiei.

Notă: dacă trebuie să suportați dispozitive care rulează o versiune de sistem mai veche decât Android N, puteți utiliza biblioteca TrustKit. Utilizează fișierul de configurare a securității în rețea exact în același mod.

Sanitizarea și validarea

Cu toate protecțiile de până acum, legăturile ar trebui să fie destul de sigure. Chiar și așa, nu uitați de validarea regulată a programării. Informațiile de încredere nevalide primite de la rețea nu sunt sigure. O bună practică de programare este "proiectarea prin contract", în care intrările și ieșirile metodelor tale satisfac un contract care definește anumite așteptări ale interfeței. 

De exemplu, dacă serverul dvs. așteaptă un șir de 48 de caractere sau mai puțin, asigurați-vă că interfața va reveni doar până la și inclusiv 48 de caractere.

dacă (editText.getText () .toString () lungimea () <= 48)  ; //return something…  else  ; //return default or error 

Dacă așteptați numai numere de pe server, intrările dvs. ar trebui să verifice acest lucru. În timp ce acest lucru ajută la prevenirea erorilor nevinovate, reduce, de asemenea, probabilitatea atacurilor de injectare și a corupției de memorie. Acest lucru este valabil mai ales atunci când aceste date sunt transmise codului NDK sau JNI-nativ C și C ++.

Același lucru este valabil și pentru trimiterea datelor pe server. Nu transmiteți orbește date, mai ales dacă acestea sunt generate de utilizatori. De exemplu, este o practică bună să limitați lungimea intrărilor de utilizatori, mai ales dacă vor fi executate de un server SQL sau de orice tehnologie care va executa cod. 

În timp ce asigurarea unui server împotriva atacurilor este dincolo de sfera de aplicare a acestui articol, ca dezvoltator de dispozitive mobile, puteți face parte prin eliminarea caracterelor pentru limba utilizată de server. În acest fel, intrarea nu este susceptibilă la atacuri de injectare. Câteva exemple sunt ghilimele de stripare, punct și virgulă și tăișuri atunci când nu sunt esențiale pentru intrarea utilizatorului:

șirul = string.replace ("\\", "") .replace (";", ""); .replace ("\" ";

Dacă știți exact formatul așteptat, trebuie să verificați acest lucru. Un bun exemplu este validarea prin e-mail:

private final String emailRegexString = "[A-Za-z0-9 ._% + \\ -] + @ [A-Za-z0-9. \\ -] + \\. 2,4 $ "; booleanul privat isValidEmailString (String emailString) returnați emailString! = null && Pattern.compile (emailRegexString) .matcher (emailString) .matches (); 

Fișierele pot fi verificate, de asemenea. Dacă trimiteți o fotografie pe serverul dvs., puteți verifica dacă este o fotografie validă. Primele două octeți și ultimii doi octeți sunt întotdeauna FF D8 și FF D9 pentru formatul JPEG.

boolean static privat esteValidJPEGAtPath (String pathString) aruncă IOException RandomAccessFile randomAccessFile = null; încercați randomAccessFile = nou RandomAccessFile (pathString, "r"); lungime lunga = randomAccessFile.length (); dacă (lungime < 10L)  return false;  byte[] start = new byte[2]; randomAccessFile.readFully(start); randomAccessFile.seek(length - 2); byte[] end = new byte[2]; randomAccessFile.readFully(end); return start[0] == -1 && start[1] == -40 && end[0] == -1 && end[1] == -39;  finally  if (randomAccessFile != null)  randomAccessFile.close();   

Aveți grijă când afișați o alertă de eroare care afișează direct un mesaj de la server. Mesajele de eroare ar putea dezvălui informații private legate de depanare sau de securitate. Soluția este ca serverul să trimită un cod de eroare pe care clientul îl caută pentru a afișa un mesaj predefinit.

Comunicare cu alte aplicații

În timp ce protejați comunicarea de la și de la dispozitiv, este important să protejați IPC-ul. Au existat cazuri în care dezvoltatorii au lăsat fișiere partajate sau au implementat prize pentru a schimba informații sensibile. Acest lucru nu este sigur. Este mai bine să o utilizați scops. Puteți să trimiteți date utilizând o adresă scop prin furnizarea numelui pachetului astfel:

Intenția intenției = intenția nouă (); intent.setComponent (nume Component nou ("com.example.app", "com.example.app.TheActivity")); intent.putExtra ("UserInfo", "Exemplu șir"); startActivity (intenție);

Pentru a difuza date în mai multe aplicații, trebuie să le impuneți că numai aplicațiile semnate cu cheia de semnare vor primi datele. În caz contrar, informațiile pe care le trimiteți pot fi citite de orice aplicație care se înregistrează pentru a primi difuzarea. De asemenea, o aplicație rău intenționată poate trimite o emisiune la aplicația dvs. dacă v-ați înregistrat pentru a primi difuzarea. Aveți posibilitatea să utilizați o permisiune atunci când trimiteți și primiți emisiuni unde semnătură este folosit ca protectionLevel. Puteți defini o permisiune personalizată în fișierul manifest ca aceasta:

 

Apoi, puteți acorda permisiunea astfel: 

Ambele aplicații trebuie să aibă permisiunile din fișierul manifest pentru a funcționa. Pentru a trimite emisiunea:

Intenția intenției = intenția nouă (); intent.putExtra ("UserInfo", "Exemplu șir"); intent.setAction ( "com.example.SOME_NOTIFICATION"); sendBroadcast (intent, "com.example.mypermission");

Alternativ, puteți utiliza setPackage (String) atunci când trimiteți o transmisie pentru al restrânge la un set de aplicații care se potrivesc cu pachetul specificat. reglaj Android: exportat la fals în fișierul manifest vor exclude emisiunile primite din afara aplicației.

End-to-End Encryption

Este important să înțelegeți limitele HTTPS pentru protejarea comunicațiilor în rețea. În majoritatea implementărilor HTTPS, criptarea este terminată la server. De exemplu, conexiunea la serverul unei companii poate fi peste HTTPS, dar odată ce traficul atinge serverul, acesta este necriptat. Acesta poate fi apoi trimis la alte servere, fie prin stabilirea unei alte sesiuni HTTPS, fie prin trimiterea acesteia necriptată. Compania este capabilă să vadă informațiile trimise și, în majoritatea cazurilor, este o cerință pentru operațiunile de afaceri. Cu toate acestea, aceasta înseamnă, de asemenea, că societatea ar putea transmite informațiile către terți necriptate.

Există o tendință recentă numită "criptare end-to-end", în care numai cele două dispozitive de comunicații finale pot citi traficul. Un bun exemplu este o aplicație de chat criptată în care două dispozitive mobile comunică între ele printr-un server; numai expeditorul și receptorul își pot citi reciproc mesajele.

O analogie care vă ajută să înțelegeți criptarea end-to-end este să vă imaginați că doriți ca cineva să vă trimită un mesaj pe care numai dvs. îl puteți citi. Pentru aceasta, le oferiți o cutie cu un lacăt deschis (cheia publică) în timp ce țineți cheia lacătului (cheia privată). Utilizatorul scrie un mesaj, îl pune în cutie, blochează lacătul și îl trimite înapoi. Numai tu poți citi mesajul deoarece tu ești singurul cu cheia pentru a debloca lacătul.

Cu criptarea end-to-end, ambii utilizatori își trimit reciproc cheile. Serverul oferă doar un serviciu de comunicare, dar nu poate citi conținutul comunicării. În timp ce detaliile implementării depășesc sfera de aplicare a acestui articol, este o tehnologie puternică. Dacă doriți să aflați mai multe despre această abordare, un loc minunat de început este repo-ul GitHub pentru proiectul Signal Open Source.

Concluzie

Cu toate noile legi privind confidențialitatea, cum ar fi GDPR, securitatea este tot mai importantă. Este adesea un aspect neglijat al dezvoltării aplicațiilor mobile.

În acest tutorial, ați acoperit cele mai bune practici de securitate, inclusiv utilizarea HTTPS, fixarea certificatelor, dezinfectarea datelor și criptarea end-to-end. Aceste bune practici ar trebui să servească drept fundație pentru securitate atunci când vă dezvoltați aplicația mobilă. Dacă aveți întrebări, nu ezitați să le lăsați mai jos și, în timp ce sunteți aici, verificați câteva dintre celelalte tutoriale despre securitatea aplicațiilor Android! 

Cod