Как безопасно отправить пароли между клиентом Android и приложением на стороне сервера? - PullRequest
0 голосов
/ 01 января 2019

Мое текущее приложение для Android требует, чтобы пользователи входили с именем пользователя и паролем.

Приложение Android вызывает веб-сервис REST для входа в систему пользователя, и я не хочу передавать пароль в виде открытого текста.

Как мне защитить пароли моих пользователей, чтобы серверная часть могла идентифицировать / аутентифицировать каждого пользователя?

В настоящее время я пытаюсь использовать библиотеку Jasypt следующим образом: -

ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
passwordEncryptor.setAlgorithm("SHA-1");
passwordEncryptor.setPlainDigest(true);
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword)) {
  // correct!
} else {
  // bad login!
}

однако моя серверная часть написана на .NET, и, насколько я понимаю, в документации Jasypt шифровщики паролей используют случайную соль.

Как я могу сделать так, чтобы мой код на стороне сервера совпадал с хешированным паролем пользователя, который я отправляю?

Все мои веб-сервисы имеют конечные точки HTTPS, гарантирует ли это, что никто не сможет "увидеть" пароли моих пользователей "в полете" при обмене на токен доступа?

Ответы [ 4 ]

0 голосов
/ 24 марта 2019

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

Рассмотрим взаимодействие с пользователем: ввод электронной почтыи пароль на мобильном устройстве громоздок, раздражает и неудобен.Тогда они также должны запомнить свой пароль?Среднестатистический человек в западном мире, вероятно, использует от 10 до 15 приложений в день, и мы хотим обложить налогом их банки человеческой памяти за другой пароль, который неудобно вводится на их телефон, когда они находятся в упакованном поезде метро?

Хотя егообманчиво сложно собрать вместе, рассмотрим одноразовый пароль.С его помощью пользователь вводит номер телефона в качестве идентифицирующего токена.

Теоретически, у каждого пользователя есть свой уникальный номер телефона, который легко запомнить.Так как ваш пользователь находится на своем устройстве Android, имеет смысл пока, верно?И никаких неудобных вводов электронной почты и пароля.

После того, как они введут свой номер телефона, мы отправим им код на мобильное устройство, которое будет представлять собой 4-6-значный номер.Пользователь вводит этот код в приложение, тем самым подтверждая, что он является владельцем устройства, к которому привязан номер телефона.

Преимущество OTP по сравнению с электронной почтой / паролем заключается в том, что он требует очень мало памяти для пользователей.часть.И да, это даже лучше, чем OAuth, потому что, если пользователь никогда не входил в учетную запись Gmail или Github через свой мобильный браузер?Затем они возвращаются к аутентификации по электронной почте и паролю для мобильного устройства.

Одноразовый пароль удобен для пользователя.

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

Правильно, поэтому технология One Time Password - это всегда амбициозный проект для ИМО.

Итак, нам нужно сохранить код, который пользователь должен вводить в устройство, чтобы мы могли сравнить его в какой-то момент в будущем.Когда вы генерируете код, сохраните его в Firebase, чтобы в будущем вы могли обратиться к Firebase и сказать, что пользователь с номером телефона 212-555-1212 только что отправил вам код 1234, это правильный код?

Итак, Firebase работает с OTP, если вы можете хранить код в Firebase.Однако на самом деле проблема заключается в том, чтобы написать пользователю код.Это актуальное SMS-сообщение.Чтобы справиться с этим, вы не можете использовать только Firebase, вы можете интегрировать чрезвычайно популярный Twilio.Twilio - это все, что нужно для взаимодействия с пользователями с помощью телефонных SMS-сообщений, поэтому мы можем использовать Twilio для отправки пользователю кода.

Вы также можете позаботиться об аутентификации или о системе пользователя внутри Firebase.Как только пользователь вводит OTP, мы генерируем JSON Web Token через Firebase.

Таким образом, все хранилище JSON и вся информация, которая отражает, кто пользователь, все, что можно сохранить в Firebase.

Но есть другая часть этого вопроса, на которую я не ответил:

Как мне защитить пароли моих пользователей, чтобы на стороне сервера можно было идентифицировать / аутентифицировать каждого пользователя?

Хорошо, вам нужно сравнить код на каком-нибудь сервере.Это не может быть Firebase, потому что Firebase - это просто хранилище данных, это место для хранения данных JSON, оно не дает нам возможности запускать пользовательский код.

