Каков наилучший способ скрыть пароль хранилища ключей в 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-код, который вы используете для расшифровки пароля.