2010-12-11 30 views
6

Je cache l'authentification d'un utilisateur à chaque fois que le serveur ping Android Market Licensing renvoie un pong GRANT_ACCESS.Vulnérabilités dans la mise en cache d'une clé obfusquée? Licence Android

Quelqu'un voit-il des vulnérabilités avec cette stratégie? Je crois que c'est très fort, puisque j'obscurcis une clé, et que le seul moyen de se déconnecter est de connaître le sel. Maintenant, quelqu'un pourrait théoriquement ouvrir l'apk et chercher le sel, mais ce n'est pas vraiment le niveau de fissuration, je pense est trop important de s'inquiéter.

Comme vous pouvez le voir, des informations spécifiques à l'appareil sont ajoutées à la technique d'obfuscation.

// 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); 

suivant la création des données persistant:

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(); 
    } 

Ensuite, je une autre méthode pour vérifier l'état du contenu mis en cache:

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; 
    } 
} 

Enfin, j'ai vérifié si isCachedLicens e dans les emplacements suivants du LicenseCheckerCallback: @Override dontAllow, et @override applicationError. Si isCachedLicense est vrai, je laisse l'utilisateur en avant.

De plus, le code source complet est situé à here.

Répondre

1

L'obfuscation avec du sel est généralement une stratégie faible. L'attaquant doit juste trouver le sel, ce qui est assez simple à faire une fois que vous savez ce que vous cherchez, et peut être fait sans un accès direct à votre application. Une fois que le sel est découvert (par n'importe qui), toute notre base d'installation a été compromise. Votre meilleur pari est, au lieu d'utiliser un algorithme d'obfuscation avec une clé fixe, d'utiliser une bibliothèque de chiffrement éprouvée + algorithme avec une clé qui est unique à l'utilisateur ou l'appareil que vous utilisez.

+0

J'utilise une bibliothèque de chiffrement éprouvée, voir le code complet pour référence. – hunterp

+1

C'est un pas de mieux - la bibliothèque semble faire un travail décent. L'attaquant devra maintenant déchiffrer les données de chaque appareil séparément, et avoir suffisamment d'accès à l'appareil pour pouvoir exécuter le décrypteur spécifique à l'appareil. Le sel global, cependant, est encore un point faible. Et comme il semble que vous le distribuez en tant que bibliothèque, les utilisateurs finaux risquent de ne pas remplir leurs propres valeurs de sel. Les chances sont qu'une population trop importante de développeurs le laisse aux valeurs que vous avez entrées - je changerais cela en une valeur qui est générée séparément pour chaque périphérique. – blueberryfields

+0

Si vous jetez un coup d'oeil à la référence, j'ai déjà des informations spécifiques au périphérique qui entrent dans le mélange de cryptage (j'ai également réédité ma question pour inclure cette information en haut) – hunterp