2016-10-25 19 views
7

я получаю некоторые ошибки из Google Play консоли, где некоторые пользователи (Pixel XL, нексус 5 и Xperia Z3 +) получаютОбщие предпочтения? javax.crypto.BadPaddingException: блок подушечка поврежден только в некоторых устройствах

Caused by: java.lang.RuntimeException: javax.crypto.BadPaddingException: pad block corrupted 
at com.darwins.custom.ObscuredSharedPreferences.decrypt(ObscuredSharedPreferences.java:193) 
at com.darwins.custom.ObscuredSharedPreferences.getInt(ObscuredSharedPreferences.java:134) 

Кроме того, приложение работает тонкий в остальных устройствах (даже в некотором соединении 5 работает нормально)

Проблема возникает при первом открытии пользователем приложения. Он пытается загрузить том музыки из общих настроек. Поскольку они не вошли в меню опций, чтобы изменить значение по умолчанию, оно должно получить значение по умолчанию:

if(sp  == null) sp = new ObscuredSharedPreferences(ctx, ctx.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE)); 
if(musicVolume == -1) musicVolume = sp.getInt(KEY_SP_MUSIC_VOLUME,10); 

Если мы вступаем в GetInt из ObsucredSharedPreferences:

@Override 
public int getInt(String key, int defValue) { 
    final String v = delegate.getString(key, null); 
    return v!=null ? Integer.parseInt(decrypt(v)) : defValue; 
} 

Так Вместо того, чтобы нулевое значение от getString Я получаю такое значение, как «ERKJFER89er» (я никогда не пишу этого значения в настройках, в противном случае он должен сбой на каждом телефоне), поэтому, когда он пытается decryp значение, которое он ожидает значение int, и он выбрасывает javax.crypto.BadPaddingException: pad block corrupted Я не знаю, t знать, как обходиться это и как исправить это, любая идея будет оценена

Код дешифрования

protected String decrypt(String value){ 
    try { 
     final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0]; 
     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
     SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT)); 
     Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
     pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Secure.getString(context.getContentResolver(), Secure.ANDROID_ID).getBytes(UTF8), 20)); 
     return new String(pbeCipher.doFinal(bytes),UTF8); 

    } catch(Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

1 пользователь сказал, что сделать сброс к заводским установкам не решает проблему, но сделать завод сбросить с вытирать кэш и стереть данные разрешат его

Полного стек Трассирование для google pixel

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.suduck.upgradethegame/com.darwins.cubegame.WelcomeActivity}: java.lang.RuntimeException: javax.crypto.BadPaddingException: pad block corrupted 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
Caused by: java.lang.RuntimeException: javax.crypto.BadPaddingException: pad block corrupted 
at com.darwins.custom.ObscuredSharedPreferences.decrypt(ObscuredSharedPreferences.java:193) 
at com.darwins.custom.ObscuredSharedPreferences.getInt(ObscuredSharedPreferences.java:134) 
at com.darwins.clases.Logro.<init>(Logro.java:41) 
at com.darwins.clases.LogrosManager.iniciar(LogrosManager.java:64) 
at com.darwins.clases.LogrosManager.<init>(LogrosManager.java:48) 
at com.darwins.motor.CEngine.Inicializar(CEngine.java:141) 
at com.darwins.superclases.CActividad.onCreate(CActividad.java:47) 
at com.darwins.cubegame.WelcomeActivity.onCreate(WelcomeActivity.java:32) 
at android.app.Activity.performCreate(Activity.java:6679) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 
... 9 more 
Caused by: javax.crypto.BadPaddingException: pad block corrupted 
at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(BaseBlockCipher.java:1267) 
at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:1100) 
at javax.crypto.Cipher.doFinal(Cipher.java:2056) 
at com.darwins.custom.ObscuredSharedPreferences.decrypt(ObscuredSharedPreferences.java:190) 
+1

Я столкнулся с тем же вопросом ранее. После этого изменился режим шифрования. –

+0

У меня тоже такая же проблема, есть ли какой-либо вариант, кроме изменения режима шифрования? –

+0

у одного из моих коллег тоже была такая же проблема – M14

ответ

1

Каков результат возврата decrypt(null)? Кажется, что ваше приложение прочитало некоторые неверные данные, которые ранее были написаны неправильно.

Также я заметил, что некоторые устройства имеют различное поведение в пути к папке с данными и, вероятно, вызвали эту проблему.

Одним из возможных решений для вашей проблемы является регистрация контекста аварийной ситуации, включая данные, вызвавшие ошибку дешифрования. Вы можете попробовать некоторые службы онлайн-журнала, такие как Fabric или Logentries. Или вы можете реализовать свой глобальный ExceptionHandler, сохранить данные и отправить данные вам, когда произошел сбой.

IMO, я предпочитаю сохранять все данные в String и анализировать их во время выполнения в случае изменения формата данных.

FYI. Вот моя реализация для предпочтения. Он поддерживает простые/закодированные/зашифрованные предпочтения, сохраненные в SharedPreference. Он также очень прост в распространении, чтобы поддерживать онлайн-настройки.

