title: Any way around awful SecretKeyFactory performance with LVL and AESObfuscator?
body: <p>I'm looking to use the new licensing (LVL) stuff with Android Marketplace, but I'm running into a performance problem with the stock AESObfuscator.  Specifically, the constructor takes several seconds to run on a device (pure agony on emulator).  Since this code needs to run to even check for cached license responses, it puts a serious damper on checking the license at startup.</p>
  
  <p>Running the LVL sample app, here's my barbarian-style profiling of AESObfuscator's constructor:</p>
  
  <pre><code>public AESObfuscator(byte[] salt, String applicationId, String deviceId) {
          Log.w("AESObfuscator", "constructor starting");
          try {
              Log.w("AESObfuscator", "1");
              SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM);
              Log.w("AESObfuscator", "2");
              KeySpec keySpec =
                  new PBEKeySpec((applicationId + deviceId).toCharArray(), salt, 1024, 256);
              Log.w("AESObfuscator", "3");
              SecretKey tmp = factory.generateSecret(keySpec);
              Log.w("AESObfuscator", "4");
              SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
              Log.w("AESObfuscator", "5");
              mEncryptor = Cipher.getInstance(CIPHER_ALGORITHM);
              Log.w("AESObfuscator", "6");
              mEncryptor.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(IV));
              Log.w("AESObfuscator", "7");
              mDecryptor = Cipher.getInstance(CIPHER_ALGORITHM);
              Log.w("AESObfuscator", "8");
              mDecryptor.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV));
          } catch (GeneralSecurityException e) {
              // This can't happen on a compatible Android device.
              throw new RuntimeException("Invalid environment", e);
          }
          Log.w("AESObfuscator", "constructor done");
      }
  </code></pre>
  
  <p>The output on a Nexus One:</p>
  
  <pre><code>09-28 09:29:02.799: INFO/System.out(12377): debugger has settled (1396)
  09-28 09:29:02.988: WARN/AESObfuscator(12377): constructor starting
  09-28 09:29:02.988: WARN/AESObfuscator(12377): 1
  09-28 09:29:02.999: WARN/AESObfuscator(12377): 2
  09-28 09:29:02.999: WARN/AESObfuscator(12377): 3
  09-28 09:29:09.369: WARN/AESObfuscator(12377): 4
  09-28 09:29:09.369: WARN/AESObfuscator(12377): 5
  09-28 09:29:10.389: WARN/AESObfuscator(12377): 6
  09-28 09:29:10.398: WARN/AESObfuscator(12377): 7
  09-28 09:29:10.398: WARN/AESObfuscator(12377): 8
  09-28 09:29:10.409: WARN/AESObfuscator(12377): constructor done
  09-28 09:29:10.409: WARN/ActivityManager(83): Launch timeout has expired, giving up wake lock!
  09-28 09:29:10.458: INFO/LicenseChecker(12377): Binding to licensing service.
  </code></pre>
  
  <p>7 seconds of thrashing (about 20 in emulator, ugh).  I can spin it off on an AsyncTask, but it doesn't do much good there, since the app can't really run until I've validated the license.  All I get is a nice, pretty seven seconds of progress bar while the user waits for me to check the license.</p>
  
  <p>Any ideas?  Roll my own obfuscator with something simpler than AES to cache my own license responses?</p>