Secure Text Entry — это режим ввода текста в Android, при котором вводимые символы отображаются в скрытом виде (точками или звёздочками) вместо фактических символов. Этот режим применяется для полей ввода паролей, PIN-кодов, CVV-кодов и другой конфиденциальной информации. Secure Text Entry не только защищает данные от визуального перехвата, но и предотвращает утечку через экранные снимки, экранные записи и функции автозамены. По данным Android Security Best Practices (2026), скрытый ввод является обязательным требованием для приложений, обрабатывающих аутентификационные данные пользователей.
Главное
Secure Text Entry (защищённый ввод текста) — это функция Android, которая заменяет отображение каждого введённого символа на маскирующий символ, обычно точку (•) или звёздочку (*). Это предотвращает чтение пароля через плечо (shoulder surfing) и скрывает вводимые данные от посторонних глаз. Функция также известна как password masking и является стандартной практикой в мобильных приложениях.
В отличие от 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 - built-in masking
editText.transformationMethod = PasswordTransformationMethod.getInstance()
// VisiblePasswordTransformationMethod - shows last char
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 влияет только на отображение символов.
// Programmatic password visibility toggle
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
}
// Restore cursor position
val cursorPos = editText.selectionStart
editText.setSelection(maxOf(0, cursorPos))
}
// Custom masking — shows only last 4 chars
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-сниффинг при передаче данных на сервер может раскрыть пароль, если не используется HTTPS с правильной валидацией сертификата.
По данным OWASP Mobile Security Testing Guide (2025), для максимальной защиты паролей в Android рекомендуется: использовать inputType="textPassword" + disable autofill для critical полей; не кешировать пароль в памяти дольше необходимого; очищать поле пароля при сворачивании приложения (onPause/onStop); использовать маскировку даже при кратковременном показе пароля.
| Уровень защиты | Secure Text Entry | Дополнительные меры |
|---|---|---|
| Визуальный перехват | Маскировка символов | Biometric auth, avoid 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", чтобы система не предлагала заполнить его текущим сохранённым паролем.
// Full password field with autofill and cleanup
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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также