2016-09-26 75 views
0

我需要驗證密碼履行這些規則至少三個結合:
Upper case, lower case, number, special char
密碼也需要至少8個字符長。正則表達式的特定密碼限制

編輯
我知道這些密碼限制是contraproductive,這是一個要求,不是我越來越強密碼天真的想法。

有效密碼的例子:

Password3 // Upper case, lower case, number 
Password! // Upper case, lower case, special 
password3! // Lower case, number, special 
PASSWORD3! // Upper case, number, special 
Password3! // Upper case, lower case, number, special 

無效密碼的示例:

password // Only lower case 
password3 // Only lower case and number 
password! // Only lower case and special 
Password // Only Upper case and lower case 
Pw3!  // Too short 

這裏是一個正則表達式我寫道:

(?=.*[A-z\d]+)(?=.*[[email protected]!?]+)(?=.*[a-z\[email protected]!?]+)(?=.*[A-Z\[email protected]!?]+)[A-z\[email protected]!?]{8,} 

Hopefuly,我知道爲什麼這個正則表達式匹配無效的密碼,如果是的話,我怎麼能說,表達式必須繼續ain從組中的一切,而不僅僅是一場比賽?

+3

爲什麼不直接通過密碼掃描並檢查每個需求?如果你到最後,一個或多個失蹤,那麼你知道你沒有一個有效的字符串。 – NathanOliver

+0

