Secure Text Entry — је режим уноса текста у Android-у, при којем се унети знакови приказују у скривеном облику (тачкама или звездицама) уместо стварних знакова. Овај режим се примењује за поља за унос лозинки, PIN-кодова, CVV-кодова и других поверљивих информација. Secure Text Entry не само да штити податке од визуелног пресретања, већ спречава и цурење путем снимака екрана, снимања екрана и функција аутоматске исправке. Према Android Security Best Practices (2026), скривени унос је обавезан захтев за апликације које обрађују податке за аутентификацију корисника.
Главне ствари
Secure Text Entry (заштићени унос текста) — је функција Android-а која замењује приказ сваког унетог знака маскирајућим симболом, обично тачком (•) или звездицом (*). Ово спречава читање лозинке преко рамена (shoulder surfing) и скрива унете податке од знатижељних очију. Функција је такође позната као маскирање лозинке и представља стандардну праксу у мобилним апликацијама.
За разлику од iOS-а, где је Secure Text Entry засебно подешавање UITextField-а, у Android-у ова функција се активира кроз атрибут inputType са варијацијом PASSWORD. Када EditText добије inputType="textPassword", аутоматски примењује PasswordTransformationMethod — класу која је одговорна за замену знакова. Приликом уноса сваког новог знака, EditText га тренутно замењује маскирајућим симболом кроз механизам TransformationMethod интерфејса.
Према Android Source Code (AOSP, 2026), имплементација PasswordTransformationMethod-а користи класу TextPaint за цртање маскирајућих симбола. Величина маскирајућег симбола се поклапа са величином фонта поља, што спречава цурење информација кроз дужину речи — сви знакови изгледају идентично по ширини. Ово је важно за заштиту од напада заснованих на анализи дужине унетих података.
<!-- Basic Secure Text Entry example -->
@+id/etPassword
android:layout_width="match_parent"
android:hint="Enter password"
android:inputType="textPassword"
android:maxLength="64"
android:importantForAutofill="yes" />
Механизам Secure Text Entry-ја у Android-у се заснива на интерфејсу TransformationMethod, дефинисаном у пакету android.text.method. PasswordTransformationMethod — је уграђена имплементација која преписује метод getTransformation(), враћајући замењену секвенцу знакова за приказ. Притом оригинални текст у Editable-у остаје непромењен — мења се само његова визуелна репрезентација.
Када корисник унесе знак, EditText позива dispatchEvent и прослеђује знак InputConnection-у, који га додаје у Editable. Затим EditText позива метод getTransformation() тренутног TransformationMethod-а, који прима оригинални CharSequence и враћа SpannableString са маскирајућим симболима. Овај SpannableString се приказује на екрану уместо оригиналног текста. Кључна карактеристика — само претварање не мења садржај Editable-а, због чега се при позивању getText().toString() враћа стварни унети текст.
Према Android Developers Reference (2026), PasswordTransformationMethod додаје сваком знаку MetricAffectingSpan који замењује глиф тачком. Ови span-ови не утичу на дужину текста, тако да се курсор и позиција уноса правилно задржавају чак и при скривеном приказу. Постоји и VisiblePasswordTransformationMethod, који приказује последњи унети знак на кратко време (слично iOS-у).
// PasswordTransformationMethod - уграђено маскирање
editText.transformationMethod = PasswordTransformationMethod.getInstance()
// VisiblePasswordTransformationMethod - приказује последњи знак
editText.transformationMethod = VisiblePasswordTransformationMethod.getInstance()
Пребацивање видљивости (password visibility toggle) — је функција која омогућава кориснику да привремено прикаже унету лозинку како би је проверио пре слања обрасца. У Android-у ова функција се реализује кроз TextInputLayout са атрибутом app:endIconMode="password_toggle". Притиском на икону ока, поље се пребацује између textPassword и textVisiblePassword.
Имплементација password_toggle у TextInputLayout-у аутоматски мења inputType унутрашњег EditText-а и анимира икону (отворено/затворено око). Важно је запамтити да се при овом пребацивању позиција курсора може ресетовати, зато TextInputLayout чува и враћа позицију након промене режима. Такође, при пребацивању на видљиву лозинку, аутоматска исправка и сугестије се не укључују — користи се TYPE_TEXT_VARIATION_VISIBLE_PASSWORD, а не обичан text.
Према Material Design Guidelines (2025), икона за приказ лозинке треба увек да буде видљива, не само када је поље у фокусу. Корисник треба да има могућност да провери лозинку у било ком тренутку. Икона не треба аутоматски да сакрива лозинку након одређеног времена — само на акцију корисника.
<!-- TextInputLayout with password toggle -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword"
android:hint="Password" />
</com.google.android.material.textfield.TextInputLayout>
Програмско постављање Secure Text Entry-ја у Kotlin-у се врши кроз постављање inputType-а или кроз setTransformationMethod(). Оба приступа доводе до истог резултата, али се разликују у детаљима. Постављање inputType додатно конфигурише аутоматску исправку и сугестије, док setTransformationMethod утиче само на приказ знакова.
// Програмско пребацивање видљивости лозинке
fun togglePasswordVisibility(til: TextInputLayout) {
val editText = til.editText ?: return
val currentType = editText.inputType
val isPassword = (currentType and
InputType.TYPE_TEXT_VARIATION_PASSWORD) != 0
if (isPassword) {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
} else {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
}
// Враћање позиције курсора
val cursorPos = editText.selectionStart
editText.setSelection(maxOf(0, cursorPos))
}
// Прилагођено маскирање — приказује само последња 4 знака
class PartialPasswordTransformation : TransformationMethod {
override fun getTransformation(source: CharSequence?,
view: View?): CharSequence {
val text = source?.toString() ?: ""
if (text.length <= 4) return text
val dots = "\u2022".repeat(text.length - 4)
return dots + text.substring(text.length - 4)
}
override fun onFocusChanged(view: View?,
sourceText: CharSequence?,
focused: Boolean,
direction: Int,
previouslyFocusedRect: android.graphics.Rect?) {}
}
Secure Text Entry пружа заштиту на неколико нивоа. Визуелна маскирања спречава читање лозинке преко рамена (shoulder surfing) — најраспрострањенији метод крађе лозинки на јавним местима. Искључивање аутоматске исправке спречава чување лозинке у речнику корисника, што искључује њено цурење кроз предиктивни унос. Заштита од снимака екрана (ако је укључен FLAG_SECURE) не дозвољава другим апликацијама да сниме садржај поља.
Међутим Secure Text Entry није потпуна заштита. Напади кроз пресретање уноса (keylogging) на нивоу система могу добити стварне знакове из InputConnection-а. Злонамерне апликације са accessibility сервисом могу читати садржај EditText-а, чак и ако су знакови скривени на екрану. Такође SSL-sniffing приликом преноса података на сервер може открити лозинку ако се не користи HTTPS са правилном валидацијом сертификата.
Према OWASP Mobile Security Testing Guide (2025), за максималну заштиту лозинки у Android-у препоручује се: користите inputType="textPassword" + искључите autofill за критична поља; не задржавајте лозинку у меморији дуже него што је потребно; очистите поље лозинке приликом минимизирања апликације (onPause/onStop); користите маскирање чак и при краткотрајном приказивању лозинке.
| Ниво заштите | Secure Text Entry | Додатне мере |
|---|---|---|
| Визуелно пресретање | Маскирање знакова | Biometric auth, избегавајте shoulder surfing |
| Снимци екрана | Делимична (зависи од имплементације) | FLAG_SECURE на Window |
| Keylogging | Не штити | Користите IME са безбедним уносом |
| Аутоматска исправка/речник | Искључена | подразумевано искључена за password |
| Пресретање мреже | Не штити | HTTPS са certificate pinning |
Програмери Android-а треба да се придржавају неколико кључних пракси при раду са скривеним уносом. Прво, увек користите TextInputLayout са endIconMode="password_toggle" за поља лозинке — ово је савремени стандард Material Design-а. Друго, не искључујте могућност приказивања лозинке — корисник треба да има могућност да провери шта је унео, посебно на мобилним уређајима са малом тастатуром.
Secure Text Entry такође захтева правилно подешавање аутоматског попуњавања. За поља лозинке обавезно наведите autofillHints="password" или autofillHints="newPassword" како би менаџери лозинки могли правилно да попуне и сачувају податке. За поље потврде нове лозинке користите autofillHints="newPassword" како систем не би предлагао да га попуни тренутно сачуваном лозинком.
// Цело поље лозинке са аутоматским попуњавањем и чишћењем
class SecurePasswordField {
private fun setupPasswordField(til: TextInputLayout) {
val editText = til.editText ?: return
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
editText.setAutofillHints(View.AUTOFILL_HINT_PASSWORD>)
editText.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_YES
}
fun clearOnPause(editText: EditText) {
editText.text?.clear()
}
}
Често постављана питања
textPassword скрива све унете знакове и искључује аутоматску исправку. textVisiblePassword такође искључује аутоматску исправку, али приказује знакове у отвореном облику. textVisiblePassword се користи при пребацивању видљивости лозинке — ово није обичан text, јер аутоматска исправка и сугестије остају искључене ради безбедности.
Да, направите прилагођену класу која имплементира интерфејс TransformationMethod. Препишите метод getTransformation(), који враћа CharSequence са потребним симболом замене. Поставите га кроз editText.transformationMethod = CustomPasswordTransformation(). Запамтите да симбол треба да буде моноширински ради безбедности.
На мобилним уређајима са малим екранима и додирном тастатуром, вероватноћа грешке при уносу лозинке је значајно већа него на десктопу. Могућност провере унете лозинке смањује број грешака при уносу и умањује број захтева за опоравак лозинке, што побољшава корисничко искуство и смањује оптерећење подршке.
Поставите заставу FLAG_SECURE на прозор Activity или Dialog: window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE). Ово ће спречити прављење снимака екрана и снимање екрана за цео прозор. Међутим, имајте у виду да ће ово такође искључити снимке екрана за обичан садржај, што може бити непожељно.
Од Android 8.0 (API 26), Autofill Framework аутоматски детектује password поља по inputType-у. За правилан рад поставите importantForAutofill="yes" и наведите autofillHints ("password", "newPassword", "emailAddress"). Gboard и менаџери лозинки користе ове атрибуте за предлагање сачуваних лозинки.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође