암호 유효성 검사를위한 Regexp Java


109

Java 응용 프로그램에서 구성 매개 변수로 사용할 암호 유효성 검사를위한 정규 표현식을 만들고 있습니다.

정규식은 다음과 같습니다.

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

비밀번호 정책은 다음과 같습니다.

  • 8 자 이상

  • 하나 이상의 숫자를 포함합니다.

  • 하나 이상의 하위 알파 문자와 하나의 상위 알파 문자를 포함합니다.

  • 특수 문자 집합 ( @#%$^등) 내에 하나 이상의 문자를 포함합니다 .

  • 공백, 탭 등을 포함하지 않습니다.

포인트 5 만 누락되었습니다. 정규 표현식에서 공백, 탭, 캐리지 리턴 등을 확인할 수 없습니다.

누구든지 나를 도울 수 있습니까?


3
암호 규칙이 잘못되었습니다. 자세한 내용은 참조-암호 유효성 검사 를 참조하십시오.
ctwheels

답변:


317

이 시도:

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

설명:

^                 # 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

모든 규칙이 독립적 인 "모듈"이기 때문에 개별 규칙을 쉽게 추가, 수정 또는 제거 할 수 있습니다.

(?=.*[xyz])구조체 전체 문자열 (먹는다 .*최초로 출현하는) 및 역 추적 [xyz]일치시킬 수있다. [xyz]발견되면 성공하고 그렇지 않으면 실패합니다.

대안은 꺼리는 한정자를 사용하는 것입니다 : (?=.*?[xyz]). 암호 확인의 경우에는 거의 차이가 없으며 훨씬 긴 문자열의 경우 더 효율적인 변형이 될 수 있습니다.

가장 효율적인 변형 (그러나 읽기 및 유지 관리가 가장 어렵 기 때문에 오류 발생 가능성이 가장 높음)은 (?=[^xyz]*[xyz])물론입니다. 이 길이의 정규식과 이러한 목적의 경우 실제 이점이 없기 때문에 그렇게하는 것을 권장하지 않습니다.


15
@ Kerby82 : Java 문자열에서는 백 슬래시를 이스케이프해야합니다. 을 사용해보십시오 \\s. 이는 정규식 요구 사항이 아니라 Java 요구 사항입니다.
Tomalak

1
@Allov 그냥 그렇게 생각하십시오. 강제되지 않는 모든 것은 선택 사항입니다. 시행하지 않으려는 항목에 대한 검사를 제거하십시오. 필요에 따라 솔루션을 쉽게 조정할 수 있어야합니다.
Tomalak

3
이 답변은 "Common Validation Tasks"아래 의 Stack Overflow Regular Expression FAQ 에 추가되었습니다 .
aliteralmind

1
@ shA.t 같은 것입니다. 난 단지 유지하는 노력 (?=...)이 .. 식의 나머지의 설정을 일치하도록 패턴
Tomalak

2
@ shA.t "공백이 아닌 문자 만 포함"( (?=\S+$)) 또는 "공백 문자를 포함하지 않음 "( )을 말하는지 여부 (?!.*\s)는 선호도의 문제입니다. 당신이 더 좋아하는 것을 사용하십시오. :)
Tomalak

55

정규식을 사용한 간단한 예

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

