かなり頻繁に、質問(特に regex とタグ付けされたもの)は、パスワードをvalidateする方法を尋ねます。ユーザーは通常、パスワードに特定の文字が含まれていること、特定のパターンに一致すること、および/または最小文字数に従うことから成るパスワード検証方法を求めているようです。この投稿は、セキュリティを大幅に低下させることなく、ユーザーがパスワード検証に適切な方法を見つけられるようにすることを目的としています。
質問は次のとおりです。どのように適切にパスワードを検証する必要がありますか?
私たち自身のJeff Atwood( Coding Horror のブロガーであり、Stack OverflowとStack Exchangeの共同設立者)は、2017年3月に Password Rules are Bullshit というタイトルのパスワードルールに関するブログを書きました=。この投稿を読んでいない場合は、この投稿の意図を大きく反映しているので、ぜひ読んでください。
NIST(National Institute of Standards and Technology) について聞いたことがない場合は、プロジェクトに正しいサイバーセキュリティ手法を使用していない可能性があります。その場合は、 デジタルアイデンティティガイドライン をご覧ください。また、サイバーセキュリティのベストプラクティスについて最新の状態に保つ必要があります。 NIST Special Publication 800-63B(Revision 3) は、パスワードルールについて次のことに言及しています。
検証者は、記憶されたシークレットに他の構成ルールを課すべきではありません(異なるキャラクタータイプの混合を要求したり、連続して繰り返されるキャラクターを禁止したり)。
フォームデータの検証 のMozillaのドキュメントでさえ、パスワードルールを楽しんでいます( ページアーカイブはこちら ):
「パスワードは8〜30文字で、大文字、記号、数字を1つずつ含む必要があります」(まじで?)
パスワードの構成規則を課すとどうなりますか?あなたは、潜在的なパスワードの数を制限し、ルールに一致しないパスワード順列を削除しています。これにより、ハッカーは攻撃を確実に同じにすることができます! "はい、しかし、四兆(1,000,000,000,000,000または1x1015)パスワードの置換」: 25-GPUクラスターは、6時間以内にすべての標準Windowsパスワードをクラックします (958 = 6,634,204,312,890,625〜6.6x1015 パスワード)。
このStackExchange Securityの投稿 は、上記のXKCDコミックを拡張します。
パスワードの要求を完全に停止し、Google、Facebook、Twitter、Yahoo、またはその他の有効な形式の インターネット運転免許証)でログインできるようにします あなたが慣れていること。最適なパスワードは 保存する必要のないパスワード です。
ソース: パスワードが短すぎます Jeff Atwood。
あなたが本当にあなた自身の認証方法を作成しなければならない場合、少なくとも実証済みのサイバーセキュリティ方法に従ってください。次の2つのセクション(2.1および2.2)は、 現在のNIST出版物 、セクション 5.1.1.2記憶された秘密検証者 から引用したものです。
NISTでは、[〜#〜] should [〜#〜]:
aaaaaa
、1234abcd
)同じ出版物はまた、あなたがSHOULD NOTと述べています:
「適切な」パスワード検証フォームの作成方法を説明するWebサイトが多数あります。これらの多くは古く、使用すべきではありません。
このセクションを読み続ける前に、このセクションの目的は、独自のセキュリティスキームを展開するために必要なツールを提供することではないことに注意してくださいhow現在のセキュリティメソッドvalidateパスワードに関する情報を提供します。独自のセキュリティスキームの作成を検討している場合は、実際に3回考えて、StackExchangeのセキュリティコミュニティの この記事 を読んでください。
最も基本的なレベルでは、パスワードエントロピーは次の式を使用して計算できます。
上記の式で:
この意味は 可能なパスワードの数を表します。または、エントロピーの観点から、すべての可能性を使い果たすために必要な試行回数。
残念ながら、この式が考慮しないのは次のようなものです。
Password1
、admin
John
、Mary
the
、I
drowssap
(パスワードの逆)P@$$w0rd
これらの追加の考慮事項にロジックを追加することは、大きな課題です。プロジェクトに追加できる既存のパッケージについては、3.2を参照してください。
これを書いている時点で、パスワードの強度を推定するための最もよく知られている既存のライブラリは Dropboxによるzxcvbn (GitHubのオープンソースプロジェクト)です。 。netangularjscc#c ++goJavajavascriptobjective-cocamlphppythonrestRubyRustscala
しかし、私は、誰もが異なる要件を持ち、時々人々が間違ったやり方でやりたいと思うことを理解しています。この基準に適合する人(または選択肢がなく、このセクションの上にあるものすべてを上司に提示しているが、メソッドの更新を拒否している人)は、少なくともUnicode文字を許可します。パスワード文字を特定の文字セットに制限する瞬間(つまり、小文字のASCII文字が存在することを確認するa-z
を入力するか、ユーザーが!@#$%^&*()
)、あなたは単にトラブルを求めています!
PS非常に簡単に無効にできるため、クライアント側の検証を信頼しないでください。つまり、 javascript[〜#〜] stop [〜#〜]を使用してパスワードを検証しようとしているユーザーにとっては意味があります。詳細については、 JavaScript:クライアント側とサーバー側の検証 を参照してください。
次の正規表現パターンは、すべてのプログラミング言語で機能するわけではありませんが、多くの主要なプログラミング言語で機能します( Java。netphp - PerlRuby )。次の正規表現はご使用の言語(または言語バージョン)でも機能しない場合があり、代替手段を使用する必要がある場合があることに注意してください(ie python :参照 nicodeプロパティに一致するPython正規表現 ) 。一部のプログラミング言語には、車輪を再発明する代わりに、この種のことをチェックするより良い方法さえあります(つまり、 Password Validation Plugin for mysql を使用します)。 node.js を使用すると、 XRegExp addon または Javascript + Unicode regexes で説明されているUnicodeクラス用の他の変換ツールを使用する場合、以下が有効です。
制御文字が入力されないようにする必要がある場合、パターン[^\P{C}\s]
を使用して、正規表現の一致が発生したときにユーザーにプロンプトを出すことができます。これは、空白文字でもない制御文字(つまり、水平タブ、改行、垂直タブ)のみに一致します。
次の正規表現は、8文字以上のパスワードに少なくとも1つの小文字、大文字、数字、および記号が存在することを保証します。
^(?=\P{Ll}*\p{Ll})(?=\P{Lu}*\p{Lu})(?=\P{N}*\p{N})(?=[\p{L}\p{N}]*[^\p{L}\p{N}])[\s\S]{8,}$
^
行の先頭の位置をアサートします。(?=\P{Ll}*\p{Ll})
(スクリプト内に)少なくとも1つの小文字が存在することを確認します。(?=\P{Lu}*\p{Lu})
(スクリプト内に)少なくとも1つの大文字が存在することを確認してください。(?=\P{N}*\p{N})
(スクリプト内に)少なくとも1つの数字が存在することを確認してください。(?=[\p{L}\p{N}]*[^\p{L}\p{N}])
文字または数字以外の文字(スクリプト内)の少なくとも1つが存在することを確認します。[\s\S]{8,}
8文字以上の任意の文字に一致します。$
行末の位置をアサートします。上記の正規表現をご自身の判断で使用してください。警告されました!