パスワードの強度を検証する正規表現


142

私のパスワード強度基準は以下の通りです:

  • 8文字の長さ
  • 大文字の2文字
  • 1特殊文字 (!@#$&*)
  • 2桁の数字 (0-9)
  • 小文字の3文字

誰かが私に正規表現を教えてくれますか?すべての条件がパスワードで満たされている必要があります。


2
あなたは本当にあなたのパスワードセキュリティ対策をインターネット全体に信頼してもいいですか?
Borealid、2011

12
@Borealid:パスワードポリシーを公開しても、通常セキュリティに大きな影響はありません。一致する場合、ポリシーは正しくありません(「パスワードのみpasswordhello123有効なパスワードです!」)。
Joachim Sauer、

3
@ヨアヒムザウアー:それは私が意味したことではありません。私が言ったのは、ポスターはおそらく彼が受け取るどんな正規表現も信頼するつもりだということでした。そのような良い考えではありません。
Borealid、2011

3
実際、この正規表現はサービスコードに含まれる予定です。盲目的に信頼しない場合は、diffケースをテストします:)
Ajay Kelkar

9
複雑なパスワードルールは通常、より安全なパスワードにつながりません。重要なのは最小の長さのみです。人々は強力なパスワードを大量に覚えることはできず、そのような規則は適切なパスワードスキームを妨害する可能性があります。「Password-2014」のような弱いパスワードを使用するなど、人々はそのようなルールを回避するために非常に独創的になることができます。多くの場合、強力なパスワードではなく、弱いパスワードを使用します。
martinstoeckli 2014年

回答:


428

これらのチェックは、肯定的な先読みアサーションを使用して実行できます。

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

風疹リンク

説明:

