Regexp Java pour la validation du mot de passe

109

Je crée une expression régulière pour la validation de mot de passe à utiliser dans une application Java en tant que paramètre de configuration.

L'expression régulière est:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$

La politique de mot de passe est:

  • Au moins 8 caractères

  • Contient au moins un chiffre

  • Contient au moins un caractère alpha inférieur et un caractère alpha supérieur

  • Contient au moins un caractère dans un ensemble de caractères spéciaux ( @#%$^etc.)

  • Ne contient pas d'espace, de tabulation, etc.

Il ne me manque que le point 5. Je ne parviens pas à faire vérifier par l'expression rationnelle l'espace, la tabulation, le retour chariot, etc.

Quelqu'un pourrait-il m'aider?

Kerby82
la source
3
Les règles de mot de passe sont mauvaises. Veuillez consulter Référence - Validation du mot de passe pour plus d'informations.
ctwheels

Réponses:

317

Essaye ça:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

Explication:

^                 # start-of-string
(?=.*[0-9])       # a digit must occur at least once
(?=.*[a-z])       # a lower case letter must occur at least once
(?=.*[A-Z])       # an upper case letter must occur at least once
(?=.*[@#$%^&+=])  # a special character must occur at least once
(?=\S+$)          # no whitespace allowed in the entire string
.{8,}             # anything, at least eight places though
$                 # end-of-string

Il est facile d'ajouter, de modifier ou de supprimer des règles individuelles, car chaque règle est un "module" indépendant.

La (?=.*[xyz])construction mange la chaîne entière ( .*) et revient à la première occurrence où [xyz]peut correspondre. Il réussit s'il [xyz]est trouvé, sinon il échoue.

L'alternative serait à l' aide d' un qualificatif réticent: (?=.*?[xyz]). Pour une vérification de mot de passe, cela ne fera guère de différence, pour des chaînes beaucoup plus longues, cela pourrait être la variante la plus efficace.

La variante la plus efficace (mais la plus difficile à lire et à maintenir, donc la plus sujette aux erreurs) serait bien (?=[^xyz]*[xyz])sûr. Pour une expression régulière de cette longueur et à cette fin, je ne recommanderais pas de le faire de cette façon, car cela n'a pas de réels avantages.

Tomalak
la source
15
@ Kerby82: dans les chaînes Java, les contre-obliques doivent être échappées. Essayez d'utiliser \\s. C'est une exigence Java, pas une exigence regex.
Tomalak du
1
@Allov Pensez-y de cette façon: tout ce qui n'est pas appliqué est facultatif. Supprimez simplement les vérifications des éléments que vous ne souhaitez pas appliquer. Devrait être facile d'adapter la solution à vos besoins.
Tomalak
3
Cette réponse a été ajoutée à la FAQ sur les expressions régulières Stack Overflow , sous "Tâches de validation courantes".
aliteralmind
1
@ shA.t C'est la même chose. J'ai seulement essayé de garder le (?=...)modèle pour qu'il corresponde à la configuration du reste de l'expression ..
Tomalak
2
@ shA.t Que vous disiez "ne contient que des caractères non espace" ( (?=\S+$)) ou "ne contient pas de caractère espace" ( (?!.*\s)) est une question de préférence. Utilisez ce que vous préférez. :)
Tomalak
55

exemple simple utilisant regex

public class passwordvalidation {
    public static void main(String[] args) {
      String passwd = "aaZZa44@"; 
      String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
      System.out.println(passwd.matches(pattern));
   }
}

Explications:

  • (?=.*[0-9]) un chiffre doit apparaître au moins une fois
  • (?=.*[a-z]) une lettre minuscule doit apparaître au moins une fois
  • (?=.*[A-Z]) une lettre majuscule doit apparaître au moins une fois
  • (?=.*[@#$%^&+=]) un caractère spécial doit apparaître au moins une fois
  • (?=\\S+$) aucun espace n'est autorisé dans toute la chaîne
  • .{8,} au moins 8 caractères
agiles
la source
5
. {5,10} représente un minimum de 5 caractères et un maximum de 10 caractères. Juste au cas où quelqu'un cherche une explication spécifique.
abhy
@iabhi, je cherchais ça. Je vous remercie.
Akshatha Srinivas
J'essaie d'implémenter Regex sur un mot de passe stocké dans un tableau de caractères au lieu d'une chaîne pour des raisons de sécurité. Mais comment appliquer une expression régulière à un tableau de caractères?
AgentM
13

Toutes les réponses précédemment données utilisent la même technique (correcte) pour utiliser une anticipation distincte pour chaque exigence. Mais ils contiennent quelques inefficacités et un bogue potentiellement massif, en fonction du back-end qui utilisera réellement le mot de passe.

Je vais commencer par l'expression régulière de la réponse acceptée:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

Tout d'abord, puisque Java prend en charge \Aet que \zje préfère les utiliser pour m'assurer que toute la chaîne est validée, indépendamment de Pattern.MULTILINE. Cela n'affecte pas les performances, mais évite les erreurs lorsque les expressions régulières sont recyclées.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z

Vérifier que le mot de passe ne contient pas d'espaces et vérifier sa longueur minimale peut être fait en un seul passage en utilisant le tout à la fois en mettant le quantificateur variable {8,}sur la sténographie \Squi limite les caractères autorisés:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z

Si le mot de passe fourni contient un espace, toutes les vérifications seront effectuées, seulement pour que la vérification finale échoue sur l'espace. Cela peut être évité en remplaçant tous les points par \S:

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z

Le point ne doit être utilisé que si vous souhaitez vraiment autoriser un caractère. Sinon, utilisez une classe de caractères (annulée) pour limiter votre expression régulière aux seuls caractères qui sont vraiment autorisés. Bien que cela fasse peu de différence dans ce cas, ne pas utiliser le point lorsque quelque chose d'autre est plus approprié est une très bonne habitude. Je vois beaucoup trop de cas de retour en arrière catastrophique parce que le développeur était trop paresseux pour utiliser quelque chose de plus approprié que le point.

Comme il y a de bonnes chances que les tests initiaux trouvent un caractère approprié dans la première moitié du mot de passe, un quantificateur paresseux peut être plus efficace:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z

Mais maintenant pour le problème vraiment important: aucune des réponses ne mentionne le fait que la question originale semble avoir été écrite par quelqu'un qui pense en ASCII. Mais en Java, les chaînes sont Unicode. Les caractères non ASCII sont-ils autorisés dans les mots de passe? Si tel est le cas, seuls les espaces ASCII sont-ils interdits ou tous les espaces Unicode doivent-ils être exclus.

Par défaut, \scorrespond uniquement aux espaces ASCII, donc son inverse \Scorrespond à tous les caractères Unicode (espaces ou non) et à tous les caractères ASCII sans espaces. Si les caractères Unicode sont autorisés mais que les espaces Unicode ne le sont pas, l' UNICODE_CHARACTER_CLASSindicateur peut être spécifié pour \Sexclure les espaces Unicode. Si les caractères Unicode ne sont pas autorisés, ils [\x21-\x7E]peuvent être utilisés à la place de \Spour faire correspondre tous les caractères ASCII qui ne sont pas un espace ou un caractère de contrôle.

Ce qui nous amène au prochain problème potentiel: voulons-nous autoriser les personnages de contrôle? La première étape dans l'écriture d'une expression régulière appropriée est de spécifier exactement ce que vous voulez faire correspondre et ce que vous ne voulez pas. La seule réponse techniquement correcte à 100% est que la spécification du mot de passe dans la question est ambiguë car elle n'indique pas si certaines plages de caractères comme les caractères de contrôle ou les caractères non ASCII sont autorisées ou non.

Jan Goyvaerts
la source
9

Vous ne devriez pas utiliser des expressions régulières trop complexes (si vous pouvez les éviter) car elles sont

  • difficile à lire (du moins pour tout le monde sauf pour vous)
  • difficile à prolonger
  • difficile à déboguer

Bien que l'utilisation de nombreuses petites expressions régulières puisse entraîner une légère surcharge de performances, les points ci-dessus l'emportent facilement.

Je voudrais implémenter comme ceci:

bool matchesPolicy(pwd) {
    if (pwd.length < 8) return false;
    if (not pwd =~ /[0-9]/) return false;
    if (not pwd =~ /[a-z]/) return false;
    if (not pwd =~ /[A-Z]/) return false;
    if (not pwd =~ /[%@$^]/) return false;
    if (pwd =~ /\s/) return false;
    return true;
}
Martin Rauscher
la source
Et du point de vue de la sécurité, il est préférable de forcer des mots de passe plus longs, d'empêcher les mots de passe bien connus (comme 12345 et pass = user) au lieu de rendre les mots de passe super compliqués et difficiles à retenir.
Martin Rauscher
J'aime votre approche ci-dessus. Merci pour ça!
Thomas Lang
1

Exigence de mot de passe:

  • Le mot de passe doit comporter au moins huit (8) caractères lorsque le système peut le prendre en charge.
  • Les mots de passe doivent inclure des caractères d'au moins deux (2) de ces groupements: caractères alphanumériques et spéciaux.

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$

Je l'ai testé et ça marche

Andrew
la source
1

Pour toute personne intéressée par les exigences minimales pour chaque type de personnage, je suggérerais de faire l'extension suivante sur la réponse acceptée de Tomalak:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$

Notez qu'il s'agit d'une chaîne de mise en forme et non du modèle final de regex. Remplacez simplement% d par les occurrences minimales requises pour: chiffres, minuscules, majuscules, non-chiffre / caractère et mot de passe entier (respectivement). Un maximum d'occurrences est peu probable (sauf si vous voulez un maximum de 0, rejetant effectivement de tels caractères) mais ceux-ci pourraient également être facilement ajoutés. Notez le regroupement supplémentaire autour de chaque type afin que les contraintes min / max permettent des correspondances non consécutives. Cela a fonctionné à merveille pour un système où nous pouvions configurer de manière centralisée le nombre de caractères de chaque type dont nous avions besoin, puis demander au site Web ainsi qu'à deux plates-formes mobiles différentes de récupérer ces informations afin de construire le modèle d'expression régulière en fonction de la chaîne de formatage ci-dessus.

Démétrios Christopher
la source
1

Celui-ci vérifie chaque caractère spécial:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$
Ansu
la source
1

Méthode Java prête pour vous, avec paramètres

Copiez et collez simplement et définissez les paramètres souhaités.

Si vous ne voulez pas de module, commentez-le ou ajoutez un "si" comme je l'ai fait pour un caractère spécial

//______________________________________________________________________________
/**
 * Validation Password     */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg)    {
    boolean result = false;
    try {
        if (PASSWORD_Arg!=null) {
            //_________________________
            //Parameteres
            final String MIN_LENGHT="8";
            final String MAX_LENGHT="20";
            final boolean SPECIAL_CHAR_NEEDED=true;

            //_________________________
            //Modules
            final String ONE_DIGIT = "(?=.*[0-9])";  //(?=.*[0-9]) a digit must occur at least once
            final String LOWER_CASE = "(?=.*[a-z])";  //(?=.*[a-z]) a lower case letter must occur at least once
            final String UPPER_CASE = "(?=.*[A-Z])";  //(?=.*[A-Z]) an upper case letter must occur at least once
            final String NO_SPACE = "(?=\\S+$)";  //(?=\\S+$) no whitespace allowed in the entire string
            //final String MIN_CHAR = ".{" + MIN_LENGHT + ",}";  //.{8,} at least 8 characters
            final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}";  //.{5,10} represents minimum of 5 characters and maximum of 10 characters

            final String SPECIAL_CHAR;
            if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
            else SPECIAL_CHAR="";
            //_________________________
            //Pattern
            //String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
            final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
            //_________________________
            result = PASSWORD_Arg.matches(PATTERN);
            //_________________________
        }    

    } catch (Exception ex) {
        result=false;
    }

    return result;
}        
Fausto70
la source
1

Utilisez la bibliothèque Passay qui est une API puissante.

Rengasamy balasubramanien
la source
0

Je pense que cela peut le faire aussi (en mode plus simple):

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$

[Démo Regex]

shA.t
la source
0

facile

("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")

  1. (? = n'importe quoi) -> signifie positif regarde vers l'avant dans toute la chaîne d'entrée et assurez-vous que cette condition est écrite. s'il n'est pas écrit, retourne false .

  2. (?! n'importe quoi) -> (vice versa) signifie négatif attend en avant si la condition est écrite return false .

    fermer la signification ^ (condition) (condition) (condition) (condition) [\ S] {8,10} $

ibrahem shabban
la source
Alors que les réponses codées uniquement peuvent apporter une solution au problème, certaines explications amélioreraient considérablement la qualité de la réponse.
Nigel Ren
0
String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
    if((Character.isDigit(s.charAt(i))))
    {
        n=5;
        break;
    }
    else
    {

    }
}
for(int i=0;i<s.length();i++)
{
    if((Character.isLetter(s.charAt(i))))
    {
        n+=5;
        break;
    }
    else
    {

    }

}

if(n==10)
{
    out.print("Password format correct <b>Accepted</b><br>");

}
else
{
    out.print("Password must be alphanumeric <b>Declined</b><br>");
}

Explication:

  1. Définissez d'abord le mot de passe sous forme de chaîne et créez un ensemble d'entiers o.
  2. Ensuite, vérifiez chaque caractère par boucle for.
  3. S'il trouve un nombre dans la chaîne, le n ajoute 5. Puis passe à la boucle for suivante. Character.isDigit (s.charAt (i))
  4. Cette boucle vérifie tous les alphabets placés dans la chaîne. Si c'est le cas, ajoutez un autre 5 dans n. Character.isLetter (s.charAt (i))
  5. Vérifiez maintenant l'entier n à l'aide de la condition if. Si n = 10 est vrai, la chaîne donnée est alphanumérique, sinon ce n'est pas le cas.
Naresh Babu
la source
0

Vous pouvez également faire comme ça.

 public boolean isPasswordValid(String password) {


    String regExpn =
            "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";

    CharSequence inputStr = password;

    Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(inputStr);

    if(matcher.matches())
        return true;
    else
        return false;
}
RANAJEET BARIK
la source
0

Exemple de bloc de code pour un mot de passe fort:

(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?=\\S+$).{6,18}
  1. au moins 6 chiffres
  2. jusqu'à 18 chiffres
  3. un nombre
  4. une minuscule
  5. une majuscule
  6. peut contenir tous les caractères spéciaux
Sedrettin Çalışkan
la source
0

RegEx est -

^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*)[^\s]{8,}$
  1. au moins 8 chiffres {8,}
  2. au moins un nombre (? =. * \ d)
  3. au moins une minuscule (? =. * [az])
  4. au moins une majuscule (? =. * [AZ])
  5. au moins un caractère spécial (? =. * [@ # $% ^ & + =])
  6. Pas d'espace [^ \ s]
Ankit Kumar Rajpoot
la source