Overview Android includes an application framework, several application libraries, and a Dalvik-based virtual machine, all of which run on the Linux kernel. By taking advantage of the Linux kernel, Android receives a large number of operating system services, including process and memory management, network stack, driver, hardware abstraction layer, and services related to the topic-security-in this article. Common acronyms
- ADT: Android Development Tool
- API: Application Programming Interface
- IDE: integrated development environment
- JDK: Java Development Kit
- URL: Uniform Resource Identifier
- XML: Extensible Markup Language
Prerequisites To follow this article, you must have the following skills and tools:
- Basic understanding of Java technology and how to use eclipse (or your favorite IDE)
- Java Development Kit (version 5 or 6 is required)
- Eclipse (version 3.4 or 3.5)
- Android SDK and ADT plugin
For more information about downloading and setting, see references at the end of this article.
Sandbox, process, and permission User ID: in Linux, a user ID identifies a given user. In Android, a user ID identifies an application. The application is assigned a user ID during installation. The user id remains unchanged during the lifetime of the application on the device. Permission is about allowing or restricting applications (rather than users) to access device resources.Android uses the sandbox concept to implement separation and permissions between applications to allow or deny an application to access device resources, such as files and directories, networks, sensors, and APIs. Therefore, Android uses some Linux utilities (such as process-level security, application-related users, group IDs, and permissions) to implement the operations that an application can perform. In terms of concept, the sandbox can be represented as shown in Figure 1.
Figure 1. Two Android applications, each in their own basic sandbox or process
Android applications run on their own Linux processes and are assigned a unique user ID. By default, applications running in basic sandbox processes are not assigned permissions, thus preventing such applications from accessing systems or resources. However, Android applications can request permissions through the manifest file of the application. Android applications allow other applications to access their resources by doing the following:
- Declare appropriate manifest Permissions
- The program runs in the same process as other trusted applications to share access to their data and code.
The latter is shown in figure 2.
Figure 2. Two Android applications run in the same process
Different applications can run in the same process. For this method, you must first sign these applications with the same private key, and then assign them the same Linux User ID using the manifest file, this is done by defining the manifest attribute Android: shareduserid with the same value/name.
Developer Cases Figure 3 demonstrates a lot of security-related issues that will be discovered during Android application development.Use Cases.
Figure 3. Security fields when compiling Android applications
- An application or code signature is a process in which private, public key, and public key certificates are generated to sign and optimize the application.
- Permission is a security mechanism of the Android platform to allow or restrict application access to restricted APIs and resources. By default, Android applications are not granted any permissions and are not allowed to access protected APIs or resources on devices, thus ensuring their security. The permission must be requested, and custom permissions are defined. Files and content providers can be protected. Check, execute, Grant, and revoke permissions at runtime.
Next, let's take a closer look at each security field.
Application Signature All Android applications must be signed. An application or code signature is a process in which private keys are used to sign a given application so that:
- Identify the author of the Code
- Check if the application has changed
- Build trust between applications
Based on this trust relationship, applications can securely share code and data. Two applications signed with the same digital signature can grant permissions to each other to access the signature-based API. If they share the user ID, they can also run in the same process, this allows access to the code and data of the other party. The application signature first generates a private, public key pair, and a public key certificate. You can useDebugging modeAndRelease Mode:
- Applications built using Android build tools (command line and eclipse ADT) use an automatic signature for debugging private keys. These applications are called debug mode applications. The debug mode application is used for testing and cannot be released. Note: apps that are not signed or that use the debugged Private Key signature cannot be released through the Android Market.
- When you are about to release your own application, you must build a release mode version, which means that the application is signed with a private key.
The code signature in Android is much simpler than other mobile platforms. On Android, certificates can be self-signed, which means no certificate authorization is required. This method simplifies the release process and related costs. Next, we will introduce how to manually sign the Android Application from the command line and by using eclipse ADT. This article does not introduce the third method, that is, Ant. Manually create private, public key, and Public Key Certificates Recall that the debug mode application uses the debug key/certificate to automatically sign the signature by the build tool. To sign a publishing mode application, you must first generate a private, public key pair, and Public Key Certificate. You can sign the application manually or by using eclipse ADT. Both methods use the Java developer kit (JDK) keytool key and Certificate Management utility. To manually generate private and public key information, you can use keytool from the command line, as shown in Listing 1.
Listing 1. Using keytool to generate private/public keys and certificates
Keytool-genkey-v-alias <alias_name>-keystore <keystore. Name> -Keyalg RSA-keysize 2048-validity <Number of days> |
Note:Listing 1 assumes that JDK has been installed on your computer, and the java_home path is correctly defined as pointing to your JDK directory (see references for download and configuration information ). In listing 1,-genkey represents a public and private key pair, and an individual element certificate chain signed by X.509 V1, which contains the generated public key. -V indicates the lengthy mode. -Alias is the alias used for keystore items. It stores the generated private keys and certificates. -Keystore indicates the name of the key warehouse used. -Keyalg is an algorithm used to generate a key pair. -Keysize indicates the size of the generated key. The default size is 1024, but the recommended size is 2048. -Validity is the number of valid days. A value greater than 1000 is recommended. Note:After the key is generated, you must ensure the security of the key. Do not share the private key or specify the key in the command line or script. Note that keytool and jarsigner will prompt you to enter the password. For more information about this and other tips, see "securing your private key" on the Android Developers website (see the link in reference ). Keytool prompts you to enter the name, name, company, city, state, and country to generate an X.500 distinguished name from this information (for more information, see references ), enter the password to protect the private key and the key warehouse itself. For the validity period, make sure that you use a period that exceeds the expected life cycle of the application itself and related applications. If you publish an application on the Android Market, the validity period must be later than January 1, October 22, 2033. Otherwise, the application cannot be uploaded. In addition, having a long-lived certificate makes it easier to upgrade applications. Fortunately, the Android Market enforces a long-lived certificate to help you avoid such problems. Manually sign the application Next, use the jarsigner tool (which is part of JDK) to sign unsigned applications:
Jarsigner-verbose-keystore <keystore. Name> <my_application.apk> <alias_name> |
In the above Code,-verbose indicates the lengthy mode, and-keystore indicates the name of the key warehouse used. The following is the application name (.apk), and the alias used for private key. Jarsigner prompts you to enter the password when using the key warehouse and private key. Applications can use different keys for multiple signatures. Applications signed with the same private key can establish a trust relationship and run in the same process, share code and data. Optimize applications manually The last step in the signing process is to optimize the application so that the data boundary is aligned with the memory at the beginning of the file, which helps improve runtime performance and memory utilization. To sign the application, you can use zipalign:
Zipalign-V 4 your_project_name-unaligned.apk your_project_name.apk |
In the previous Code,-V indicates lengthy output. The number 4 indicates that the four-byte alignment is used (the four-byte alignment is always used ). The next parameter is to enter the name of the signed application (.apk), which must be signed with your private key. The last parameter is the output file name. If the existing application is overwritten, add a-F parameter. Manually verify that the application has been signed To verify that the application has been signed, use jarsigner to pass the-verify flag this time:
Jarsigner-verify-verbose-Certs my_application.apk |
In the previous Code,-verify indicates the verification application;-verbose indicates the lengthy mode;-Certs indicates the CN field for creating the key, the last parameter is the name of the android application package to be verified. Note:If CN reads "android debug", it means that the application is signed with a debugging key, which means it cannot be published. If you plan to release your application on the Android Market, remember to use a private key. I learned how to manually create private and public keys and sign and optimize applications. Next, learn how to use eclipse ADT to automatically create private and public keys, and sign and optimize applications.
Use eclipse ADT to create keys and certificates, and sign and optimize applications To use eclipse ADT to generate a key, you must export the application. There are two ways to export an application from Eclipse:
- ExportNot signedVersion
- ExportSignedVersion. All steps are performed by the ADT.
Export unsigned applications You can export the unsigned version of the application that you must manually sign. That is to say, You need to manually run keytool (as described earlier, to generate the key) and jarsigner (to sign the application) and use zipalign to optimize the application, as described earlier. To use ADT to export the unsigned version of the application, right-click the project and selectAndroid tools> export unsigned application package(See figure 4 ).
Figure 4. Export unsigned applications
After the selection, ADT prompts you to select a directory to export unsigned applications. Remember, once an application is exported, you must manually sign and optimize the application, as described earlier. Export signed applications With eclipse ADT, you can export the signed version of the application. Using this method, ADT prompts you to enter the following content:
- Information required to use an existing keystore or create a new protected keystore
- Information required to create a protected private key
- Information required to generate a Public Key Certificate
To export signed applications, right-click the project, but this time select the menu itemAndroid tools-> export signed Application Package, As shown in Figure 5.
Figure 5. Export signed applications
In this case, the export wizard command is executed, as shown in figure 6.
Figure 6. Export wizard
In Figure 7, select an existing key warehouse (or create a new one) and certificate.
Figure 7. Export Wizard: Key warehouse Selection
In figure 8, enter information to create a private key and digital certificate.
Figure 8. Export Wizard: create a private key and a digital certificate
In Figure 9, enter the path and name of the target file and verify the validity period.
Figure 9. Enter the path and name of the target file
When the release mode is complete, you have a signed and optimized application in the release mode, and you can release it. You can also use the android manifest tool to call the export wizard, as shown in figure 10.
Figure 10. Use the android manifest tool to call the export wizard
After the application is signed, the next step is to define the permissions required by the application in manifest. Next, we will describe this process. Note that the android developer website has excellent documents about application signing. When a new version of the Android platform is available, these documents will be updated (see references for more information ).
Permission Permission is a security mechanism of the Android platform. It is designed to allow or restrict application access to restricted APIs and resources. By default, Android applications are not granted permissions, which ensures their security by not allowing them to access protected APIs or resources on the device. Permissions are requested by the application through the manifest file during installation, and are granted or not granted by the user. Android defines a long series of manifest permissions to protect all aspects of the system or other applications. To request permissions, you can declare the <user-Permission> attribute in the manifest file:
<Uses-Permission Android: Name = "string"/> |
Android: Name specifies the permission name. For a list of all Android-defined manifest permissions, see the manifest. permisson page. Listing 2 is an example of a manifest file that requests Internet access and write to external storage:
Listing 2. Declaring (request) Permissions
<? 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. To access protected resources of an application, other applications must request appropriate permissions through their own manifest files. Listing 3 shows an example of how to define permissions.
Listing 3. Declaring custom Permissions
<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 custom permission is defined by specifying the minimum attribute, namely name, description, label, and protectionlevel. You can also define other attributes, but this is not described here. It is particularly interesting that the Android: protectionlevel attribute represents the method the system should follow when granting (or not granting) a given permission to an application requesting permissions. Protection Level:NormalAndDangerous. The former automatically grants permissions (although users can always review permissions before installation) and grant permissions based on signatures (that is, if the application requesting permissions is signed with the same certificate ); the latter indicates the permission to give access to private data, or has another potential negative impact. For more information about the <permission> manifest attribute, see the <permission> page (see references ). Applications can restrict access to applications and their system components (such as activity, service, content provider, and broadcast Explorer. This restriction is easily implemented by defining the Android: Permission attribute as in Listing 4. This level of protection allows applications to allow or restrict other applications to access system resources.
Listing 4. Define the permissions for an activity
<Activity Android: Name = ". friendslistactivity" Android: Label = "Friends List"> Android: Permission = "com. cenriqueortiz. Android. access_friends_list" <Intent-filter> : : </Intent-filter> </Activity> |
Content provider and File Permissions The content provider exposes a public URI for uniquely identifying their data (see references ). To protect this content provider, the caller can set intent. flag_grant_read_uri_permission and intent. flag_grant_write_uri_permission at the beginning or when returning results from the activity to grant access to specific data Uris. Application Files are protected by default. Files are protected based on user IDs, so they are accessible only to the owner application (this application has the same user ID ). As described above, applications that share the same user ID (and sign with the same digital certificate) run on the same process and thus share access to their applications. Applications can allow other applications or processes to access their files. This can be done by specifying the appropriate mode_world_readable and mode_world_writeable operation modes (to allow read or write access to files) or mode_private (to open files in private mode. You can use the following methods to specify the operation mode when creating or opening a file:
- Getsharedpreferences (filename, operatingmode)
- Openfileoutput (filename, operatingmode)
- Openorcreatedatabase (filename, operatingmode, sqlitedatabase. cursorfactory)
Runtime permission API Android provides various APIs to check, execute, Grant, and revoke permissions at runtime. These APIs are part of the android. content. context class, which provides global information about the application environment. For example, if you want to handle permissions elegantly, you can determine whether your application has been granted Internet access permissions (see OK 5 ).
Listing 5. Check permissions when using the runtime permission API
If (context. checkcallingorselfpermission (manifest. Permission. Internet) ! = Packagemanager. permission_granted ){ // The application requires permission to access // Internet "); } Else { // OK to access the Internet } |
For details about other APIs that check, execute, Grant, and revoke permissions at runtime, refer to the context class.
Conclusion This section describes the security of the Android platform, including sandbox, application signature, application permissions, and file and content provider permissions. After reading this introductory article, you will be able to use eclipse to manually create digital certificates, request application permissions, and allow or deny application access to files and content providers. In addition, you have a brief understanding of the runtime APIs that allow you to check, execute, Grant, and revoke permissions during runtime. |