Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vulnerabilities in caching of obfuscated key? Android Licensing

I'm caching a user's authentication to whenever the Android Market Licensing ping server returns a GRANT_ACCESS pong.

Does anyone see any vulnerabilities with this strategy? I believe it is very strong, since I am obfuscating a key, and the only way to unobfuscate is to know the salt. Now, someone could conceivably open the apk and look for the salt, but this is not really the level of cracking I think is too important to worry about.

As you can see, device specific information is being added to the obfuscation technique.

// Try to use more data here. ANDROID_ID is a single point of attack. 
String deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID); 
obfuscator = new AESObfuscator(SALT, getPackageName(), deviceId); 
mChecker = new LicenseChecker(this, new ServerManagedPolicy(this, obfuscator), BASE64_PUBLIC_KEY ); 

Next the creation of the persisted data:

 public void allow() {
   SharedPreferences settings = getSharedPreferences(PREFERENCES_EULA, 0);
   SharedPreferences.Editor editor = settings.edit();
   String uid = UUID.randomUUID().toString();
   if(!settings.contains(ACCESS_KEY)) {
     editor.putString(ACCESS_KEY,uid);       
     editor.commit();
   } 
   if(!settings.contains(OBFU_ACCESS_KEY)) {
     String obfu = obfuscator.obfuscate(uid);
     editor.putString(OBFU_ACCESS_KEY,obfu); 
     editor.commit();
   }

Then, I used another method to check the state of the cached content:

boolean isCachedLicense() {
  SharedPreferences settings = getSharedPreferences(PREFERENCES_EULA, 0);
  if(settings.contains(ACCESS_KEY) && settings.contains(OBFU_ACCESS_KEY)) {
    String accessKey = settings.getString(ACCESS_KEY, "");
    String obAccessKey = settings.getString(OBFU_ACCESS_KEY, "");
    try {
      if(accessKey.equals(obfuscator.unobfuscate(obAccessKey))) {
              return true;
      } else {
              return false;
      }
    } catch (ValidationException e) {
       e.printStackTrace();
       return false;
    }
  } else {
       return false;
  }
} 

Finally, I checked if isCachedLicense in the following locations of the LicenseCheckerCallback: @Override dontAllow, and @override applicationError. If isCachedLicense is true, then I let the user forward.

Also, full source code is located at here.

like image 672
hunterp Avatar asked Dec 11 '10 00:12

hunterp


1 Answers

Obfuscation with salt is generally speaking a weak strategy. The attacker just has to figure out the salt, which is fairly straight forward to do once you know what you're looking for, and can be done without direct access to your application. Once the salt is discovered (by anyone), all of our install base has been compromised.

Your best bet is, instead of using an obfuscation algorithm with a fixed key, to use a proven encryption library+algorithm with a key that is unique to either the user or the device that you're running on.

like image 135
blueberryfields Avatar answered Sep 28 '22 06:09

blueberryfields