SecureEditText Field API

App Shielding offers a secure text input API to protect sensitive text input against key loggers. Every time the user should provide sensitive text input, App Shielding will determine if the keyboard is trusted or not. The keyboard is considered as trusted if one of the following is true:

  • The keyboard was part of the original firmware.
  • The keyboard is listed in the Trusted keyboards configuration option.

If the system-installed keyboard cannot be trusted, App Shielding can use an in-app keyboard. The in-app keyboard supports text fields and numeric text inputs and is ideal for protecting password or PIN code entries. However, it does not have dictionary support or any form of text input prediction, so it might not be ideal for other forms of input.

The layout of the in-app keyboard is determined by the language settings of the device. The following keyboard layouts are supported:

  • English (US)
  • German
  • Norwegian
  • Danish
  • Swedish

If no keyboard layout for the system settings can be found, the English (US) layout is used by default.

Application Integration

To use the secure text field, replace android.widget.EditText from the Android SDK with the class no.promon.shield.ui.SecureEditText.

The keyboard protection mechanism is associated with the text input field, meaning that only text fields that are instances of the SecureEditText class are protected. Normal EditText instances remain unprotected and can still be used to have the user input non-sensitive information without any interruptions.

The SecureEditText class needs to know where the in-app keyboard should be displayed. Otherwise, it might cover important parts of the application. To achieve this, you must provide a container view for the keyboard, and this container must to have an ID (to be referenced later on).

An example container might look like the following:

<RelativeLayout 
  android:id="@+id/keyboardContainer"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  ... />

Lastly, the SecureEditText field needs to know about the container. This is achieved by setting an XML attribute on the SecureEditText class that points to the container's ID.

For example:

<no.promon.shield.ui.SecureEditText
  keyboard_container_id="keyboardContainer"
  ... />

Working with the secure text field

To test the in-app keyboard when no untrusted keyboards are installed, the default policy that decides whether to show the in-app keyboard can be overridden. This is achieved by calling one of the following methods on an instance of the SecureEditText class:

  • alwaysUseGlobalKeyboard()

    Always shows the global keyboard for this text field.

  • alwaysUseInAppKeyboard()

    Always shows the in-application keyboard for this text field.

  • chooseKeyboardUsingPolicy()

    Use the default policy to decide which keyboard to use. That is, the in-app keyboard is only shown if the system-installed keyboard is not trusted.

App Shielding does not dipslay a warning message by default to the user if their keyboard is not trusted. However, you can call the displayMessageOnUntrustedKeyboard(true) method to display a generic message about the keyboard. If you need a custom implementation of this functionality, contact OneSpan.

Diagnostics interface

The App Shielding SDK offers a diagnostics interface to determine which keyboard a given SecureEditText class currently uses.

By calling the getActiveKeyboard method of a SecureEditText object, the currently used keyboard can be determined. If the in-app keyboard is used, the string in-app is returned. If the global software keyboard is used, the keyboard’s package name is returned.

Keystroke Logging Interface

The SecureEditText class has the option to log keystrokes made on the keyboard attached to it. This functionality can be used by implementing the no.promon.shield.ui.KeystrokeListener interface and then calling the addKeystrokeListener method on a SecureEditText object, passing it an instance of a class that implements the KeystrokeListener interface.

Likewise, listeners can be removed by calling removeKeystrokeListener.

This process must be performed for all text fields where keystrokes should be logged, because if a listener is added to a text field only, the listener will only get events from that one text field.

KeystrokeListener events can be captured with the following callback methods:

  • onInAppKeyboardKey

    Provides events when the user presses and releases keys on the in-app keyboard. The callback method has the following parameters:

    • A time stamp, which represents a nanosecond precision time stamp when the event was first intercepted by App Shielding.
    • The type of the event, which can either be KeystrokeListener.TYPE_KEY_DOWN (the key was pressed) or KeystrokeListener.TYPE_KEY_UP (the key was released).
    • The key code of the character that was pressed.
  • onTextFieldTextChange
    Provides events when the text in the text field has changed by one character, indicating that the user has pressed a key. This is a way to log keystrokes for all keyboard types, including the in-app keyboard, the global software keyboard, and hardware keyboards

    Global software keyboards do not report all key events to the text field, meaning that App Shielding cannot know about them. This indirect way of determining keystrokes will only create and report events when the actual text in the text field changes (i.e., by key release events.

    The callback method has the following parameters:

    • A time stamp, which represents a nanosecond precision time stamp when the event was first intercepted by App Shielding.
    • The character that was changed in the text field.

Controlling the visibility of the keyboard

The SecureEditText class allows an application to control the visibility of the keyboard attached to it. This can either be the in-app keyboard or the global software keyboard. Use the showKeyboard and hideKeyboard methods on a SecureEditText object to show and hide the keyboard, respectively.

Limitations of the in-app keyboard

The secure in-app keyboard is not implemented as yet another system keyboard for Android. This way, it can be used in any application without the need for users to install a new input method (and make it active) on their phone or tablet.

The in-app keyboard is implemented as an Androidwidget instead of an input method. Thus, the Android system does not interact with the in-app keyboard in the same way it would with a global keyboard. For instance, the in-app keyboard will not receive keyboard-related events or commands from the Android system. You can think of the in-app keyboard as something that attaches to the SecureEditText widget, while the global keyboard attaches to the application Window.

Because of these architectural differences, the in-app keyboard is not a drop-in replacement for a global Android keyboard in all possible cases, even though the in-app keyboard works as expected in many typical use cases.

The following examples detail some of the in-app keyboard's limitations:

  • The in-app keyboard must be placed in a container (sub-layout) in the same top-level layout (i.e., the same XML file) where the corresponding SecureEditText widget resides. It is impossible to have a SecureEditText widget in a Dialog and an in-app keyboard outside the Dialog.

  • The in-app keyboard will not receive commands from InputMethodManager. Instead, InputMethodManager will direct those commands to the global keyboard. For example, callingInputMethodManager.showSoftInput() will cause Android to display the global keyboard instead of the in-app keyboard. You should use the SecureEditText.showKeyboard() function instead.

  • The in-app keyboard cannot be controlled by keyboard-related attributes in the enclosing Activity, Dialog, or Window. For example, calling a function like Window.setSoftInputMode(), or defining an XML attribute like <activity android:windowSoftInputMode> in the layout file, will affect the global keyboard, not the in-app keyboard.