Post-Itによるセキュリティ


16

ご存知かもしれませんが、ハッカーはどこにでもいて、すべてをハッキングしたいと考えています。あなたはハッカーを止めるパスワード要件を作るように頼まれました。問題は、上司がLOCにお金を払うのは悪いことだと聞いており、彼が月に挿入する$ 1800-$ 0.03 *文字を支払って、おそらく最も簡単に機能するものを書くようにしていることです。そのため、少数の文字(できれば非常に小さい文字)を使用するか、現金を忘れる必要があります。また、上司は使用する言語を気にしません。

良いパスワードの要件は、前述の記事の要件と似ていますが、外部ファイルにソリューションが依存するのを避けるために辞書ベースの要件が削除され、再配置された文字を確認する必要がありません(実際の意味を理解するのが難しい)、最後のルールは削除され(3/4とは?)、古いパスワードはチェックされません。

リンクされた記事から特定の要件を削除した後の正確な要件は次のとおりです。

  • 少なくとも8文字が必要です!
  • 12文字を超えないでください!
  • 大文字と小文字があります!
  • 大文字は8文字までです!
  • 小文字は8文字までです!
  • 少なくとも2つの文字があります!
  • 一流の手紙があります!
  • 少なくとも1桁が必要です!
  • ユーザー名ではありません!
  • ユーザー名を逆にしてはいけません!
  • ユーザー名が含まれていません!
  • 後方にユーザー名を含めないでください!
  • 繰り返し文字のペアは1つのみです!
  • 同じキャラクターが3回出現していない!
  • カラットを含まない(^)
  • スペースを含まない
  • 含まない=
  • ないconatain
  • #を含まない
  • 含まない、
  • 一致しない;
  • 「を含まない
  • 含まない>
  • <を含まない
  • 含まない[
  • 含まない|
  • を含まない)

このリストのスペルミスはすべてそのまま残されました。

$ ./checkpass
Username: John
Password: L!]E2m69
OK.

$ ./checkpass
Username: John
Password: JohnnhoJ12
Nope.

$ ./checkpass
Username: JOE.smith
Password: JOE!smith123
OK.

最短のコードが賞金を獲得します(JPGファイルとして送信されます)。「ユーザー名:」および「パスワード:」のプロンプトを表示し、正確なメッセージで返信する必要があります。


1
ナイス、デイリーWTFの記事でコードゴルフチャレンジを見て、+ 1 ;-)
ChristopheD

1
最初の例は失敗するはずです(「大文字と小文字があります!」)。
ハワード

@Howard:パスワードには大文字と小文字の両方が必要であることを意味します。「ない」という言葉がないことに注意してください。
コンラッド

一部のフォントでは、その最初のパスワードのlが1番ではなく小文字のellであることはあまり明らかではないため、私はそれを明確な小文字に置き換えるために編集しています。
ピーターテイラー

@PeterTaylorああ、ありがとう。確かに、私はそれ1をエルではなく(数字の1)と読みました。
ハワード

回答:


8

Perl、203 194 189 193文字

私のPerlがこの問題に取り組んでいます:

