2016-09-26 8 views
0


Upper case, lower case, number, special char
パスワードは、少なくとも8文字の長さにする必要があります。私はこれらのパスワード制限は反対の効果を知っている正規表現特定のパスワードの制限

EDIT
は、その要求ではなく、強力なパスワードを取得する私の素朴なアイデアです。有効なパスワードの

例:無効なパスワードの

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 

例:

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

Hopefuly、私はなぜこの正規表現を知っている:ここで

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 

は、私が書いた正規表現でありますもし無効ならば、無効なパスワードとマッチする1つの試合だけでなく、グループからのすべて?

+3

パスワードを直線的にスキャンし、要件を確認するだけではどうですか?あなたがそれを最後までして、1つまたは複数が見つからない場合、あなたは有効な文字列を持っていないことを知っています。 – 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

パスワードチェッカーが、パスワードがチェックに失敗した理由をユーザーに知らせないのは悪いUXです。非常にイライラ。チェックが失敗したときにfalseを反転させた単一のブール型フラグを保持する方が、成功回数をカウントするよりも簡単です。非常に簡単にチェックを追加し、適切なカウントを更新することを忘れないでください。さらに簡単に:それを関数に入れて、最初のチェック失敗に戻ります。 – Schwern

+0

はい、「有効でないパスワード」を伝えるのは悪いですが、この場合は絶対に必要です。有効なパスワードは必要ありません。テスト目的のために文字列が4式に適合しているかどうかを調べる必要があります。 –

1

この問題を解決しましょう。password strength checkers like this do not work

理論上、パスワード強度チェッカーは機能しません。これは、パスワードの強さは(あなたがチェッカーに与える)パスワードの値に依存するのではなく、パスワード生成プロセス(あなたがしばしば正式化しないで、チェッカーに入ることはありません)に基づいています。

ここには、件名のソフォス:"Why you can’t trust password strength meters""Why you STILL can’t trust password strength meters"があります。

単純なパスワードメーターは、パスワードの長さとエントロピーをチェックし、ユーザーがパスワードに含めることをお勧めする種類のチェックリストを持っています。大文字と小文字の混在、数字や特殊文字などがあります。

これは、ブルートフォース攻撃(攻撃者がランダムに推測する)に耐える能力を判断するのに役立ちますが、ブルートフォース攻撃に耐性があるのは、それが攻撃者がやろうとしている場合にのみ役に立ちます。 t。

ここはConcordia University、"From Very Weak to Very Strong: Analyzing Password-Strength Meters"です。我々の大規模な実証分析において

は、一般的に使用されるメーターは、高度に矛盾しているユーザ選択にコヒーレントなフィードバックを提供する 失敗、時には 露骨紛らわしいある強度の測定値を提供する 明らかです。

パスワードデータベースのすべての長年にわたり、攻撃者は何億年もの真のパスワードを調査し、悪用可能なパターンを探しています。 P4ssw0rd!はもう動作しません。彼らは私たちのトリックを実行しています。彼らはa4に置き換えることを知っています。彼らは最後に句読点をつけることを知っています。彼らは、大文字の大文字は辞書の単語の最初の文字を知っています。攻撃者は、これらのすべてのトリックを試すために極端な並列処理を行うために、スーパーコンピュータとして低コストのGPUを使用します。

さらに重要なことは、パスワードのエントロピーを測定することです。基本的には、パスワードと既存のパターンを一致させることがどれほど難しいかです。どのようにランダムに見ているのですか?人類はエントロピーを作成することに本当に悪いです。エントロピーチェッカーを書くことはこの答えの範囲外です。

安全なパスワードを作成する唯一の方法は、ランダムに利用可能な最大長を使用して、パスワードボールトに格納する各アカウントのための新しいものを生成することです。 あなたの頭の中でパスワードを作成して覚えているシステムは、すでに壊れています

ポイントは:気にしないでください。馬が納屋を離れた後、あなたは扉を閉めています。

今質問に。


複数の正規表現で

それを行います 1つの正規表現としてそれを行うことができますが、その後、あなたは読めない、unmaintainable混乱を持っていると思います。あなたはそれに追加したい場合は、幸運。

もう1つの理由は、なぜパスワードが失敗したかを把握することが難しいことです。あなたのパスワードは無効だが、はなぜではないと言われるより厄介なことはありません。パスワードチェック機能を設計して、どのチェックが失敗したかを確認してください。

基本的なパターンは、失敗する一連のチェックを書き込むことです。それがすべて通過すれば、合格です。ここに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]/

ああ、... Unicodeを待ちます。 POSIX character classesを使用しなければならない場合は、Élan1;を拒否します。 Perlがこれを行う方法です。あなたの言語は変わるかもしれません。

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

それは、この間違った操作を行うと、ユーザーを困らせることは非常に簡単です。正しいことをするのはちょっとした作業です。これはセキュリティを追加するものではありません。これが私が気にしないことをお勧めする理由です。

+0

数分前に私の質問を編集したので、パスワードセキュリティに関する序論を削除することができます。私はすでに私の質問のコメントにあなたに言った。私はパスワードの制限を知っているが、長さは悪いです、それはパスワードのような愚かなルールを要求する私の考えではありません。 他の言語での回答を防ぐために、私の質問にC++タグを指定しました。私が知る限り、正規表現は単にこの問題を解決すべき方法ではなく、それは質問の要点です。しかし、あなたの努力に感謝します。 – ProXicT

+1

@ ProXicT私に銃を求めたら、安全ブリーフィング(またはより良いアナロジー、私がうまくいかないことを知っている弾丸のベスト)を得るつもりです。悪いアイデアは、あなたがそれをするように命じられたとしても、悪いアイデアです。私は良心的にそのような警告なしに質問に答えることはできません。答えはあなたのためではなく、それを見つけた他の人のためです。その情報を使って注文を取り消すことができるかもしれません。 C++については、言語は関係ありません。技術は同じです。 – Schwern

+0

ここでのポイントは、ただ1つの正規表現でタスクを実行する方法があるかどうかを知るために質問したことです。私はすでに私が満足している答えを得ました。私はこれが愚かな考えであることを知っているので、私はセキュリティ問題について尋ねなかった、私は他人を説得するにはあまりにも小さな男だ。私はあなたの努力に本当に感謝していますが、セキュリティの前奏は[Security SE](http://security.stackexchange.com/)のものです。 – ProXicT

関連する問題