我會建議不要打擾這樣的政策。它們已不再適用於現代密碼破解技術,而這些技術已經涵蓋了所有你可以想到的簡單技巧。他們只是爲你增加更多的工作,並以更多的方式獲取用戶的方式。請使用專業製作的[密碼強度](https://en.wikipedia.org/wiki/Password_strength)檢查程序,或者不要打擾。考慮詢問[Security.SE](https://security.stackexchange.com/)。 – Schwern

+2

至少3 *這些規則的組合*需要一個巨大的正則表達式與變化。更好地將它們分成幾個較小的。 –

回答

1

很明顯,你的問題是一個很難的問題。所以我會把它分成更容易理解的部分。這將有助於這麼多。看看這個例子,我做:

#include <iostream> 
#include <string> 
#include <regex> 

int main(){ 

    bool upper_case = false; //saves the result if upper-case characters were found. 
    bool lower_case = false; //same for lower-case 
    bool number_case = false; //... 
    bool special_char = false; 


    std::regex upper_case_expression{ "[A-Z]+" }; //here is the very simple expression for upper_case search 
    std::regex lower_case_expression{ "[a-z]+" }; //for lower-case 
    std::regex number_expression{ "[0-9]+" }; //... 
    std::regex special_char_expression{ "[@!?]+"}; 


    std::string pw; 


    bool done = false; //let's assume we're not done 

    do{ //do ask-for-password as long were not done 

     std::cout << "Type in a valid password: "; 
     std::getline(std::cin, pw); //get input 

     if (pw.length() <= 8){ //too short! 
      std::cout << "Invalid password! Try again . . .\n\n"; 
     } 
     else{ 

      upper_case = std::regex_search(pw, upper_case_expression); //save the result, if the expression was found. 
      lower_case = std::regex_search(pw, lower_case_expression); //.... 
      number_case = std::regex_search(pw, number_expression); 
      special_char = std::regex_search(pw, special_char_expression); 

      //like: sum_of_positive_results = 1 + 0 + 1 + 1 (true/false as an integer) 
      int sum_of_positive_results = upper_case + lower_case + number_case + special_char; 

      if (sum_of_positive_results < 3){ //not enough booleans were true! 
       std::cout << "Invalid password! Try again . . .\n\n"; 
      } 
      else{ //otherwise it's valid! 
       std::cout << "That's a valid Password!" << std::endl; 
       done = true; 
      } 
     } 

    } while (!done); 

    return 0; 
} 

輸出:

Type in a valid password: password 
Invalid password! Try again . . . 

Type in a valid password: Password 
Invalid password! Try again . . . 

Type in a valid password: password! 
Invalid password! Try again . . . 

Type in a valid password: password3 
Invalid password! Try again . . . 

Type in a valid password: not valid! 
Invalid password! Try again . . . 

Type in a valid password: Password! 
That's a valid Password! 

正如你所看到的,這是更好的方式,更容易跟隨。我希望這對你有所幫助!

+1

我知道如何彙總一些C++代碼來完成這項工作,正如我在評論中所說的,我只是想知道,如果有一種方法可以用一個正則表達式來實現,那就是爲什麼我問,也許我應該指定在我的問題。感謝您的努力!我會將你的答案標記爲一個解決方案,因爲我將以類似的方式驗證它。 – ProXicT

+0

密碼檢查器不會告訴用戶爲什麼密碼未通過檢查,這是不好的用戶體驗。非常令人沮喪。當檢查失敗時,保持單個布爾標誌被翻轉爲false比計數成功次數更容易;很容易添加支票並忘記更新正確的支票。更容易:把它放在一個函數中,並在第一次檢查失敗時返回。 – Schwern

+0

是的,在這種情況下,告訴「無效密碼」是絕對必要的,但這是不好的。我們不想要有效的密碼,爲了測試目的,我們希望看看字符串是否適合4個表達式。 –

1

讓我們一起來看看,password strength checkers like this do not work

理論上,密碼強度檢查器不起作用。這是因爲密碼的強度不取決於密碼值(你給檢查器),而是取決於密碼生成過程(你不經常正規化,更不用說輸入檢查器)。

這是Sophos的主題:"Why you can’t trust password strength meters""Why you STILL can’t trust password strength meters"

簡單的密碼錶檢查密碼的長度和熵,並有用於建議用戶在其密碼中包含的各種事物的清單;例如,大寫和小寫字母,數字和特殊字符的混合。

這有助於確定密碼抵禦暴力攻擊的能力(攻擊者隨機猜測),但是抵抗暴力攻擊只有在攻擊者要做的時候纔有用,噸。

這是Concordia大學,"From Very Weak to Very Strong: Analyzing Password-Strength Meters"

在我們的大型實證分析,很明顯 的是,常用米高度不一致,無法 提供用戶選擇一致的反饋,有時 提供強度測量是公然誤導。

多年來密碼數據庫的所有馬褲都給了攻擊者數年來研究數以億計的真實密碼並尋找可利用的模式。 P4ssw0rd!不會再工作了,他們已經開始使用我們的技巧了。他們知道用4代替a。他們知道在最後粘上標點符號。他們知道大寫字典詞的第一個字母。攻擊者使用低成本的GPU作爲小型超級計算機來進行極端的並行處理來嘗試所有這些技巧。

更重要的是測量密碼熵,基本上它是如何難以匹配您的密碼與現有的模式。它是如何隨機看?人類在創造熵方面真的很糟糕。編寫一個熵檢查器超出了這個答案的範圍。

進行安全密碼的唯一方法是隨機生成每個使用最大可用長度,並將其存儲在一個密碼保險箱佔一個新的。 任何涉及在您的腦海中編寫密碼並記住它們的系統已被破解

要點是:不要打擾。這匹馬離開穀倉後,你正在關門。

現在問題。


做到在多個正則表達式

可以做它作爲一個正則表達式,但你不得不不可讀,不可維護一塌糊塗。如果你想添加它,祝你好運。

另一個原因是很難從一個檢查中找出爲什麼的密碼失敗。沒有什麼比被告知你的密碼無效更煩人,但不是爲什麼。一定要設計你的密碼檢查功能,以便說明檢查失敗。

基本模式是寫一系列的檢查失敗。如果它通過所有這些,它會通過。這是Perl中的草圖。

sub is_invalid_password { 
    my $password = shift; 

    # Instead of hard coding the wording of the message, 
    # use constants. This lets the UX person handle the 
    # wording. Also helps internationalization. 
    return NEEDS_UPPER_CASE unless $password =~ /[A-Z]/; 
    return NEEDS_LOWER_CASE unless $password =~ /[a-z]/; 

    ...and so on... 

    return 0; 
} 

它檢查是否有無效密碼,以便它可以返回失敗錯誤不斷。這使它更簡單易用。只要確保所有的常量是真值,你可以寫:

if(my $reason = is_invalid_password($password)) { 
    # Don't just say the password is invalid, say why. 
    display_invalid_password_reason($reason); 
} 
else { 
    store_password($password); 
} 

正則表達式是...

  1. /[A-Z]/
  2. /[a-z]/
  3. /[0-9]/
  4. /[^A-Za-z0-9]/

哦,等一下......統一。您必須使用POSIX character classes否則您會拒絕Élan1;。這些是Perl如何做的,你的語言可能會有所不同。

  1. /[[:upper:]]/
  2. /[[:lower:]]/
  3. /[[:digit:]]/
  4. /[^[:alnum:]]/

這很容易做到這一點錯誤,惹惱用戶。做正確的工作有點麻煩。它不增加任何安全性。這就是爲什麼我建議不要打擾。

+0

在我幾分鐘前編輯我的問題時,我認爲,您可以刪除有關密碼安全的前奏。我已經在我的問題的評論中告訴過你。我知道任何密碼限制,但長度是不好的,這是不是我的想法要求這樣愚蠢的密碼規則。 我也爲我的問題指定了C++標籤,以防止其他語言的答案。這足以讓我知道,一個正則表達式根本就不是我應該解決這個問題的方式,這就是問題的要點。感謝您的努力。 – ProXicT

+1

@ProXicT如果你問我一把槍,你會得到一個安全簡報(或者更好的比喻,我知道的防彈背心不起作用)。一個壞主意是一個壞主意,即使你被命令去做,但我不能良心回答這個問題,而沒有提出這樣的警告。答案不僅僅針對你,而是針對任何發現它的人。您可能可以使用該信息來對抗訂單。至於C++,語言並不重要,技術是一樣的。 – Schwern

+0

這裏的要點是,我只問了一個問題,以確定是否有辦法只用一個正則表達式來完成任務。我已經得到了我很滿意的答案。我沒有詢問安全問題,因爲我知道這是一個愚蠢的想法,我只是在這裏太小,不能說服其他人。我非常感謝你的努力,但是安全的前奏更適合[Security SE](http://security.stackexchange.com/)。 – ProXicT