Sicherheit per Post-It

16

Wie Sie vielleicht wissen, sind Hacker überall und wollen alles hacken. Sie wurden aufgefordert, Kennwortanforderungen zu stellen, die jeden Hacker stoppen . Das Problem ist, dass Ihr Chef gehört hat, dass es schlecht ist, für LOC zu bezahlen, und er bezahlt Ihnen $ 1800 - $ 0,03 * Zeichen pro Monat, damit Sie die einfachste Sache schreiben, die möglicherweise funktionieren könnte. Sie müssen also eine kleine Anzahl von Zeichen verwenden (hoffentlich sehr klein) oder auf andere Weise das Bargeld vergessen. Außerdem ist es Ihrem Chef egal, welche Sprache Sie verwenden.

Die Anforderungen für gute Passwörter sind ähnlich wie in dem genannten Artikel, außer dass die wörterbuchbasierten Anforderungen entfernt wurden, um zu vermeiden, dass die Lösung von externen Dateien abhängt. Sie müssen nicht überprüfen, ob Buchstaben neu angeordnet werden (schwer zu verstehen, was dies tatsächlich bedeutet) Die letzte Regel wurde entfernt (Was ist 3/4?) und überprüft alte Passwörter nicht.

Die genauen Anforderungen nach dem Entfernen bestimmter Anforderungen aus dem verknüpften Artikel sind:

  • habe mindestens 8 Zeichen!
  • nicht länger als 12 Zeichen sein!
  • habe Groß- und Kleinschreibung!
  • habe nicht mehr als 8 Großbuchstaben!
  • habe nicht mehr als 8 Kleinbuchstaben!
  • Habe mindestens 2 Buchstaben!
  • habe einen führenden Brief!
  • mindestens 1 Stelle (n) haben!
  • Sei nicht dein Benutzername!
  • Sei nicht dein Benutzername rückwärts!
  • nicht deinen Benutzernamen enthalten!
  • nicht rückwärts Ihren Benutzernamen enthalten!
  • Du darfst nicht mehr als 1 Paar sich wiederholender Zeichen haben!
  • habe nicht 3 Vorkommen desselben Charakters!
  • kein Karat enthalten (^)
  • kein Leerzeichen enthalten
  • nicht enthalten =
  • nicht conatain &
  • nicht enthalten #
  • nicht enthalten ,
  • nicht conatain ;
  • nicht enthalten "
  • nicht enthalten>
  • nicht enthalten <
  • nicht enthalten [
  • nicht enthalten
  • nicht enthalten )

Alle Rechtschreibfehler auf dieser Liste wurden so belassen, wie sie sind.

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

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

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

Der kürzeste Code gewinnt Geld (als JPG-Datei gesendet). Es muss "Benutzername:" und "Passwort:" anzeigen und mit einer genauen Nachricht antworten.

Konrad Borowski
quelle
1
Schön, eine Code Golf Challenge in einem Daily WTF Artikel zu sehen, +1 ;-)
ChristopheD
1
Das erste Beispiel sollte fehlschlagen ("Groß- und Kleinschreibung!"), Oder?
Howard
@Howard: Dies bedeutet, dass im Kennwort sowohl Groß- als auch Kleinbuchstaben erforderlich sind. Beachten Sie das Fehlen des Wortes "nicht".
Konrad Borowski
Bei einigen Schriftarten ist es nicht sehr offensichtlich, dass das l in diesem ersten Kennwort ein Kleinbuchstabe und nicht die Nummer eins ist. Ich bearbeite es daher, um es durch einen eindeutigen Kleinbuchstaben zu ersetzen.
Peter Taylor
@ PeterTaylor Ah, danke. In der Tat las ich es als 1(Ziffer eins) anstelle von ell.
Howard

Antworten:

8

Perl, 203 194 189 193 Zeichen

Hier ist meine Perl-Einstellung zum Problem:

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."