Итак, вы пишете сервер для сравнения кодов?Мы НЕ хотим делать это сравнение на устройстве пользователя.

Так что же нам делать?Кроме того, как мы генерируем код?Для этого также не используйте устройство пользователя.

Так, где мы генерируем код?Мы знаем, как использовать хранилище данных Firebase для хранения кода, но как мы его сгенерируем?

Это хорошая работа для облачных функций Google.

Так что облачные функции Google - это фрагменты кода, которые запускают один из них.время по запросу на серверах Google.GCF тесно взаимодействует и интегрируется с хранилищами данных Firebase.

Мы можем добавить некоторую логику или обработку к данным, находящимся внутри Firebase.GCF позволит вам использовать некоторую пользовательскую логику для генерации ваших кодов и сохранения их в Firebase, а GCF также может сравнивать код после его отправки пользователем.

AWS Lambda и GCF почти идентичны по функциональности, что может бытьвариант, а также.

0 голосов
/ 01 января 2019

При реализации аутентификации и авторизации между клиентом (мобильным приложением) и сервером необходимо учитывать несколько моментов.Во-первых, какой механизм аутентификации и авторизации ваш сервер должен запрашивать конечные точки API?(Является ли это двухфакторной аутентификацией? Основана ли она на токене-носителе (имя пользователя и пароль типа предоставления)? На основе токена-носителя (grant-type access-token)?

Во-вторых, как вы упомянули, программирование сервера происходит в .Netна основе, но можете ли вы более конкретно указать, написан ли ваш уровень обслуживания (Api) в WebApi 2 или OData?

Наконец, позволяет ли ваш сервер обмениваться данными с SSH или без него, т. е. HTTP против HTTPS? Если это с SSH, то егоможно передавать учетные данные пользователя, т. е. имя пользователя и пароль, иначе они никогда не будут защищены для передачи учетных данных через HTTP.

Тогда только на вашем конце, то есть в Android Mobile App, будет реализован механизм аутентификации и авторизации для каждого сервера.требование обмениваться данными с конечными точками API.

Например, мой сервер требует реализовать аутентификацию на основе токенов (токен на предъявителя и grant-type password), чтобы каждый запрос к серверу (GET, POST, DELETE, PUT), и я реализовал с помощью модифицированного клиента, как:

 public Retrofit getRetrofitClient() {

    // first add the authorization header
    OkHttpClient mOkClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request newRequest  = chain.request().newBuilder()
                    .addHeader("Authorization", "XXXXXXXXXXXX")
                    .build();
            return chain.proceed(newRequest);
        }
    }).build();

    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .client(mOkClient)
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                .build();
    }
    return retrofit;
}

и мой сервис

  public interface LoginService {

    @POST("/api/token")
    @FormUrlEncoded
    Call<TokenModel> getToken(@Field("username") String username,
                              @Field("password") String password,
                              @Field("grant_type") String grantType);

}

Нетw Я могу использовать этот токен в каждом запросе для связи с сервером.Мне не нужно передавать имя пользователя и пароль через общедоступный Интернет, я использую только токен, срок действия которого истекает 24 часа (так как сервер реализовал эту дату истечения срока действия токена).

Надеюсь, это поможет вам понять механизм аутентификации и авторизации между cleint (Android Mobile App) и сервером.

0 голосов
/ 01 января 2019

Вы должны быть осторожны с тем, что вы делаете.Подумайте о реализации общего двухфакторного алгоритма совместного использования ключей, такого как TOTP .
Довольно необычной, но действительно хорошей практикой является хеширование на стороне клиента .Это, конечно, не мешает хакеру войти в учетную запись пользователя, но мешает им получить потенциально повторно используемый текстовый пароль.
Я рекомендую, чтобы смена E-mail и пароля производилась в сбросить пароль формула, так что требуется подтверждение по электронной почте / SMS.
И, наконец, очень важно, чтобы соединение, где происходит вход, было безопасным, например, https / tls.

0 голосов
/ 01 января 2019

Если вы используете протокол Https (TLS), тогда ваш пароль будет недоступен для всех, кто перехватывает сеть.

Вы должны хешировать строку пароля в коде на стороне сервера, а не в клиенте

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...