Understanding security on Android

Enhance application security with sandboxes, application signing, and permissions

When you develop Android applications, you must deal with a number of security-related aspects, including application processes and sandboxes, code and data sharing, system protection through application signing, and permissions use. Highlight these aspects of security in Android application development as you work with sample code.

C. Enrique Ortiz, Developer and author, About Mobility Weblog

C. Enrique Ortiz is a long-time mobile technologist, developer and author. He blogs at the About Mobility weblog and is the founder of the Austin chapter of MobileMonday.



16 November 2010

Also available in Japanese Vietnamese Portuguese Spanish

Overview

Android consists of an application framework, application libraries, and a Dalvik virtual machine-based runtime, all running on top of a Linux® kernel. By taking advantage of the Linux kernel, Android gets a number of operating system services, including the management of processes and memory, a network stack, drivers, a hardware abstraction layer, and, related to the topic of this article, security services.

Frequently used acronyms

  • ADT: Android Development Tools
  • API: Application program interface
  • IDE: Integrated development environment
  • JDK: Java Development Kit
  • URL: Uniform Resource Identifier
  • XML: Extensible Markup Language
Prerequisites

To follow along with this article, you need the following skills and tools:

  • Basic knowledge of Java™ technology and how to use Eclipse (or your favorite IDE)
  • Java Development Kit (version 5 or 6 required)
  • Eclipse (version 3.4 or 3.5)
  • Android SDK and ADT plug-in

For download and setup information, see the Resources section at the end of this article.


Sandboxes, processes, and permissions

User ID: Linux versus Android

While in Linux a user ID identifies a given user, on Android, a user ID identifies an application. User IDs are assigned when the application is installed, and they remain for the life span of the application on the device. Permissions are about allowing or restricting the application (rather than users) access to the device's resources.

Android uses the concept of a sandbox to enforce interapplication separation and permissions to allow or deny an application access to the device's resources such as files and directories, the network, the sensors, and APIs in general. For this, Android uses Linux facilities such as process-level security, user and group IDs that are associated with the application, and permissions to enforce what operations an application is allowed to perform.

Conceptually, a sandbox can be represented as in Figure 1.

Figure 1. Two Android applications, each on its own basic sandbox or process
Diagram: Two Android applications, each on its own basic sandbox or process (with different user IDs)

Android applications run on their own Linux process and are assigned a unique user ID. By default, applications run inside a basic sandbox process with no permissions assigned, thus preventing such applications from accessing the system or resources. Android applications can request permissions, however, through the application's manifest file.

Android applications can allow access to their resources to other applications by:

  • Declaring the appropriate manifest-permissions
  • Running in the same process with other trusted applications, thus sharing access to their data and code

The latter is illustrated in Figure 2.

Figure 2. Two Android applications, running on the same process
Diagram: Two Android applications, running on the same process (with same digital signature and same Linux user ID)

Different applications can run in the same process. For this approach, you first must sign those applications using the same private key and you then must assign to them the same Linux user ID using the manifest file, by defining the manifest attribute android:sharedUserId with the same value/name.


Developer use cases

Figure 3 illustrates a number of security-related use-cases found when you develop Android applications.

Figure 3. Security areas present when programming Android applications
Diagram: Security areas present when programming Android applications
  • Application or code signing is the process of generating private and public keys and public-key certificates, signing and optimizing the application.
  • Permissions are an Android platform security mechanism to allow or restrict application access to restricted APIs and resources. By default, Android applications have no permissions granted, making them safe by not allowing them to gain access to protected APIs or resources on the device. Permissions must be requested, customized permissions defined, and file and content providers protected. Be sure that you check, enforce, grant, and revoke permissions at runtime.

Next, look at each of the security areas in more detail.


Application signing

All Android applications must be signed. Application or code signing is the process of digitally signing a given application using a private key to:

  • Identify the code's author
  • Detect if the application has changed
  • Establish trust between applications

Based on this trust relationship, applications can share code and data in a secure manner.

Applications signed using the same digital signature can grant each other permissions to access signature-based APIs and also can run in the same process if they share user IDs, allowing access to each other's code and data.

Application signing begins by generating a private and public key pair and a related public-key certificate, also known as a public-key certificate.

When working with Android applications, you can build applications in debug and release-mode:

  • Applications built using the Android build tools (command line and Eclipse ADT) are automatically signed using a debug private key; these applications are referred to as debug-mode applications. Debug-mode applications are used for testing and should not be distributed. Note that unsigned applications or applications signed using a debug private key cannot be distributed through the Android Market.
  • When you are ready to release your application, you have to build a release mode version of it, which means signing the application with your private key.

Code signing in Android is done in a much simpler manner than in other mobile platforms. On Android, the certificate can be self-signed, that is, there is no need for a certificate authority. This approach simplifies the publishing process and related costs.