Die regulären Ausdrücke überprüfen, ob das Passwort:

  • Beginnt mit einem Buchstaben, hat acht bis zwölf Zeichen

  • enthält eine Ziffer

  • enthält einen Großbuchstaben

  • hat acht oder weniger Großbuchstaben

  • hat acht oder weniger Kleinbuchstaben

  • enthält einen Kleinbuchstaben

  • Enthält keine der verbotenen Satzzeichen, drei Vorkommen eines Zeichens, mehr als ein Vorkommen eines doppelten Zeichens, den Benutzernamen oder den umgekehrten Benutzernamen.

(Vielen Dank an Peter Taylor für den Hinweis auf einen Fehler in der 189-Zeichen-Version.)

Brot-Box
quelle
Fand heraus, wie man das auf ideone mit laufen lässt use v5.10;und es scheitert an meinem Testfall "Sind Regexes richtig entkommen". Siehe ideone.com/QKFnZ
Peter Taylor
@PeterTaylor: Ich weiß nichts über Ruby, aber in Perl wäre das fix \Q$u\E|\Q$n(das letzte \Ekann übersprungen werden, wenn dieser Teil zum Ende verschoben würde).
Konrad Borowski
OTOH Ich denke, ein Charakter kann durch Zusammenführen der Wiederholungen als gespeichert werden (.)(.*\1.*\1|\1.*(.)\3)(nicht getestet - ich werde nicht versuchen, eine vollständige Testbatterie mit ideone zu schreiben).
Peter Taylor
5

Ruby, 270 Zeichen

$><<"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."

Eine Ruby-Implementierung basiert auf zwölf regulären Ausdrücken. Jeder Ausdruck ist entweder eine positive Übereinstimmung (die ersten fünf) oder eine negative Übereinstimmung (die letzten sieben). Als Einschränkung darf der Benutzername nur Buchstaben oder Ziffern enthalten.

Positive Übereinstimmungen mit regulären Ausdrücken:

  • /^.{8,12}$/: Mindestens 8 Zeichen! Darf nicht länger als 12 Zeichen sein!
  • /\p{Lower}/und /\p{Upper}/: Groß- und Kleinschreibung!
  • /^(\p{Alpha}.*){2}/: habe mindestens 2 Buchstaben !, habe einen Anfangsbuchstaben!
  • /\d/: mindestens 1 Stelle (n) haben!

Übereinstimmungen mit negativen regulären Ausdrücken:

  • /(\p{Lower}.*){9}/: habe nicht mehr als 8 Kleinbuchstaben!
  • /(\p{Upper}.*){9}/: darf nicht mehr als 8 Großbuchstaben enthalten!
  • /(.)\1.*(.)\2/: darf nicht mehr als 1 Paar sich wiederholender Zeichen enthalten!
  • /(.).*\1.*\1/: habe nicht 3 Vorkommen des gleichen Charakters!
  • /[ ^=&#,;"<>\[|)]/: kein Caret, Leerzeichen, =, &, #, ,,; ",>, <, [, |,)
  • /#{u}/: Sei nicht dein Benutzername! Enthält nicht deinen Benutzernamen!
  • /#{u.reverse}/: nicht dein Benutzername rückwärts sein !, nicht dein Benutzername rückwärts enthalten!
Howard
quelle
Dies entgeht nicht dem Benutzernamen, so dass ein vollkommen gültiges Passwort abgelehnt werden kann. Testfall unter ideone.com/bPpeo
Peter Taylor
@PeterTaylor Deshalb habe ich in meiner Antwort die Einschränkung für Benutzernamen vermerkt.
Howard
1

Python 3, 291 Bytes / Zeichen

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])])

Schöner formatiert und kommentiert:

# 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.
                           ])

Sie finden diese Lösung auf ideone.com , aber die Ausgabe sieht etwas hässlich aus, da dort keine vordefinierten Eingaben oder sogar Zeilenumbrüche angezeigt werden. Auch die Benutzername-Passwort-Kombination "JOE.smith"- "JOE!smith123"wird derzeit als feste Eingabedaten eingegeben.
Ich habe eine Aufschlüsselung aller Prüfungen als Debug-Ausgabe hinzugefügt.

Byte Commander
quelle