3
votes

Comment envoyer en toute sécurité des mots de passe entre le client Android et l'application côté serveur?

Mon application Android actuelle nécessite que les utilisateurs se connectent avec un nom d'utilisateur et un mot de passe.

L'application Android appelle un service Web REST pour la connexion de l'utilisateur et je ne souhaite pas transmettre le mot de passe en texte clair.

Comment est-ce que je vais sécuriser les mots de passe de mes utilisateurs afin que le côté serveur puisse identifier / authentifier chaque utilisateur?

J'essaie actuellement d'utiliser la bibliothèque Jasypt comme suit: -

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!
}


0 commentaires

4 Réponses :


1
votes

Si vous utilisez Https (TLS), votre mot de passe est inaccessible à quiconque intercepte le réseau.

Vous devez hacher la chaîne de mot de passe dans le code côté serveur et non dans le client

Vous pouvez également utiliser OkHttp CertificatePinner pour épingler un certificat Https (TLS) à votre connexion afin d'éviter les attaques man in the middle.


2 commentaires

Je ne comprends pas pourquoi je n'ai besoin que de hacher mon mot de passe côté serveur. Les utilisateurs se connectent sur l'application Android et je dois passer un appel de service Web pour échanger leur nom d'utilisateur et leur mot de passe contre un jeton d'accès. L'utilisation de points de terminaison HTTPS garantit-elle que les attaquants n'ont aucun moyen de découvrir les noms d'utilisateur et les mots de passe transmis par mon application?


@Hector Yes Https fait exactement ce dont vous avez besoin.



-1
votes

Vous devez prendre en compte deux éléments lors de la mise en œuvre de l'authentification et de l'autorisation entre le client (application mobile) et le serveur. Premièrement, de quel mécanisme d'authentification et d'autorisation votre serveur dispose-t-il pour demander des points de terminaison d'API? (S'agit-il d'une authentification à deux facteurs? S'agit-il d'un jeton porteur (nom d'utilisateur et mot de passe de type octroi)? S'agit-il d'un jeton porteur (jeton d'accès de type octroi )?

Deuxièmement, comme vous ont mentionné que la programmation du serveur est basée sur .Net mais pouvez-vous être plus précis si votre couche de service (Api) écrite en WebApi 2 ou OData?

Enfin, votre serveur permet-il de communiquer avec ou sans SSH, c'est-à-dire HTTP vs Si c'est avec SSH, il est possible de transférer les informations d'identification de l'utilisateur, c'est-à-dire le nom d'utilisateur et le mot de passe, sinon, il ne sera jamais sécurisé pour les informations d'identification de transfert via HTTP.

Alors seulement, il vient à votre fin, c'est-à-dire dans l'application mobile Android pour mettre en œuvre le mécanisme d'authentification et d'autorisation conformément aux exigences du serveur pour communiquer avec les points de terminaison de l'API.

Par exemple, mon serveur doit implémenter une authentification basée sur des jetons (jeton de support et mot de passe de type octroi ) pour faire chaque demande de serveur (GET, POST, DELETE, PUT) et j'ai implémenté en utilisant le client de retrofit comme l ike:

  public interface LoginService {

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

}

et mon service est

 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;
}

