Каков наилучший способ скрыть пароль хранилища ключей в Android?

Я новичок в разработке Android и реализации SSLSockets. После некоторых копаний я смог настроить простой сервер / клиент, который работает. Реализация, которую я чувствую, может использовать некоторую работу и поставить вопрос о том, как загрузить пароль в хранилище ключей, не имея его в виде простого текста. Вот код, который находится на стороне клиента. Как вы можете видеть, я жестко запрограммировал пароль в локальную переменную. Есть ли лучший способ загрузить пароль хранилища ключей, чтобы в коде его не было в виде простого текста?

    char [] KSPASS = "password".toCharArray();
    char [] KEYPASS = "password".toCharArray();
    try {
        final KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), KSPASS);

        final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManager.init(keyStore, KEYPASS);

        final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustFactory.init(keyStore);

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);
        Arrays.fill(KSPASS, ' ');
        Arrays.fill(KEYPASS, ' ');

        KSPASS = null;
        KEYPASS = null;

Обновить:

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

        final KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), null);

        final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManager.init(keyStore, null);

        final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustFactory.init(keyStore);

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);

2 ответа

Решение

Ну, это не простая проблема для начала.

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

Если это невозможно, то ваша проблема возникает, если кто-то имеет доступ к банкам и "видит" код и впоследствии пароль. Вы можете делегировать пользователю защиту этих банок.

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

В конце концов, это зависит от того, какие требования к безопасности у вас есть.

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

Один из вариантов, который вы могли бы рассмотреть, - хранить пароли, но шифровать пароль с помощью PIN-кода, предоставленного пользователем. Затем, когда пользователь хочет получить доступ к своему паролю, он просто предоставляет PIN-код, который вы используете для расшифровки пароля.

Другие вопросы по тегам