Legge til et sikkerhetsmål til Android's delte preferanser

Hvis du har gitt ut en applikasjon på Googles Android-marked, og den applikasjonen krevde brukertypen din i noen form for legitimasjon, er sjansen stor for at søknaden din var tilgjengelig i omtrent tolv minutter før du mottok den første brukerforespørselen din for å tillate at legitimasjonen ble lagret på telefonen. Brukere hater å skrive inn et passord hver gang de vil bruke applikasjonen din. Sikkerhetsrisiko eller ikke, på et tidspunkt kan det hende du må la noen brukere lagre sensitive preferanser, eller sjansen er stor for at de bare ikke vil bruke applikasjonen din.

På Apples iOS-plattform holdes applikasjonsinnstillinger i noe som kalles nøkkelkjeden. Dataelementer som er lagret i nøkkelkjeden, blir kryptert automatisk av operativsystemet. Androids foretrukne mekanisme for å holde rede på brukerpreferanser, imidlertid, SharedPreferences-klassen, er ikke like sikker. Selv om SharedPreferences-klassen er enkel og enkel for en utvikler å bruke, blir det på en forankret enhet tydelig at den bare lagrer dataene i en XML-fil.

Hva dette betyr er at det faller på våre skuldre som ansvarlige Android-apputviklere å bestemme hvilke innstillinger vi lar brukeren lagre i den delte preferansefilen, og om nødvendig implementere våre egne krypterings- / dekrypteringsalgoritmer. Hensikten med denne artikkelen er ikke å få deg oppdatert på datakryptering. Det er et bredt emne, og det er mange bøker tilgjengelig om chifferteori.

I stedet vil jeg dele med deg en utvidet versjon av standard EditText-widgeten, som lar deg utvikleren bruke hva slags krypteringsnivå du mener passer for applikasjonen din. Den utvidede widgeten har vist seg å være en nyttig måte for meg å bruke et sikkerhetsmål på alle brukerpreferanser jeg velger, uten å kreve at jeg hele tiden skal håndtere koding / dekoding av strengene. Videre, hvis jeg på et eller annet tidspunkt i fremtiden bestemmer at det er nødvendig med en bedre sikkerhetskrypter, må jeg bare endre krypteringsmekanismen i widgeten, i stedet for å refaktere hele applikasjonen.

La oss ta en titt skal vi gjøre det?

  1. Opprett et nytt Android-prosjekt (mål hvilken SDK du foretrekker).
  2. I / src-filen vår la oss legge til en ny klasse som utvider android.widget.EditText.
 MyEditText.Java public class MyEditText utvider EditText { 
 public MyEditText (Context context, AttributeSet attrs) { 
 super (kontekst, attrs); 
 } 
 } 

Tok deg! For å referere til en utvidet widget fra XML-layoutfilen din, må du overstyre denne spesifikke konstruktørsignaturen. Selv om du også kan overstyre de to andre signaturene, vil du ikke overstyre kontekst- / attributtsignaturen føre til at det blir en styrke lukket når du laster inn en xml-layoutressurs som refererer til MyEditText.

3. I tillegg til å overstyre konstruktøren, ønsker vi å implementere en tilpasset versjon av standard widget-få / angi tekstfunksjoner. Disse kloner signaturen til standard-get / set-metodene, men tar en ekstra parameter, et flagg som indikerer om kryptering eller dekryptering er passende.

 public void setText (CharSequence text, boolean doDecrypt) 
 { 
 if (doDecrypt) { 
 tekst = rot13Dekode (tekst); 
 } 
 super .setText (tekst); 
 } 
 public Editable getText ( boolean doEncrypt) 
 { 
 Redigerbar e = super .getText (); 
 if (doEncrypt) { 
 e = rot13Kode (e); 
 } 
 return e; 
 } 

Hvis du vil merke når flagget er satt, ringer jeg en rot13-kode / dekoder-chiffer. Dette er bare noe enkelt jeg pisket opp for denne demoen. Du må bestemme hvilket sikkerhetsnivå som er passende for søknaden din. Hvis du er usikker, foreslår jeg at du bruker BouncyCastle-bibliotekene som er tilgjengelige som en del av standard Android-bygningen, ettersom disse gir et antall passende sifre.

 public Editable rot13Encode (CharSequence input) { 
 StringBuilder-utgang = ny StringBuilder (); 
 for ( int i = 0; i <input.length (); i ++) { 
 char c = input.charAt (i); 
 hvis ((c 126)) { 
 // utenfor vårt utskriftsvennlige sortiment, så la være i takt 
 output.append (c); 
 } annet { 
 //skifte 
 c * = 13; 
 hvis (c> 126) { 
 //pakke inn 
 c - = ((126 - 32) + 1); 
 } 
 output.append (c); 
 } 
 } 
 returner nye SpannableStringBuilder (output); 
 } 
 public CharSequence rot13Decode (CharSequence input) { 
 StringBuilder-utgang = ny StringBuilder (); 
 for ( int i = 0; i <input.length (); i ++) { 
 char c = input.charAt (i); 
 hvis ((c 126)) { 
 // utenfor vårt utskriftsvennlige sortiment, så la være i takt 
 output.append (c); 
 } annet { 
 //skifte 
 c- = 13; 
 hvis (c <32) { 
 //pakke inn 
 c + = ((126 - 32) + 1); 
 } 
 output.append (c); 
 } 
 } 
 return output.toString (); 
 } 

