If you are up for the simple off-the-shelf encryption provided by Android Cryptography APIs, then this introductory tutorial will show you where to find the resources, how to check if some algorithms are supported on your devices programmatically, and provide examples of a couple of popular algorithms in AES and RSA. A quick description is also given to explain the general difference in symmetric and asymmetric concepts. This is, however, not a discussion regarding the possibility how these algorithms can be compromised by experienced hackers. That is way beyond what this short tutorial can cover.
Android Cryptography API Resources and Device Support
If you are already familiar with Java’s cryptography support, the official reference for Android’s crypto APIs should be very straightforward. Here are the three main packages in the APIs:
- javax.crypto: This package provides the classes and interfaces for cryptographic applications implementing algorithms for encryption, decryption, or key agreement.
- javax.crypto.interfaces: This package provides the interfaces needed to implement the key agreement algorithm.
- javax.crypto.spec: This package provides the classes and interfaces needed to specify keys and parameter for encryption.
These APIs have been added since level 1 and you don’t need to specify the minimum SDK version. To get your device’s inventory of all the supported cryptographic algorithms, here is a snippet you can use.
public void ListSupportedAlgorithms() { String result = ""; // get all the providers Provider[] providers = Security.getProviders(); for (int p = 0; p < providers.length; p++) { // get all service types for a specific provider Set<Object> ks = providers[p].keySet(); Set<String> servicetypes = new TreeSet<String>(); for (Iterator<Object> it = ks.iterator(); it.hasNext();) { String k = it.next().toString(); k = k.split(" ")[0]; if (k.startsWith("Alg.Alias.")) k = k.substring(10); servicetypes.add(k.substring(0, k.indexOf('.'))); } // get all algorithms for a specific service type int s = 1; for (Iterator<String> its = servicetypes.iterator(); its.hasNext();) { String stype = its.next(); Set<String> algorithms = new TreeSet<String>(); for (Iterator<Object> it = ks.iterator(); it.hasNext();) { String k = it.next().toString(); k = k.split(" ")[0]; if (k.startsWith(stype + ".")) algorithms.add(k.substring(stype.length() + 1)); else if (k.startsWith("Alg.Alias." + stype +".")) algorithms.add(k.substring(stype.length() + 11)); } int a = 1; for (Iterator<String> ita = algorithms.iterator(); ita.hasNext();) { result += ("[P#" + (p + 1) + ":" + providers[p].getName() + "]" + "[S#" + s + ":" + stype + "]" + "[A#" + a + ":" + ita.next() + "]n"); a++; } s++; } }
Figure 1 shows the screenshot listing the crypto algorithms available on my device where “P#” indicates the sequence number for providers, “S#” for service types, and “A#” for algorithms.
Figure 1: Supported Crypto Algorithms
Symmetric vs. Asymmetric Cryptographic Algorithms
The main technical difference between symmetric and asymmetric cryptographic algorithms is – in the asymmetric algorithm, the key used to encrypt a message is not the same as the key used to decrypt it. Each user has a pair of cryptographic keys — a public encryption key and a private decryption key. This is made possible mathematically by large integer factorization. One extremely widely used algorithm, called RSA, is demonstrated later.
In contrast, symmetric algorithms use a single key for both encryption and decryption. One popular algorithm is called AES, which will be covered later in this tutorial. These algorithms are usually more efficient but might not be as secure as their asymmetric counterparts. There are some hybrid approaches to capitalize on the advantages of both types of algorithms.
Symmetric Encryption Example – AES
Here is one very popular and highly efficient symmetric algorithm called — Advanced Encryption Standard (AES). Based on the Rijndael cipher developed by two Belgian cryptographers, AES has been adopted by the U.S. government and is now used worldwide.
public class SymmetricAlgorithmAES extends Activity { static final String TAG = "SymmetricAlgorithmAES"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.symm); // Original text String theTestText = "This is just a simple test"; TextView tvorig = (TextView)findViewById(R.id.tvorig); tvorig.setText("n[ORIGINAL]:n" + theTestText + "n"); // Set up secret key spec for 128-bit AES encryption and decryption SecretKeySpec sks = null; try { SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); sr.setSeed("any data used as random seed".getBytes()); KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(128, sr); sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES"); } catch (Exception e) { Log.e(TAG, "AES secret key spec error"); } // Encode the original data with AES byte[] encodedBytes = null; try { Cipher c = Cipher.getInstance("AES"); c.init(Cipher.ENCRYPT_MODE, sks); encodedBytes = c.doFinal(theTestText.getBytes()); } catch (Exception e) { Log.e(TAG, "AES encryption error"); } TextView tvencoded = (TextView)findViewById(R.id.tvencoded); tvencoded.setText("[ENCODED]:n" + Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "n"); // Decode the encoded data with AES byte[] decodedBytes = null; try { Cipher c = Cipher.getInstance("AES"); c.init(Cipher.DECRYPT_MODE, sks); decodedBytes = c.doFinal(encodedBytes); } catch (Exception e) { Log.e(TAG, "AES decryption error"); } TextView tvdecoded = (TextView)findViewById(R.id.tvdecoded); tvdecoded.setText("[DECODED]:n" + new String(decodedBytes) + "n"); } }
Figure 2 shows the screenshot after running 128-bit AES algorithm first with encryption and then with decryption.
Figure 2: AES Algorithm
Asymmetric Encryption Example – RSA
RSA stands for Ron Rivest, Adi Shamir and Leonard Adleman. They developed the algorithm by using the large integer factorization technique in 1977. It has since become so popular that we almost depend on similar technologies used in everyday life, such as banking, messaging, etc. As we briefly mentioned before, this type of algorithm uses a pair of keys used for encryption and decryption respectively.
public class AsymmetricAlgorithmRSA extends Activity { static final String TAG = "AsymmetricAlgorithmRSA"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.asym); // Original text String theTestText = "This is just a simple test!"; TextView tvorig = (TextView)findViewById(R.id.tvorig); tvorig.setText("n[ORIGINAL]:n" + theTestText + "n"); // Generate key pair for 1024-bit RSA encryption and decryption Key publicKey = null; Key privateKey = null; try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); KeyPair kp = kpg.genKeyPair(); publicKey = kp.getPublic(); privateKey = kp.getPrivate(); } catch (Exception e) { Log.e(TAG, "RSA key pair error"); } // Encode the original data with RSA private key byte[] encodedBytes = null; try { Cipher c = Cipher.getInstance("RSA"); c.init(Cipher.ENCRYPT_MODE, privateKey); encodedBytes = c.doFinal(theTestText.getBytes()); } catch (Exception e) { Log.e(TAG, "RSA encryption error"); } TextView tvencoded = (TextView)findViewById(R.id.tvencoded); tvencoded.setText("[ENCODED]:n" + Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "n"); // Decode the encoded data with RSA public key byte[] decodedBytes = null; try { Cipher c = Cipher.getInstance("RSA"); c.init(Cipher.DECRYPT_MODE, publicKey); decodedBytes = c.doFinal(encodedBytes); } catch (Exception e) { Log.e(TAG, "RSA decryption error"); }
Figure 3 shows the screenshot after running RSA algorithm first with encryption and then with decryption.
Figure 3: RSA Algorithm
Conclusion
This brief tutorial is mainly to walk you through the method of finding the provided support for your Android devices, as well as some basic usage of the popular approaches in symmetric AES and asymmetric RSA algorithms. Some approaches utilize hybrid algorithms and very often padding functions are also incorporated to pad the data to specific block size. The cryptography technology itself covers many areas of knowledge and requires in-depth studies. We only touch the surface here to offer some info for you to get started. You can download the entire software package from the references.
References
Download the Code
Download the TutorialOnCrypto files.
About the Author
Chunyen Liu has been a software professional for years. He was among winners at programming contests administered by SUN, ACM, and IBM. He has co-authored software patents, written 25+ articles, reviewed books, and published apps at Androidlet and The J Maker. He holds advanced degrees in Computer Science with 20+ graduate-level courses taken. On the non-technical side, he is a tournament-ranked table tennis player, certified umpire, and certified coach of USA Table Tennis.