https://github.com/passos/SimplePreferences/blob/master/library/src/main/java/com/ioenv/preferences/

+0

Да, данные неверны, но проблема в том, что приложение не записывает данные раньше, эта проблема возникает в некоторых устройствах, ПЕРВЫЙ раз, когда приложение пытается прочитать настройки вместо того, чтобы давать значение по умолчанию, оно дает случайный String, но эта строка никогда не записывалась до – D4rWiNS

+0

У меня есть журнал сбоя, я прикрепляю его – D4rWiNS

+0

Вы также можете попытаться определить, является ли это первым исполнением, а затем написать настройки по умолчанию. Это не лучший вариант, но он должен работать. – juanlugm

2

Я не могу сказать, что это гораздо больше, чем догадка, но я дам ему попробовать.

Я видел, что другие используют по умолчанию значение null для SharedPreferences, но мне нравится использовать фактическое значение по умолчанию в виде строки. Исходя из этого, у меня было бы нечто подобное (предполагая, что существует encryt() метод для перехода с decrypt()).

@Override 
public int getInt(String key, int defValue) { 
    final String v = delegate.getString(key, encrypt(String.valueOf(defValue)); 
    return Integer.parseInt(decrypt(v)); 
} 

Если это не исправить проблему, попробуйте ли вы использовать значение, отличное от нуля, в качестве значения по умолчанию. Как насчет пустой строки? Некоторые символы Unicode, которые вы уверены, не могут быть реальным зашифрованным сохраненным значением? EDIT: Это вряд ли проблема. После просмотра документации параметр defValue для getString() является Nullable, что означает, что метод предназначен для обработки нулевого параметра изящно.

Надеюсь, что это поможет и удачи.

EDIT: Я попытался дублировать вашу проблему, но не смог. Я попробовал эмулированное устройство Nexus 5 и реальное устройство Nexus 5, оба с использованием API 23. getString() всегда возвращал null. Я использовал код на основе this. Я предполагаю, что это более или менее тот же код, на котором основывается ваш код.

Опуская неиспользованные методы ...

public class ObscuredSharedPreferences implements SharedPreferences { 

    private static final String TAG = "ObscuredSp"; 
    protected static final String UTF8 = "utf-8"; 
    private static final char[] SEKRIT = "abc".toCharArray() ; // INSERT A RANDOM PASSWORD HERE. 

    protected SharedPreferences delegate; 
    protected Context context; 

    public ObscuredSharedPreferences(Context context, SharedPreferences delegate) { 
     this.delegate = delegate; 
     this.context = context; 
    } 

    @Override 
    public int getInt(String key, int defValue) { 
     final String v = delegate.getString(key, null); 
     Log.d(TAG, "got int " + v); 
     return v!=null ? Integer.parseInt(decrypt(v)) : defValue; 
    } 

    protected String decrypt(String value){ 
     try { 
      final byte[] bytes = value!=null ? Base64.decode(value, Base64.DEFAULT) : new byte[0]; 
      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
      SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT)); 
      Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
      pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID).getBytes(UTF8), 20)); 
      return new String(pbeCipher.doFinal(bytes),UTF8); 

     } catch(Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

В onCreate() ...

private static final String MY_PREFS_FILE_NAME = "MyFile"; 
private static final String KEY_SP_MUSIC_VOLUME = "KeySpMusicVol"; 

final SharedPreferences prefs = new ObscuredSharedPreferences(
      this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE)); 

int musicVolume; 
musicVolume = prefs.getInt(KEY_SP_MUSIC_VOLUME, 10); 
Log.d(TAG, "volume = " + musicVolume); 

Вы могли бы попытаться упростить код, чтобы что-то вроде этого. Если это работает, а ваше - нет, просто нужно удалить, удалив код, пока вы не определите причину проблемы. (Я знаю, что это не обязательно так просто, как это звучит).

Другой вопрос, о чем подумать. Пробовали ли вы как отладочную, так и деблокирующую конфигурацию сборки? Вы удаляете приложение каждый раз, чтобы убедиться, что это действительно первый раз, когда приложение запущено? Является ли объем единственным преимуществом, с которым это происходит?

Я вернулся и перечитал ваш вопрос & Теперь я замечаю, что вы пишете проблемы, о которых сообщает Google Play. Это делает большой вопрос, можете ли вы дублировать это самостоятельно, чтобы вы могли попробовать разные вещи, чтобы определить основную причину?

+0

. Я попробую изменить на другое значение по умолчанию, однако проблема в том, что вместо верните нулевое значение, оно возвращает случайную строку – D4rWiNS

+0

. Большинство ошибок было получено из отчета Google Play или отчета об аварии Firebase, однако, шесть месяцев назад такая же ошибка была на моем Nexus 5, я много чего пробовал, но только формат с кэшем очистки сделайте трюк – D4rWiNS

+0

Если вы хотите указать мне имя приложения, я попробую загрузить его, чтобы узнать, работает ли он на моем Nexus 5. Какой у вас API на вашем? – Gary99