Tok deg! Legg merke til at kodefunksjonen returnerer en type redigerbar? Dette er et grensesnitt, ikke en faktisk variabeltype. Googles dokumentasjon gjør en god jobb med å forklare hvordan du kan konvertere en redigerbar til en streng, men det tar virkelig litt graving for å finne ut hvordan du går fra en streng til en redigerbar. Å lage en ny forekomst av SpannableStringBuilder fra en eksisterende CharSequence ser ut til å gjøre susen ganske praktisk.

4. Nå som vi kan legge til den utvidede widgeten til XML-filen vår, la oss lage oppsettet for vår demo i mappen / res / layout.

 main.xml 
 "1.0" encoding = "utf-8" ?> 
 "Http://schemas.android.com/apk/res/android" 
 android: orientering = "vertikal" 
 android: layout_width = "fill_parent" 
 android: layout_height = "fill_parent" 
 android: padding = "4dip" > 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 

android: layout_marginBottom = "20dip"

android: gravitasjon = "sentrum"

android: text = "@ streng / hallo" />

 android: layout_width = "wrap_content" 
 android: layout_height = "wrap_content" 
 android: layout_gravity = "sentrum" 
 android: text = "@ string / prompt" /> 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 
 android: layout_marginBottom = "20dip" 
 android: id = "@ + id / entry_field" /> 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 
 android: id = "@ + id / lagre" 
 android: text = "@ string / save_pref" /> 
 android: layout_width = "fill_parent" 
 android: layout_height = "wrap_content" 
 android: id = "@ + id / hente" 
 android: layout_marginBottom = "20dip" 
 android: text = "@ string / retrieve_pref" /> 
 android: id = "@ + id / showme" 
 android: layout_width = "wrap_content" 
 android: layout_height = "wrap_content" 
 android: sjekket = "true" 
 android: layout_gravity = "sentrum" 
 android: text = "@ string / show_text" /> 

5. Vi legger til et par standardmeldinger i mappen res / Values.

 strings.xml  "1.0" encoding = "utf-8" ?> 
 "hallo"> Skjul demo for passord 
 "app_name"> HideMe 
 "save_pref"> Lagre preferanse 
 "retrieve_pref"> Hent preferanse 
 "prompt"> Skriv inn litt tekst nedenfor: 
 "show_text"> Vis passord mens du skriver 

6. Nå er vi klare for hovedaktiviteten vår.

 Main.Java public class Main 
 utvider aktiviteten 
 implementerer OnCheckedChangeListener, OnClickListener 
 { 
 //hoved 
 } 

7. I onCreate-metoden trenger vi bare å koble UI-elementene våre.

 @Overstyring 
 public void onCreate (Bundle savedInstanceState) { 
 super .onCreate (savedInstanceState); 
 setContentView (R.layout. main ); 
 CheckBox cb = (CheckBox) findViewById (R.id. Showme ); // vis mens du skriver 
 cb.setOnCheckedChangeListener ( dette ); 
 Button sb = (Button) findViewById (R.id. Save ); // lagre til preferanser 
 sb.setOnClickListener ( dette ); 
 Knapp rb = (Knapp) findViewById (R.id. Hente); // få fra preferanser 
 rb.setOnClickListener ( dette ); 
 } 

8. I forbindelse med demoen har jeg lagt til en avkrysningsrute som lar deg vise eller ikke vise hva som skrives i redigeringsfeltet vårt. Dette er en ganske fin funksjon som er innebygd i Android-redigerings-tekstwidget kalt en transformasjon.

 @Overstyring 
 public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) { 
 MyEditText et = (MyEditText) findViewById (R.id. Entry_field ); 
 if (isChecked) { 
 et.setTransformationMethod ( null ); 
 } annet { 
 et.setTransformationMethod ( nytt PasswordTransformationMethod ()); 
 } 
 } 

9. Og sist, men ikke minst, har vi knappeklikk. Ved å bare sende inn flagget vårt når vi får og angir teksten i MyEditText, kan vi få ren eller kryptert tekst. Toastmeldingen gir en visuell indikator på hva som faktisk er lagret i og hentet fra innstillingsfilen på enheten.

 @Overstyring 
 public void onClick (Vis v) { 
 MyEditText et = (MyEditText) findViewById (R.id. Entry_field ); 
 SharedPreferences-innstillinger = getSharedPreferences ("MyPreferences", 0); 
 if (v.getId () == R.id. lagre ) { 
 Streng encodedPassword = et.getText ( true ) .toString (); 
 SharedPreferences.Editor editor = settings.edit (); 
 editor.putString ("passord", kodet passord); 
 editor.commit (); 
 Skål. makeText (Main. this, kodedPassword, Toast. LENGTH_LONG ) .show (); 
 } annet { 
 String encodedPassword = settings.getString ("passord", ""); 
 et.setText (kodet passord, sant ); 
 Skål. makeText (Main. this, kodedPassword, Toast. LENGTH_LONG ) .show (); 
 } 
 } 

Og der har du det - en praktisk, fleksibel mekanisme for å legge til litt nødvendig sikkerhet i dine egne preferansefiler. Hvis du ønsker å laste ned hele prosjektet, er kilden tilgjengelig her. Nyt!

© Copyright 2021 | pepebotifarra.com