Next, I cover how to sign Android applications manually from the command line and by using the Eclipse ADT. I do not cover a third approach, using Ant, in this article.

Manually creating the private and public keys and public-key certificate

Recall that debug-mode applications are automatically signed by the build tools using the debug key/certificate. To sign a release-mode application, you first must generate the private and public key pair and public-key certificate. You can sign your application manually or by using the Eclipse ADT. In both approaches, the Java Developer Kit (JDK) keytool key and certificate management utility are used.

To generate the private and public key information manually, use the keytool from the command line, as in Listing 1.

Listing 1. Using keytool to generate private/public keys and certificate
keytool -genkey -v -alias <alias_name> -keystore <keystore.name> 
-keyalg RSA -keysize 2048 -validity <number of days>

NOTE:Listing 1 assumes the JDK is installed on your computer and the JAVA_HOME path is properly defined to point to your JDK directory (see Resources for download and set-up information).

In Listing 1, -genkey indicates a public and private key pair entry, as well as an X.509 v1 self-signed, single-element certificate chain that includes the generated public key. -v indicates verbose-mode. -alias is the alias to use for the keystore entry that stores the generated private key and certificate. -keystore indicates the name of the keystore to use. -keyalg is the algorithm to use to generate the key pair. -keysize is the size of the key to generate where the default is 1024 but 2048 is recommended. And -validity is the validity period in days; a value greater than 1000 is recommended.

NOTE: After you generate your keys, it is very important that you safeguard your private key. Do not share the private key, and do not specify it on the command line or in scripts; note that keytool and jarsigner prompt for the password. For this and other tips, see "Securing Your Private Key" from the Android Developers website (see Resources for a link).

Keytool prompts for your first and last names, organization, city, state, country from which a X.500 Distinguished Name is generated (see Resources for more information), and passwords to protect the private key and to protect the keystore itself.

For the validity period, make sure to use a period that exceeds the expected life of the application and related applications. If you are publishing your application on the Android Market, the period must end after October 22, 2033; otherwise, you are not able to upload it. Also, having long-lived certificates makes your life easy when upgrading your applications. Fortunately, the Android Market enforces long-lived certificates to help you avoid such situations.

Manually signing your application

Next, sign the unsigned application using the jarsigner tool, which is part of the JDK:

jarsigner -verbose -keystore <keystore.name> <my_application.apk> <alias_name>

In the preceding code, -verbose indicates verbose mode, and -keystore indicates the name of the keystore to use. Next is the name of the application (.apk), and last is the alias to use for the private key.

Jarsigner prompts for the password to use the keystore and private key.

Applications can be signed multiple times using different keys, and applications signed with the same private key can establish a trust relationship with each other and can run in the same process and share code and data.

Manually optimizing your application

The last step in the signing process is to optimize the application so that the data boundaries are memory-aligned with respect to the start of the file, a technique that helps improve runtime performance and memory utilization. To align the application, use zipalign:

zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

In the preceding code, -v indicates verbose output. The number 4 indicates to use four-byte alignment (always use four bytes). The next argument is the filename of the input signed application (.apk), which must be signed with your private key, and the last argument is the output filename; if overriding an existing application, add -f.

Manually verifying that the application has been signed

To verify that the application was signed, use Jarsigner, this time passing the -verify flag:

jarsigner -verify -verbose -certs my_application.apk

In the preceding code, -verify indicates to verify the application; -verbose indicates verbose mode; -certs indicates to show the CN field of who created the key, and the last argument is the name of the Android application package to verify.

NOTE: If the CN reads "Android Debug," it means the application was signed using the debug key, which means it cannot be published; remember to use a private key if your plan is to publish your application on the Android Market.

You just saw how to manually create the private and public keys and to sign and optimize the application. Next, look at how to use the Eclipse ADT to automatically create the private and public keys and to sign and optimize the application for you.


Using Eclipse ADT to create keys and certificate and to sign and optimize your application

To generate the keys using the Eclipse ADT, you have to export the application. There are two methods of exporting applications from Eclipse:

  • Export an unsigned version of the application that you must manually sign
  • Export a signed version of the application, where the ADT does all the steps for you

Exporting an unsigned application

You can export an unsigned version of your application that you must manually sign. That is, you need to manually run keytool (to generate the keys as described previously) and Jarsigner (to sign the application) and optimize the application using the zipalign tool, as previously explained.

To export an unsigned version of the application using the ADT, right-click the project and select Android Tools>Export Unsigned Application Package (see Figure 4).

Figure 4. Exporting the unsigned application
Screen capture of exporting the unsigned application

After it is selected, the ADT prompts you for the directory where to export the unsigned application. Remember that once the application is exported, you have to manually sign and optimize the application, as covered previously.

Exporting a signed application

