title: Encrypting data in Android
body: <p>I would like to encrypt data in my Android app. I have little experience in what the current state of encryption is, either for Android specifically or in general. I remember years ago that the US had laws that prevented software companies from exporting strong encryption technology. I'm not sure if any of that is applicable today considering that Android is open source code.</p>
  
  <p>What I want to accomplish is to allow a user to encrypt data using only a password. I prefer to avoid using private/public keys because this probably requires having to enter in those two keys by the user. In my app, the user should be able to encrypt/decrypt data using a password. Their data will be sent from one mobile device to another and it should not be possible to decrypt their data on the receiving end without knowing the password. I do use SSL when sending the data but that isn't good enough because the data needs to remain encrypted on the server before it gets relayed to the receiving device. If a hacker had access to my server, they could potentially read the data. For this reason, I want to encrypt it on the sending device and only decrypt it on the receiving device.</p>
  
  <p>A number of issues I need to resolve:</p>
  
  <ol>
  <li>Is there an encryption API that will let me encrypt just using a password but if not, then I'll consider using private/public keys.</li>
  <li>What are the current encryption algorithms that I can use and are they available internationally or does the US put some restriction on using them?</li>
  <li>Would I be better off creating my own custom encryption algorithm and modify it from time to time to prevent hackers from easily breaking it? Or would you discourage this? If so, why? If I change algorithm regularly, I will need to include an algorithm ID in the data in order for the decryption code to recognize whether it can decrypt that current version of the algorithm.</li>
  </ol>
  
  <p>I'm not looking for any "extremely hard to break" algorithm but something that should be adequate. The kind of data being stored are images, videos, audio and GPS data. It would be nice if the solution worked on Android 2.2 and above. I don't see why any algorithm shouldn't work on these versions since algorithms should be independent of an OS. Nevertheless, maybe Android does use a built-in algorithm for only certain versions?</p>
  
  <p>Edit:</p>
  
  <p>Code I am using now for some basic internal encryption in my app looks like this, but I have my doubts it's sufficient enough:</p>
  
  <pre><code>import java.security.SecureRandom;
  import javax.crypto.Cipher;
  import javax.crypto.KeyGenerator;
  import javax.crypto.SecretKey;
  import javax.crypto.spec.SecretKeySpec;
  
  SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
  byte[] encrypted = cipher.doFinal(clear);
  </code></pre>
  
  <p>Originally, the above line was:</p>
  
  <pre><code>SecureRandom.getInstance("SHA1PRNG")
  </code></pre>
  
  <p>but Google changed this in 4.0 and this caused my code to break. Anything encrypted with my previous code could no longer be decrypted with the default API for 4.0. I personally found that a major issue with Google because they broke compatibility. What's to stop them from repeating this again in the future? My encryption/decryption cannot be dependent upon Google's choice of breaking compatibility.</p>
  
  <p>I am also forced to use 128 bit encryption because apparently support for 192 and 256 bits is not necessarily available on all devices, persumably because of local government laws.</p>