All Android packages must be signed by a private key associated with a certificate held by the developer or other appropriate authority (such as an application store certificate, whose presence indicates that the application has been vetted for use).
The digital signature provides integrity protection over the application, as any unauthorized modifications will be detected. The digital signature enables Android's signature-based permissions enforcement, allowing sharing between applications that are signed by the same entity. Application upgrades are also protected by digital signatures and certificates by ensuring that the new version of the same application has been signed by the same key.
The stock Android operating system and application installer currently do not use digital signatures and certificates to guarantee authenticity. Applications signed by any entity, even a completely unknown entity, can be installed. Malicious applications, or applications from unknown or less-trusted developers whose security properties are unknown, are a huge potential attack vector.
In the future, whether the feature is added by Google or another party, the Android operating system ideally would provide the ability to only allow applications that are digitally signed by a trusted entity to be installed or executed. Requiring that all Android packages be signed by a private key associated with a trusted certificate holder helps prepare for that future ability, and also provides the ability now for an enterprise application market to automatically verify application authenticity or for other out-of-band verification of application authenticity.
1Signed Code Identification
All signed code must be signed with a DoD PKI mobile code signing certificate. Signed code certificates must be validated as indicated in the PKI Certificate Validation section before they are executed on a workstation.16
The Android NDK and Java JNI provide the ability to implement portions of applications using native code written in languages such as C and C++.
The Android application permissions scheme and “sandbox” protections still apply to native code. However, many of the discovered Android privilege escalation exploits require native code execution ability in order to exploit Linux kernel vulnerabilities or vulnerabilities in Android OS system processes. Also, code analysis tools used to discover vulnerabilities or malicious behavior in Android applications are more likely to be able to examine Java code rather than native code. DARPA’s BAA-11-63 effort to perform automated analysis of Android applications is specifically excluding the ability to analyze native code at this time. Also, using the NDK eliminates many of the security protections provided by the Java language such as protection against buffer overflows.
According to Google's Android developer guidance17, the "NDK will not benefit most applications… using native code does not result in an automatic performance increase, but always increases application complexity. In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++."
Due to the increased complexity and security risks involved with native code, application developers should avoid use of the Android NDK or Java JNI unless their use is necessary. Developers should justify in writing any use of the NDK or JNI, and these uses should be scrutinized as part of a certification and accreditation process.
Third-Party Libraries
In some cases, code may already exist that provides desired functionality. However, caution should be used when relying on third-party libraries. Libraries from unknown or untrusted sources should not be used. Such libraries could contain code that performs more than the desired actions. Utilizing an external library allows it to act with the permissions of the developed application. Malicious third-party libraries could probe for permissions or transmit sensitive phone information.
Secure Data Communication
Mobile devices typically rely on cellular or Wi-Fi networks for connectivity. Cellular networks frequently use weak cryptography that can be compromised by adversaries to eavesdrop on or manipulate network traffic. Cellular networks may be controlled by potentially untrusted third parties or may have been infiltrated by unknown parties. Wi-Fi networks may also be controlled by potentially untrusted third parties or utilized by malicious users. Routing of Internet communication is unpredictable. The network path between the endpoints may take data packets through entities with malicious intentions. For all of these reasons, mobile applications must employ end-to-end data in transit protection of any potentially sensitive information, including session cookies or authentication tokens. To be safe, mobile applications should use data-in-transit encryption for all transmitted information unless a specific reason exists not to. Transport Layer Security (TLS), described below, is the typical method for providing this protection. IPsec Virtual Private Networks (VPNs) are another option in some cases.
Leverage TLS/SSL
Transport Layer Security (TLS), formerly known as Secure Sockets Layer, or SSL) is an Internet Engineering Task Force (IETF) standard for securing IP communications by providing confidentiality and integrity protections to data as well as authentication. TLS is used to secure a variety of protocols including HTTPS. TLS is readily available to Android developers. This section provides guidance on utilizing TLS within Android applications.
Use of Appropriate TLS Cipher Suites and TLS Protocol Version
TLS clients and servers negotiate a cipher suite to use. A cipher suite is a set of cryptographic algorithms used to protect the TLS session. Cipher suite negotiation provides the flexibility to adapt to new cryptographic algorithms over time. TLS supports a wide variety of cryptographic algorithms and cipher suites. Android's default TLS implementation has many cipher suites enabled by default, and a number of these are insecure choices or are otherwise not approved for U.S. Government use. NIST Special Publication 800-57 Part 3 provides guidance on appropriate U.S. Government TLS cipher suite choices. If NSA Suite B compliance is necessary, IETF RFC 5430 (soon to be updated by IETF RFC 5430bis) provides stricter guidance.
Multiple versions of the TLS/SSL protocol exist, but some of the older versions are no longer considered secure and must not be used. SSL version 2.0 must not be used under any circumstance as it is insecure. SSL version 3.0 is not approved for federal government use according to NIST Special Publication 800-52. TLS versions 1.0, 1.1, 1.2, or above are generally acceptable for use, although Suite B compliance requires TLS version 1.2 or above. Android's default crypto library appears to acceptably use SSL version 3.0 and TLS version 1.0 by default.
In environments using RSA PKI certificates, we recommend enabling these widely supported cipher suites that are US Government approved, listed in this priority order (most preferred first):
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
The cipher suites containing "DHE" as part of the name perform an ephemeral Diffie-Hellman key exchange that provides additional protection against decrypting the sessions, but those cipher suites may not be supported by all servers.
If Suite B ECDSA PKI certificates are being used, the TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA and TLS_ECDHE_ECSDA_WITH_AES_128_CBC_SHA cipher suites are supported by newer versions of the Android OS. These cipher suites are not fully Suite B compliant but can be used for a transitional period until the fully compliant cipher suites are available (TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 and TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256).
In Java, the SSLSocket or SSLServerSocket class's sslEnabledCipherSuites method and the SSLParameters class's setCipherSuites method provide the ability to specify the allowable cipher suites.
Certificate Validation
TLS clients authenticate the server's identity using the server's X.509 PKI certificate. The server may optionally authenticate the client's identity using a client X.509 PKI certificate. PKI certificate validation relies on a list of root certification authorities (CAs) that are trusted to issue certificates. Certificates are only valid if a certificate trust chain can be constructed between the certificate and one of the trusted root CAs.
Android devices are typically distributed with over 100 root CA certificates from a variety of certification authorities all around the world. These certification authorities all have equal ability to create certificates that will be trusted by default to assert identities. If any of these CAs are controlled or compromised by a malicious adversary, the adversary could easily construct falsified certificates. Most of these CAs are not needed and just increase the attack surface against devices. Also, the root certificate list generally does not include the DoD PKI root CA or other US Government root CAs. The root certificate list is stored in the read-only /system partition where it is difficult to customize or manage at an enterprise level (modification requires root access to the device).
Typical Android applications only need to trust the specific root CAs used to sign certificates for the specific servers contacted by the applications. For example, the DoD PKI root CAs are used to issue certificates to DoD NIPRNET and Internet web servers. Android applications only communicating with these servers only need to trust the DoD PKI root CA certificates and not other root CA certificates.
Below is a code example of initiating an HTTPS connection to https://www.example.com/ with a specific list of trusted root certificates. The file keystore.bks is a Bouncy Castle-formatted key store containing the trusted certificates:18
KeyStore keyStore = KeyStore.getInstance("BKS");
FileInputStream fis = null;
try {
fis = new FileInputStream("keystore.bks");
keyStore.load(fis, null);
} finally {
if (fis != null) {
fis.close();
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(keyStore);
SSLContext context = SSLContext.getInstance("TLS");
Context.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://www.example.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
inputStream in = urlConnection.getInputStream();
FIPS Validated Implementations
FIPS validated cryptographic implementations are required for protection of sensitive U.S. Government information. Android, by default, uses a combination of the BouncyCastle and OpenSSL cryptographic libraries, which are not known to be FIPS validated. Mocana and RSA BSAFE are two examples of FIPS validated cryptographic libraries with Java support. To use a FIPS validated cryptographic library for cryptographic operations, it needs to be added to the application's crypto provider list. The specific FIPS cryptographic library should contain the instructions for adding it as a crypto provider. A future version of this document may provide more details on how to add a FIPS validated cryptographic library.
Remote Authentication Best Practices
In typical commercial practice, TLS/SSL only authenticates the server's PKI certificate, because clients often do not have certificates. Then, once the session is established, the client authenticates using another technique. However, we recommend that clients should be issued certificates and use those for TLS/SSL client certificate authentication (mutual authentication using both server and client certificates), as this is a strong authentication method.
If client certificates are not available, username and password authentication is typically performed. Storing passwords on the Android device is prohibited, as that places the password at increased risk of compromise. Instead, the password should be passed to the remote server to obtain an authentication token or other long-term session identifier, the password should be cleared from the Android device's memory, and the authentication token should be stored on the Android device for future use of the remote server. If the authentication token is compromised, it can be revoked by the remote server, and unlike a password, the token is not potentially re-used on multiple servers, avoiding placing other servers that use the same password at risk.
Virtual Private Networks
Virtual Private Networks (VPNs) provide the ability to establish an encrypted tunnel from the mobile device through an untrusted network (such as a cellular network, Wi-Fi network, or the Internet) to a trusted network enclave, effectively placing the mobile device onto that trusted network enclave.
IPsec is the industry standard typically used to establish VPNs. NIST Special Publication 800-77 and 800-57 Part 3 provide guidance for acceptable U.S. Government use of IPsec.
Android includes IPsec VPN support. However, the default VPN client built in to typical Android devices is not FIPS validated. FIPS validated IPsec VPN clients should be preferred and are required for connectivity to government networks.
|