^                         Start anchor
(?=.*[A-Z].*[A-Z])        Ensure string has two uppercase letters.
(?=.*[!@#$&*])            Ensure string has one special case letter.
(?=.*[0-9].*[0-9])        Ensure string has two digits.
(?=.*[a-z].*[a-z].*[a-z]) Ensure string has three lowercase letters.
.{8}                      Ensure string is of length 8.
$                         End anchor.

92
少なくともを必要とするn場合は、次のものに置き換え.{8}てください.{n,}
NullUserException

14
完全な説明については+1。私のパスワードルールは異なりますが、あなたの回答に基づいて、正規表現を適用できます。
Morvael 2013年

14
正規表現で起こっていることを説明していただきありがとうございます。これは、構文を実際に使用したことがない私たちにとって、優れた学習例です。

4
正規表現の説明にも感謝します。何が起こっているのか本当に理解せずに、私が見つけた複雑な正規表現を何度も使用しています。
ニコラススミス

4
素晴らしいパターン、なぜ数量詞を使わないのかしら?少なくとも1つの特殊文字、1つの数字、1つの特殊文字、8文字:^(?=。*([AZ]){1、})(?=。* [!@#$&*] {1、})( ?=。* [0-9] {1、})(?=。* [az] {1、}){8,100} $
RockOnGom 2018年

11

長さ0の正の先読みを使用して、各制約を個別に指定できます。

(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[!@#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})

正規表現エンジンが\p表記法をサポートしておらず、純粋なASCIIで十分な場合は\p{Lu}[A-Z]および\p{Ll}で置き換えることができます[a-z]


8

上記の回答は完璧ですが、大きな正規表現ではなく、複数の小さな正規表現を使用することをお勧めします。
長い正規表現を分割すると、いくつかの利点があります。

  • 読みやすさ
  • デバッグのしやすさ
  • 正規表現の一部を追加/削除する容易さ

一般に、このアプローチはコードを簡単に保守できるようにします

そうは言っても、例としてSwiftで作成したコードの一部を共有します。

struct RegExp {

    /**
     Check password complexity

     - parameter password:         password to test
     - parameter length:           password min length
     - parameter patternsToEscape: patterns that password must not contains
     - parameter caseSensitivty:   specify if password must conforms case sensitivity or not
     - parameter numericDigits:    specify if password must conforms contains numeric digits or not

     - returns: boolean that describes if password is valid or not
     */
    static func checkPasswordComplexity(password password: String, length: Int, patternsToEscape: [String], caseSensitivty: Bool, numericDigits: Bool) -> Bool {
        if (password.length < length) {
            return false
        }
        if caseSensitivty {
            let hasUpperCase = RegExp.matchesForRegexInText("[A-Z]", text: password).count > 0
            if !hasUpperCase {
                return false
            }
            let hasLowerCase = RegExp.matchesForRegexInText("[a-z]", text: password).count > 0
            if !hasLowerCase {
                return false
            }
        }
        if numericDigits {
            let hasNumbers = RegExp.matchesForRegexInText("\\d", text: password).count > 0
            if !hasNumbers {
                return false
            }
        }
        if patternsToEscape.count > 0 {
            let passwordLowerCase = password.lowercaseString
            for pattern in patternsToEscape {
                let hasMatchesWithPattern = RegExp.matchesForRegexInText(pattern, text: passwordLowerCase).count > 0
                if hasMatchesWithPattern {
                    return false
                }
            }
        }
        return true
    }

    static func matchesForRegexInText(regex: String, text: String) -> [String] {
        do {
            let regex = try NSRegularExpression(pattern: regex, options: [])
            let nsString = text as NSString
            let results = regex.matchesInString(text,
                options: [], range: NSMakeRange(0, nsString.length))
            return results.map { nsString.substringWithRange($0.range)}
        } catch let error as NSError {
            print("invalid regex: \(error.localizedDescription)")
            return []
        }
    }
}

また、上記のような複雑な正規表現を使用すると、壊滅的なバックトラック(regular-expressions.info/catastrophic.html)を簡単に開くことができます。ユーザーが「奇妙な」パスワードを使用したため、サーバーが100%のCPUでハングアップするまで、これは気付かれない可能性があります。例:^([a-z0-9] +){8、} $(エラーが表示されますか?)
aKzenT


1

codaddictのソリューションはうまく機能しますが、これは少し効率的です:(Python構文)

password = re.compile(r"""(?#!py password Rev:20160831_2100)
    # Validate password: 2 upper, 1 special, 2 digit, 1 lower, 8 chars.
    ^                        # Anchor to start of string.
    (?=(?:[^A-Z]*[A-Z]){2})  # At least two uppercase.
    (?=[^!@#$&*]*[!@#$&*])   # At least one "special".
    (?=(?:[^0-9]*[0-9]){2})  # At least two digit.
    .{8,}                    # Password length is 8 or more.
    $                        # Anchor to end of string.
    """, re.VERBOSE)

否定された文字クラスは、1つのステップで目的の文字まですべてを消費するため、バックトラックは不要です。(ドットスターソリューションは問題なく機能しますが、バックトラックが必要です。)もちろん、パスワードなどの短いターゲット文字列では、この効率の向上は無視できます。


正しいか確認していただけませんか?三重の二重引用符と疑問符の間の最初の行に丸括弧が開いているので、私は疑問です。Pythonコメント(ハッシュ)が後であることがわかります。エンドアンカー(ドル記号)の近くに対応する終了丸括弧が表示されません。私は正規表現ではないことに言及すべきです。
lospejos 2016年

@lospejos-#は、通常の1行コメントの始まりではありません。このハッシュは、a で始まりで終わるコメントグループの一部です。この正規表現には不均衡な括弧はありません。(?#)
ridgerunner 2017年

1
import re

RegexLength=re.compile(r'^\S{8,}$')
RegexDigit=re.compile(r'\d')
RegexLower=re.compile(r'[a-z]')
RegexUpper=re.compile(r'[A-Z]')


def IsStrongPW(password):
    if RegexLength.search(password) == None or RegexDigit.search(password) == None or RegexUpper.search(password) == None or RegexLower.search(password) == None:
        return False
    else:
        return True

while True:
    userpw=input("please input your passord to check: \n")
    if userpw == "exit":
        break
    else:
        print(IsStrongPW(userpw))

1

@codaddictのソリューションが機能します。

また、いくつかのルールを次のように変更することを検討する必要があります。

  1. %、^、(、)、-、_、+、ピリオドなどの特殊文字を追加します。USキーボードの数字記号の上で見逃した特殊文字をすべて追加します。正規表現が使用するものをエスケープします。
  2. パスワードは8文字以上にしてください。単なる静的な数字ではない8。

上記の改善により、柔軟性と可読性を高めるため、正規表現を次のように変更します。

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

基本的な説明

(?=.*RULE){MIN_OCCURANCES,}     Each rule block is shown by (){}. The rule and number of occurrences can then be easily specified and tested separately, before getting combined

詳細説明

^                             start anchor
(?=.*[a-z]){3,}               lowercase letters. {3,} indicates that you want 3 of this group
(?=.*[A-Z]){2,}               uppercase letters. {2,} indicates that you want 2 of this group
(?=.*[0-9]){2,}               numbers. {2,} indicates that you want 2 of this group
(?=.*[!@#$%^&*()--__+.]){1,}   all the special characters in the [] fields. The ones used by regex are escaped by using the \ or the character itself. {1,} is redundant, but good practice, in case you change that to more than 1 in the future. Also keeps all the groups consistent
{8,}                          indicates that you want 8 or more
$                             end anchor

そして最後に、テスト目的のために、ここに上記の正規表現を持つロブリンクがあります


@AFractに感謝します。コードで使用しています。私は可読性と繰り返し性が好きです。将来戻ってそれを変更する必要がある場合、つまりパスワードポリシーが変更された場合のためです。:)
lsu_guy

0

PHPの場合、これは正常に機能します。

 if(preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/", 
 'CaSu4Li8')){
    return true;
 }else{
    return fasle;
 }

この場合、結果は真です

@ridgerunnerのThsk


なんでreturn preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/", 'CaSu4Li8')
aloisdgがcodidact.comに移動

0

別の解決策:

import re

passwordRegex = re.compile(r'''(
    ^(?=.*[A-Z].*[A-Z])                # at least two capital letters
    (?=.*[!@#$&*])                     # at least one of these special c-er
    (?=.*[0-9].*[0-9])                 # at least two numeric digits
    (?=.*[a-z].*[a-z].*[a-z])          # at least three lower case letters
    .{8,}                              # at least 8 total digits
    $
    )''', re.VERBOSE)

def userInputPasswordCheck():
    print('Enter a potential password:')
    while True:
        m = input()
        mo = passwordRegex.search(m) 
        if (not mo):
           print('''
Your password should have at least one special charachter,
two digits, two uppercase and three lowercase charachter. Length: 8+ ch-ers.

Enter another password:''')          
        else:
           print('Password is strong')
           return
userInputPasswordCheck()

0

パスワードは、次の4つの複雑さのルールのうち少なくとも3つを満たす必要があります。

[少なくとも1つの大文字(AZ)、少なくとも1つの小文字(az)、少なくとも1つの数字(0-9)、少なくとも1つの特殊文字—スペースも特殊文字として扱うことを忘れないでください]

10文字以上

最大128文字

同一の文字が連続して2つ以下(例:111は不可)

'^(?!。(。)\ 1 {2})((?=。 [az])(?=。[AZ])(?=。 [0-9])|(?=。[az] )(?=。 [AZ])(?=。[^ a-zA-Z0-9])|(?=。 [AZ])(?=。[0-9])(?=。 [^ a -zA-Z0-9])|(?=。[az])(?=。 [0-9])(?=。* [^ a-zA-Z0-9])){10,127} $ '

(?!。*(。)\ 1 {2})

(?=。[az])(?=。 [AZ])(?=。* [0-9])

(?=。[az])(?=。 [AZ])(?=。* [^ a-zA-Z0-9])

(?=。[AZ])(?=。 [0-9])(?=。* [^ a-zA-Z0-9])

(?=。[az])(?=。 [0-9])(?=。* [^ a-zA-Z0-9])

。{10.127}


0

上記の正規表現はすべて、残念ながらうまくいきませんでした。強力なパスワードの基本ルールは

  • 少なくとも大文字を含む必要があります
  • 少なくとも小文字を含む必要があります
  • 少なくとも数字が含まれている必要があります
  • 少なくとも特殊文字を含む必要があります
  • そして最小の長さ

したがって、Best Regexは

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

上記の正規表現の最小長は8です。これを{8、}から{ any_numberに変更できます。、}に。

ルールの変更?

最小x文字の小文字、y文字の大文字、z文字の数値、合計最小長wが必要だとします。次に、以下の正規表現を試してください

^(?=.*[a-z]{x,})(?=.*[A-Z]{y,})(?=.*[0-9]{z,})(?=.*[!@#\$%\^&\*]).{w,}$

注:正規表現でxyzwを変更します

編集:正規表現の回答を更新

Edit2:追加された変更


あなたの正規表現が一致している12345678あなたはそれがあることを確認されている強力なパスワード?投稿する前に正規表現を試してください。
トト

それはより良いですが、質問には答えません、彼らは1)8文字の長さを望んでいます。2)大文字の2文字。3)1特殊文字(!@#$&*)。4)2つの数字(0-9)。5)小文字の3文字。
トト

@トト今、あなたの考えを共有してくれませんか?
Juned Khatri

正規表現では、2つの必須の大文字が他の文字で区切られる可能性があることは考慮されていません。小文字と数字についても同様です。有効な答えは受け入れられたものです。
トト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.