With the Eclipse ADT, you can export a signed version of the application. Using this approach, the ADT prompts you for the following:

  • The information required to use an existing KeyStore or create a new protected KeyStore
  • The information needed to create a protected private key
  • The information needed to generate the public-key certificate

To export a signed application, right-click the project, but this time select the menu item Android Tools->Export Signed Application Package, as illustrated in Figure 5.

Figure 5. Exporting a signed application
Screen capture of exporting a signed application

At this point, the Export Wizard executes, as in Figure 6.

Figure 6. Export Wizard
Screen capture of the Export Wizard

In Figure 7, select an existing keystore or create a new one and the credentials to use.

Figure 7. Export Wizard: Keystore selection
Screen capture of Export Wizard: Keystore selection

In Figure 8, enter the information to create the private key and the digital certificate.

Figure 8. Export Wizard: Creating the private key and the digital certificate
Screen capture of Export Wizard: selecting the project to export

In Figure 9, enter the path and name for the destination file, and verify the validity period.

Figure 9. Entering the path and name for the destination file
Screen capture of entering the path and name for the destination file

When finished, you have a release-mode signed and optimized application that you can publish.

Alternatively, you can also invoke the Export Wizard using the Android Manifest Tool, as in Figure 10.

Figure 10. Invoking the Export Wizard using the Android Manifest tool
Screen capture of invoking the Export Wizard using the Android Manifest tool

After applications are signed, the next step is for you to define in the manifest the permissions needed by the application. This process is described next.

Note that the Android Developer's website has very good documentation on application signing that is always up-to-date as new releases of the Android platform become available (see Resources for more information).


Using permissions

Permissions are an Android platform security mechanism to allow or restrict application access to restricted APIs and resources. By default, Android applications have no permissions granted, making them safe by not allowing them to gain access to protected APIs or resources on the device. Permissions are requested by the application through the manifest file and granted or not granted by the user during installation.

Android defines a long list of manifest permissions, protecting various aspects of the system or other applications. To request permission, declare a <user-permission> attribute in the manifest file:

<uses-permission android:name="string" />

where the android:name specifies the name of the permission.

For a list of all the Android-defined manifest permissions, see the Manifest.permisson page. Listing 2 is an example of a manifest file requesting permission to use the Internet and permission to write to external storage:

Listing 2. Declaring (requesting) a permission
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      android:versionCode="1"
      android:versionName="1.0"
      package="com.cenriqueortiz.tutorials.datastore" 
      android:installLocation="auto">

    <application 
        :
        :
        :
    </application>

    <uses-permission 
        android:name="android.permission.INTERNET"/>
    <uses-permission 
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

Applications can define their own custom permissions to protect application resources. Other applications wanting to access an application's protected resources must request the appropriate permissions through their own manifest file. Listing 3 shows an example of how to define permissions.

Listing 3. Declaring a custom permission
<permission
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:name="com.cenriqueortiz.android.ACCESS_FRIENDS_LIST"
        android:description="@string/permission_description"
        android:label="@string/permission_label"
        android:protectionLevel="normal"
    >
</permission>

In Listing 3, a customer permission is defined by specifying the minimum attributes name, description, label, and protectionLevel. Other attributes can be defined, but they are not covered here.

Of special interest is the android:protectionLevel attribute, which indicates the method the system should follow when granting (or not) a given permission to a requesting application. Protection levels include normal, which automatically grants permissions (though the user can always review before installation), granting permissions based on signature (that is, if the requesting application is signed with the same certificate), and dangerous, indicating the permission gives access to private data or has another potentially negative impact. For more information about the <permission> manifest attribute, see the <permission> page (see Resources).

Applications can restrict access to the application and the system components it uses such as Activity, Service, Content Provider, and Broadcast Receiver. This restriction is easily done by defining the android:permission attribute as in Listing 4. This level of protection lets the application allow or restrict other applications to access the system resource.

Listing 4. Defining a permission to an activity
<activity 
    android:name=".FriendsListActivity" 
    android:label="Friends List">
    android:permission="com.cenriqueortiz.android.ACCESS_FRIENDS_LIST"
    <intent-filter>
        :
        :
    </intent-filter>        
</activity>

Content providers and file permissions

Content providers expose a public URI that uniquely identifies their data (see Resources). To protect such content providers, the caller, when starting or returning a result from an activity, can set the Intent.FLAG_GRANT_READ_URI_PERMISSION and Intent.FLAG_GRANT_WRITE_URI_PERMISSION, to grant the receiving activity permission to access the specific data URI in the intent.

Application files are protected by default. Files are protected based on user IDs and thus accessible only to the owner application, which has the same user ID. As previously covered, applications that share the same user ID (and are signed using the same digital certificate) run on the same process and thus share access to their applications.