설명 :

  • (?=.*[0-9]) 숫자는 한 번 이상 있어야합니다.
  • (?=.*[a-z]) 소문자는 한 번 이상 있어야합니다.
  • (?=.*[A-Z]) 대문자는 한 번 이상 있어야합니다.
  • (?=.*[@#$%^&+=]) 특수 문자는 한 번 이상 나타나야합니다.
  • (?=\\S+$) 전체 문자열에 공백이 허용되지 않습니다.
  • .{8,} 8 자 이상

5
. {5,10}은 최소 5 자에서 최대 10자를 나타냅니다. 누군가 특정 설명을 찾고있는 경우를 대비하여.
abhy 2015

@iabhi, 나는 이것을 찾고 있었다. 감사합니다.
Akshatha Srinivas

보안 때문에 String 대신 char 배열에 저장된 암호에 Regex를 구현하려고합니다. 그러나 정규식을 char 배열에 어떻게 적용합니까?
AgentM 2010 년

13

이전에 제공된 모든 답변은 동일한 (올바른) 기술을 사용하여 각 요구 사항에 대해 별도의 미리보기를 사용합니다. 그러나 실제로 암호를 사용할 백엔드에 따라 몇 가지 비효율 성과 잠재적으로 대규모 버그가 있습니다.

수락 된 답변에서 정규식으로 시작하겠습니다.

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

우선, Java 는 .NET과 독립적으로 전체 문자열의 유효성을 검사하기 위해 Java를 지원 \A하고 \z이를 사용하는 것을 선호하기 때문에 Pattern.MULTILINE. 이것은 성능에 영향을 미치지 않지만 정규식이 재활용 될 때 실수를 방지합니다.

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

암호에 공백이 포함되어 있지 않은지 확인하고 허용되는 문자를 제한하는 {8,}속기 변수 한정자를 한 번에 사용하여 한 번에 최소 길이 확인을 수행 할 수 있습니다 \S.

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

제공된 암호에 공백이 포함되어 있으면 모든 검사가 수행되고 해당 공백에 대한 최종 검사가 실패하게됩니다. 모든 점을 \S다음 으로 바꾸면이를 방지 할 수 있습니다 .

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

점은 실제로 어떤 문자를 허용하려는 경우에만 사용해야합니다. 그렇지 않으면 (부정 된) 문자 클래스를 사용하여 정규식을 실제로 허용되는 문자로만 제한하십시오. 이 경우에는 별 차이가 없지만 다른 것이 더 적절할 때 점을 사용하지 않는 것은 아주 좋은 습관입니다. 개발자가 점보다 더 적절한 것을 사용하기에는 너무 게으 르기 때문에 엄청난 역 추적 사례가 너무 많습니다 .

초기 테스트에서 암호의 전반부에서 적절한 문자를 찾을 가능성이 높기 때문에 lazy quantifier가 더 효율적일 수 있습니다.

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

그러나 이제 정말 중요한 문제에 대해 설명합니다. 원래 질문이 ASCII로 생각하는 사람이 작성한 것처럼 보인다는 사실에 대한 답변은 없습니다. 그러나 Java에서 문자열은 유니 코드입니다. 비 ASCII 문자가 비밀번호에 허용됩니까? 그럴 경우 ASCII 공백 만 허용되거나 모든 유니 코드 공백을 제외해야합니다.

기본적으로 \sASCII 공백 만 일치하므로 그 역 \S은 모든 유니 코드 문자 (공백 여부) 및 모든 비 공백 ASCII 문자와 일치합니다. 유니 코드 문자는 허용되지만 유니 코드 공백은 허용되지 않는 경우 유니 코드 공백 UNICODE_CHARACTER_CLASS\S제외 하도록 플래그를 지정할 수 있습니다 . 유니 코드 문자가 허용 되지 않으면 공백이나 제어 문자가 아닌 모든 ASCII 문자를 일치시키는 [\x21-\x7E]대신 사용할 수 있습니다 \S.

다음으로 잠재적 인 문제가 있습니다. 제어 문자를 허용 하시겠습니까? 적절한 정규식을 작성하는 첫 번째 단계는 일치하려는 항목과 일치하지 않는 항목을 정확하게 지정하는 것입니다. 기술적으로 유일한 100 % 정답은 제어 문자 또는 비 ASCII 문자와 같은 특정 범위의 문자가 허용되는지 여부를 나타내지 않기 때문에 질문의 암호 사양이 모호하다는 것입니다.


9

지나치게 복잡한 Regex (피할 수있는 경우)를 사용해서는 안됩니다.

  • 읽기 어렵다 (적어도 자신을 제외한 모든 사람에게)
  • 확장하기 어렵다
  • 디버그하기 어렵다

작은 정규식을 많이 사용하는 데 약간의 성능 오버 헤드가있을 수 있지만 위의 점은 쉽게 가중치를 초과합니다.

다음과 같이 구현합니다.

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

그리고 보안 측면에서는 암호를 매우 복잡하고 기억하기 어렵게 만드는 대신 더 긴 암호를 강제하고 잘 알려진 암호 (예 : 12345 및 pass = user)를 방지하는 것이 훨씬 좋습니다.
Martin Rauscher

위의 접근 방식이 마음에 듭니다. 감사합니다!
토마스 랭

1

암호 요구 사항 :

  • 암호는 시스템에서 지원할 수있는 8 자 이상이어야합니다.
  • 비밀번호에는 알파벳, 숫자 및 특수 문자와 같은 그룹 중 최소 2 개 이상의 문자가 포함되어야합니다.

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

나는 그것을 테스트하고 작동합니다.


1

각 유형의 캐릭터에 대한 최소 요구 사항에 관심이있는 사람에게는 Tomalak의 허용 된 답변에 대해 다음 확장을 제안합니다.

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

이것은 최종 정규식 패턴이 아니라 형식화 문자열입니다. 숫자, 소문자, 대문자, 숫자 / 문자가 아닌 문자 및 전체 암호 (각각)에 대해 필요한 최소 항목으로 % d를 대체하십시오. 최대 발생 가능성은 거의 없지만 (최대 0을 원하지 않는 한 이러한 문자를 효과적으로 거부하지 않는 한) 쉽게 추가 할 수 있습니다. 최소 / 최대 제약 조건이 비 연속적인 일치를 허용하도록 각 유형 주변의 추가 그룹화에 유의하십시오. 이것은 우리가 필요한 각 유형의 문자 수를 중앙에서 구성한 다음 위의 형식 지정 문자열을 기반으로 정규식 패턴을 구성하기 위해 해당 정보를 가져 오는 두 개의 서로 다른 모바일 플랫폼과 웹 사이트를 구성 할 수있는 시스템에서 놀라운 일이었습니다.


1

이것은 모든 특수 문자를 확인합니다.

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

1

매개 변수가있는 Java Method 준비

원하는 매개 변수를 복사하여 붙여넣고 설정하기 만하면됩니다.

모듈을 원하지 않는 경우 주석을 달거나 특수 문자에 대해 저가 한대로 "if"를 추가하십시오.

//______________________________________________________________________________
/**
 * 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;
}        


0

나는 이것이 또한 그것을 할 수 있다고 생각합니다 (더 간단한 모드로) :

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

[정규식 데모]


0

쉬운 것

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

  1. (? = anything)-> 모든 입력 문자열에서 긍정적 인 기대를 의미하며이 조건이 작성되었는지 확인합니다. .sample (? =. * [0-9])-> 모든 문자열에 한 자리 숫자가 작성되었는지 확인합니다. 작성되지 않은 경우 false를 반환 합니다.

  2. (?! anything)-> (vise versa) 조건이 작성 되면 부정적 전망이 false를 반환 함을 의미 합니다.

    닫기 의미 ^ (조건) (조건) (조건) (조건) [\ S] {8,10} $


코드 만 답변이 문제에 대한 해결책을 제공 할 수 있지만 일부 설명은 답변의 품질을 크게 향상시킬 수 있습니다.
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>");
}

설명:

  1. 먼저 비밀번호를 문자열로 설정하고 정수 세트 o를 만듭니다.
  2. 그런 다음 for 루프로 각 문자를 확인하십시오.
  3. 문자열에서 숫자를 찾으면 n은 5를 더합니다. 그런 다음 다음 for 루프로 이동합니다. Character.isDigit (s.charAt (i))
  4. 이 루프는 문자열에있는 모든 알파벳을 확인합니다. 발견되면 n에 5를 더 추가하십시오. Character.isLetter (s.charAt (i))
  5. 이제 if 조건으로 정수 n을 확인하십시오. n = 10이 참이면 주어진 문자열은 영숫자이고 그렇지 않으면 그렇지 않습니다.

0

또한 이렇게 할 수 있습니다.

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

0

강력한 암호를위한 샘플 코드 블록 :

(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?=\\S+$).{6,18}
  1. 6 자리 이상
  2. 최대 18 자리
  3. 하나의 숫자
  4. 하나의 소문자
  5. 대문자 1 개
  6. 모든 특수 문자를 포함 할 수 있습니다.

0

RegEx는-

^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*)[^\s]{8,}$
  1. 최소 8 자리 {8,}
  2. 하나 이상의 숫자 (? =. * \ d)
  3. 하나 이상의 소문자 (? =. * [az])
  4. 하나 이상의 대문자 (? =. * [AZ])
  5. 하나 이상의 특수 문자 (? =. * [@ # $ % ^ & + =])
  6. 공백 없음 [^ \ s]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.