2016-07-14 5 views
4

Я разрабатываю Android-модуль, и я должен использовать общие настройки для хранения токена jwt для автоматического входа в систему и для некоторых других вещей.Общие настройки Безопасность

Я хранил его с ключом, как «токен» или что-то в этом роде.

Проблема заключается в том:

Если разработчик импортировать мой модуль для его применения, а также выяснить, ключ, он может легко прочитать мой JWT фишку, и было бы не хорошо для меня.

Не могли бы вы предоставить мне альтернативное решение?

Edit: Мой минимальный уровень API должен быть 14.

+1

Я никогда не делал этого, но случилось, чтобы найти его вчера, проверьте это https://github.com/sveinungkb/encrypted-userprefs –

+0

В каталоге, где хранятся предпочтения, защищен. Вы хороши, пока устройства не внедрены. –

+0

@MisterSmith, да, я это знаю.Но разработчик, который использует мой модуль, и если он знает ключ для jwt, он может легко прочитать его из своего приложения. –

ответ

0

Вы можете зашифровать ваш маркер перед сохранением в общих настройках и когда вам нужно использовать можно расшифровать и использовать его.

Я предлагаю вам использовать unpredictible ключ, когда вы сохраняете в общие настройки вместо «маркеров»

Вот класс шифрования, который может быть использован в Android приложений для шифрования и дешифрования данных.

public final class Encryption { 
    private static final String CHIPHER_TRANSFORMATION = "AES/ECB/PKCS5Padding"; 
    private static final String GENERATE_KEY__ALGORITHM = "PBKDF2WithHmacSHA1"; 
    private static final String GENERATE_KEY_ALGORITHM = "AES"; 
    public static final int CRYPTO_TYPE_ENCRYPT = 0; 
    public static final int CRYPTO_TYPE_DECRYPT = 1; 

    public static String crypto(String inString, int type, String hashKey, String salt, String charset) { 
     Cipher cipher = null; 
     try { 
      cipher = Cipher.getInstance(CHIPHER_TRANSFORMATION); 
      byte[] inputByte = inString.getBytes(charset); 
      switch (type) { 
       case CRYPTO_TYPE_DECRYPT: 
        cipher.init(Cipher.DECRYPT_MODE, initKey(hashKey, salt)); 
        return new String(cipher.doFinal(Base64.decode(inputByte, Base64.DEFAULT))); 
       case CRYPTO_TYPE_ENCRYPT: 
        cipher.init(Cipher.ENCRYPT_MODE, initKey(hashKey, salt)); 
        return new String(Base64.encode(cipher.doFinal(inputByte), Base64.DEFAULT)); 
      } 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      e.printStackTrace(); 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    private static SecretKey getSecretKey(char[] password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { 
     SecretKeyFactory factory = SecretKeyFactory.getInstance(GENERATE_KEY__ALGORITHM); 
     KeySpec spec = new PBEKeySpec(password, salt, 1024, 128); 
     SecretKey tmp = factory.generateSecret(spec); 
     return (new SecretKeySpec(tmp.getEncoded(), GENERATE_KEY_ALGORITHM)); 
    } 

    private static SecretKey initKey(String hashKey, String salt) { 
     try { 
      return getSecretKey(hashKey.toCharArray(), salt.getBytes()); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (InvalidKeySpecException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 
+0

Как я уже говорил, если я использую AES, я должен хранить мой пароль или ключ где-то, поэтому проблема будет повторяться. –

+0

Код Java может быть легко декомпилирован. Поэтому это предотвратит только атаки неопытных нападавших. – Robert

+0

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

1

Эта проблема не так проста, как кажется. Для того, что я знаю, лучшим решением является сохранение вашего ключа каким-то образом с помощью NDK; C-код сложнее декомпилировать, а уровень защиты выше, чем при использовании простой Java.
Obfuscating Android Applications using O-LLVM and the NDK

Другим решением может быть использование обфускатора String; но, вообще говоря, безопасность через неясность никогда не является хорошей идеей.
Protect string constant against reverse-engineering

+0

Ваша первая идея кажется интересной! –

-1

система Android Keystore позволяет хранить закрытые ключи в контейнере, чтобы сделать его более трудно извлечь из устройства. После того, как ключи находятся в хранилище, они могут быть использованы для криптографических операций с закрытым ключом материалом остающегося неэкспортируемыми. (Примечание: Одна из проблем, он был введен в уровне API 18)

Android обеспечения общих предпочтений с помощью Android система Keystore
https://github.com/ophio/secure-preferences

См эту статью, для подробной информации,
https://medium.com/@vashisthg/android-secure-shared-preferences-10f8356a4c2b#.8nf88g4g0

Другим решением [уровень API, 8]: Obscured Shared Preferences for Android

[ObscuredSharedPreferences.java] https://github.com/RightHandedMonkey/WorxForUs_Library/blob/master/src/com/worxforus/android/ObscuredSharedPreferences.java

Надеется, что это поможет вам!

+0

Я редактирую свой вопрос, я должен использовать api 14. Спасибо за ваш ответ. –

+1

Android Keystore работает на уровне приложений. Поскольку мы говорим о модуле в стороннем приложении, приложение может получить доступ ко всем ключам, доступ к которым может получить модуль. Поэтому в этой ситуации это не поможет. – Robert

Смежные вопросы