print"Username: ";chop($u=<>);$n=reverse$u;print"Password: ";$_=<>;
say/^\pL.{7,11}$/*/\d/*/[A-Z]/*9>y/A-Z//&y/a-z//<9*/[a-z]/*
!/[" #,;->^&[|)]|(.)(.*\1.*\1|\1.*(.)\3)|\Q$u\E|\Q$n/?"OK.":"Nope."

正規表現は、パスワードが次のことを順番にチェックします。

  • 文字で始まり、8〜12文字

  • 数字を含む

  • 大文字が含まれています

  • 大文字が8文字以下である

  • 小文字が8文字以下である

  • 小文字が含まれています

  • 禁止された句読点、3文字の出現、2文字以上の出現、ユーザー名、またはユーザー名の反転が含まれていません。

(189文字バージョンのバグを指摘してくれたPeter Taylorに感謝します。)


ideoneでこれを実行する方法を考え出したところuse v5.10;、「正規表現は適切にエスケープされている」テストケースに失敗しました。参照してくださいideone.com/QKFnZ
ピーター・テイラー

@PeterTaylor:Rubyについては知りませんが、Perlでは修正されます\Q$u\E|\Q$n\Eこの部分を最後に移動する場合は、最後の部分をスキップできます)。
コンラッド

OTOH繰り返しをマージすることで1つのキャラクターを節約できると思います(.)(.*\1.*\1|\1.*(.)\3)(テストされていません-テストバッテリー全体をideoneでスクリプトしようとはしません)。
ピーターテイラー

5

ルビー、270文字

$><<"Username: ";u=gets.chop
$><<"Password: ";gets
puts ('^.{8,12}$+\p{Lower}+\p{Upper}+^(\p{Alpha}.*){2}+\d+(\p{Lower}.*){9}+(\p{Upper}.*){9}+(.)\1.*(.)\2+(.).*\1.*\1+[ ^=&#,;"<>\[|)]+'+u+?++u.reverse).split(?+).map{|r|/#{r}/=~$_??A:?B}*""=="AAAAABBBBBBB"?"OK.":"Nope."

ルビーの実装は、12個の正規表現に基づいています。各表現は、正の一致(最初の5つ)または負の一致(後半の7つ)です。制限として、ユーザー名には文字または数字のみを含めることができます。

正の正規表現一致:

  • /^.{8,12}$/:少なくとも8文字!、12文字を超えないでください!
  • /\p{Lower}/および/\p{Upper}/:大文字と小文字があります!
  • /^(\p{Alpha}.*){2}/:少なくとも2つの文字があります!、先頭の文字があります!
  • /\d/:少なくとも1桁が必要です!

負の正規表現の一致:

  • /(\p{Lower}.*){9}/:小文字は8文字までです!
  • /(\p{Upper}.*){9}/:大文字は8文字までです!
  • /(.)\1.*(.)\2/:繰り返し文字のペアは1つ以下にしてください!
  • /(.).*\1.*\1/:同じキャラクターが3回出現しない!
  • /[ ^=&#,;"<>\[|)]/:キャレット、スペース、=、&、#、、、;、 "、>、<、[、|、)を含まない
  • /#{u}/:ユーザー名ではない!、ユーザー名を含まない!
  • /#{u.reverse}/:後方にユーザー名を入れないでください!、後方にユーザー名を含めないでください!

これはユーザー名をエスケープしないため、完全に有効なパスワードは拒否されます。ideone.com/bPpeoの
ピーターテイラー

@PeterTaylorそれが、答えの中でユーザー名の制限に注意した理由です。
ハワード

1

Python 3、291バイト/文字

from re import*
n,p=map(input,["Username: ","Password: "])
c,U,L=lambda x:len(split("[%s]"%x,p)),"A-Z","a-z"
print(["OK.","Nope."][any([8>len(p)>12,2>c(U)>9,2>c(L)>9,3>c(U+L),match(U+L,p),2>c("0-9"),n in p,n[::-1]in p,any(c(x)>3 for x in p),len(findall("(.)\\1",p))>1,c(' ^=&#,;"><[|)')>1])])

より適切にフォーマットされ、コメントが付けられました:

# import all elements from the regular expression module
from re import *

# Get the two lines of user input (username `n`, password `p`):
n, p = map(input, ["Username: ","Password: "])

# Assign some internally useful shortcuts (uppercase letters `U`, lowercase letters `L`):
# `c(x)` counts the occurrences of pattern `x` in the password `p` plus 1
c, U, L = lambda x: len(split("[%s]" % x, p)), "A-Z", "a-z"

# Print the test result: `"OK."` if the `any(...)` function returned `False`, else `"Nope."`.
# The `any(...)` combines the result of all enclosed checks and returns `True` if at least
# one of the checks failed (returned `True`).
print(["OK.", "Nope."][any([                                # vvv--- CHECKS: ---vvv
                             8>len(p)>12,                   # password length 8-12
                             2>c(U)>9,                      # 1-8 uppercase letters
                             2>c(L)>9,                      # 1-8 lowercase letters
                             3>c(U+L),                      # at least 2 letters
                             match(U+L,p),                  # starts with a letter
                             2>c("0-9"),                    # at least 1 digit
                             n in p,                        # username is not (in) the pw.
                             n[::-1]in p,                   # reversed name not (in) the pw.
                             any(c(x)>3 for x in p),        # at most 3 same characters
                             len(findall("(.)\\1",p))>1,    # at most 1 pair (e.g. "AA")
                             c(' ^=&#,;"><[|)')>1])         # does not contain special char.
                           ])

この解決策はideone.comで見つけることができますが、定義済みの入力や改行さえも表示されないため、出力は少しいように見えます。また、ユーザ名とパスワードの組み合わせは"JOE.smith"- "JOE!smith123"現在の固定入力データとして入力されます。
ただし、すべてのチェックの内訳をデバッグ出力として追加しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.