Maintenant, je peux utiliser ce jeton dans chaque requête pour communiquer avec le serveur. Je n'ai pas besoin de transférer le nom d'utilisateur et le mot de passe sur Internet public, je n'utilise que le jeton et il a 24 heures d'expiration (car le serveur a mis en œuvre cette date d'expiration de jeton).

J'espère que cela vous aidera à comprendre le mécanisme d'authentification et d'autorisation entre cleint (Android Mobile App) et le serveur.


1 commentaires

mes services Web sont tous des points de terminaison HTTPS; Je dois envoyer à mes utilisateurs le nom d'utilisateur et le mot de passe pour échanger contre un jeton d'accès. Je souhaite que le mot de passe soit haché pour garantir qu'il n'est pas accessible "en transit".




1
votes

Une bonne solution serait d'éviter d'utiliser l'approche traditionnelle de l'authentification par e-mail / mot de passe et de suivre ce qu'une autre réponse suggérée ici est OTP ou One-Time-Password.

Tenez compte de l'expérience utilisateur: saisir un e-mail et un mot de passe sur un appareil mobile est fastidieux, ennuyeux et gênant. Ensuite, ils doivent également se souvenir de leur mot de passe? La personne moyenne dans le monde occidental utilise probablement 10 à 15 applications par jour et nous voulons taxer leurs banques de mémoire humaine pour qu'un autre mot de passe taper maladroitement sur leur téléphone alors qu'ils sont dans une rame de métro bondée?

Bien que ce soit trompeusement difficile à assembler, pensez à One Time Password. Avec lui, un utilisateur entre un numéro de téléphone comme jeton d'identification.

En théorie, chaque utilisateur a son propre numéro de téléphone unique et c'est facile à retenir pour un utilisateur. Puisque votre utilisateur est sur son appareil Android, cela a du sens pour l'instant, non? Et pas de saisie maladroite de l'email et du mot de passe.

Une fois qu'ils ont saisi leur numéro de téléphone, nous leur envoyons un code par SMS sur l'appareil mobile, soit un numéro de 4 à 6 chiffres. L'utilisateur entre ce code dans l'application, prouvant ainsi qu'il est le propriétaire de l'appareil auquel le numéro de téléphone est lié.

L'avantage d'OTP par rapport aux e-mails / mot de passe est qu'il nécessite très peu de mémoire de la part des utilisateurs. Et oui, c'est encore mieux que OAuth, car que se passe-t-il si l'utilisateur ne s'est jamais connecté à un compte Gmail ou à un compte Github via son navigateur mobile? Ensuite, ils sont de retour à l'authentification par e-mail / mot de passe pour appareil mobile.

Le mot de passe à usage unique est convivial.

Mais vous dites d'accord, mais est-ce sécurisé et, plus important encore, à la question ... Comment puis-je faire correspondre le code côté serveur avec le mot de passe utilisateur haché que je vous envoie?

Bien, donc la technologie One Time Password est toujours un projet ambitieux pour l'OMI.

Nous devons donc conserver le code que l'utilisateur doit entrer dans l'appareil afin que nous puissions le comparer à un moment donné dans le futur. Lorsque vous générez un code, enregistrez-le dans Firebase afin qu'à un moment donné dans le futur, vous puissiez revenir vers Firebase et dire que l'utilisateur avec le numéro de téléphone 212-555-1212 vient de vous envoyer le code 1234, est-ce le bon code? / p>

Ainsi, la façon dont Firebase fonctionne avec OTP est que vous pouvez stocker le code dans Firebase. Le défi consiste en fait à envoyer un code à l'utilisateur. Ceci est un message SMS réel. Pour gérer cela, vous ne pouvez pas utiliser Firebase seul, vous pouvez intégrer le très populaire Twilio. Twilio consiste à interagir avec les utilisateurs via des SMS téléphoniques et nous pouvons donc utiliser Twilio pour envoyer un code à l'utilisateur.

Vous pouvez également vous occuper de l'authentification ou du système utilisateur dans Firebase. Une fois que l'utilisateur entre un OTP, nous générons le jeton Web JSON via Firebase.

Donc, tout le stockage JSON et toutes les informations qui reflètent qui est l'utilisateur, tout ce qui peut être enregistré sur Firebase.

Mais il y a une autre partie de cette question à laquelle je n'ai pas répondu:

Comment sécuriser les mots de passe de mes utilisateurs afin que le côté serveur peut identifier / authentifier chaque utilisateur?

D'accord, vous devez donc comparer le code sur un serveur. Cela ne peut pas être Firebase car Firebase est simplement un magasin de données, c'est un endroit pour stocker des données JSON, cela ne nous permet pas d'exécuter du code personnalisé.

Alors, écrivez-vous un serveur pour la comparaison des codes? Nous ne voulons PAS faire cette comparaison sur l'appareil de l'utilisateur.

Alors, que faisons-nous? Aussi, comment générer un code? N'utilisez pas non plus l'appareil de l'utilisateur pour cela.

Alors, où générons-nous le code? Nous savons utiliser le stockage de données Firebase pour stocker le code, mais comment le générer?

C'est un bon travail pour Google Cloud Functions.

Les fonctions Google Cloud sont donc des extraits de code qui s'exécutent une fois à la demande sur les serveurs Google. GCF a une interopérabilité et une intégration étroites avec les magasins de données Firebase.

Nous pouvons ajouter une logique ou un traitement aux données se trouvant à l'intérieur de Firebase. GCF vous permettra une logique personnalisée pour générer vos codes et les enregistrer dans Firebase et GCF peut également comparer le code une fois que l'utilisateur l'a envoyé.

AWS Lambda et GCF ont des fonctionnalités presque identiques, ce qui pourrait également être une option.


0 commentaires