Applications can allow access of their files to other applications or processes. This allowance is made by indicating the proper MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE operating mode to allow read or write access to the file, or MODE_PRIVATE to open the file in private mode. You can specify an operating mode with the following methods when you create or open files:

  • getSharedPreferences(filename, operatingMode)
  • openFileOutput(filename, operatingMode)
  • openOrCreateDatabase(filename, operatingMode, SQLiteDatabase.CursorFactory)

Runtime Permission APIs

Android provides APIs to check, enforce, grant, and revoke permissions at runtime. These APIs are part of the android.content.Context class, which provides global information about an application environment. For example, if you want to handle permissions gracefully, you can determine whether your application has been granted access to the Internet (see Listing 5).

Listing 5. Using a runtime Permission API to check permissions at runtime
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
        != PackageManager.PERMISSION_GRANTED) {
            // The Application requires permission to access the  
            // Internet");
} else {
    // OK to access the Internet
}

For other permission APIs to check, enforce, grant, and revoke permissions at runtime, see the context class.


Conclusion

This article introduced security on the Android platform, including sandboxes, application signing, application permissions, and file and content provider permissions. After this introduction, you can create digital certificates manually and using Eclipse, request applications permissions, and allow or disallow applications to access files and content providers. Also, you looked briefly at the permissions runtime APIs, which allow you to check, enforce, grant, and revoke permissions at runtime.

Resources

Learn

  • What is Android?: Read the overview from the Android Developers website.
  • Develop Android applications with Eclipse (Frank Ableson,developerWorks, February 2008): Learn all about the easiest way to develop Android applications is to use Eclipse in this tutorial.
  • Introduction to Android Development (Frank Ableson, developerWorks, May 2009): Get an introduction to the Android platform and learn how to code a basic Android application.
  • X.509 Certificates: Read the X.509 standard that defines what information can go into a certificate, and describes how to write it down (the data format).
  • Extended permissions: Request extended permissions for your application if it needs to access other parts of the user's profile that might be private, or if it needs to publish content to Facebook on a user's behalf.
  • Securing Your Private Key: Learn how to maintain the security of your private key on the Android Developers website.
  • Signing Your Applications: Read about signing your Android applications prior to publishing them for mobile device users from the Android Developers website.
  • Manifest.permission page: For a list of all the Android-defined Manifest permissions, visit the Android Developers website.
  • Content Providers: Learn how to store and retrieve data and make it accessible to all applications.
  • The Context class: Allow access to application-specific resources and classes with this interface to global information described on the Android Developers website.
  • Networking with Android (Frank Ableson, developerWorks, June 2009): Explore the networking capabilities of Android.
  • Working with XML on Android (Michael Galpin, developerWorks, June 2009): Learn about the different options for working with XML on Android and how to use them to build your own Android applications.
  • Under the Hood of Native Web Apps for Android: Learn about hybrid applications in Android.
  • Unlocking Android (Frank Ableson, Manning Publications, 2010): Cover all aspects of Android development in this book.
  • Mobile Design and Development (Brian Fling, O'Reilly Media, 2009): Read about practical guidelines, standards, techniques, and best practices for building mobile products in this book.
  • Read the Data Storage Dev Guide: Choose the right solution to save persistent application data s noted on the official Android Developer website.
  • Intents: Learn about this abstract description of an operation to be performed from the Android Developer site.
  • Android SDK documentation: Get the latest information in the Android API reference.
  • The Open Handset Alliance: Visit Android's sponsor.
  • XML area on developerWorks: Get the resources you need to advance your skills in the XML arena.
  • My developerWorks: Personalize your developerWorks experience.
  • XML technical library: See the developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks. Also, read more XML tips.
  • developerWorks technical events and webcasts: Stay current with technology in these sessions.
  • developerWorks on Twitter: Join today to follow developerWorks tweets.
  • developerWorks podcasts: Listen to interesting interviews and discussions for software developers.
  • developerWorks on-demand demos: Watch demos ranging from product installation and setup for beginners to advanced functionality for experienced developers.

Get products and technologies

  • The <permission> page: Find more information about the <permission> Manifest page.
  • keytool: Try this key and certificate management tool.
  • jarsigner: Get this JAR signing and verification tool to generate signatures for Java ARchive (JAR) files, and verify the signatures of signed JAR files.
  • Android SDK: Download the SDK, access the API reference, and get the latest news on Android from the official Android developers' site. Version 1.5 and later will work.
  • The Android Open Source Project: Find the open source information and source code you need to build an Android-compatible device.
  • JDK 6 Update 21: Get the Java Platform, Standard Edition.
  • Eclipse: Obtain the latest Eclipse IDE.
  • IBM product evaluation versions: Download and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into XML on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Open source, Industries
ArticleID=580346
ArticleTitle=Understanding security on Android
publish-date=11162010