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. Зловредни приложения с услуга за достъпност могат да четат съдържанието на 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", за да не предлага системата да го попълни с текущата запазена парола.
// Пълно поле за парола с autofill и изчистване
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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също