Ekanvitha9 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,I have written a code to validate the password of size must eqaul to 8,and must contain one capital&small letters,digits and special characters.

#!usr/bin/perl use strict; use warnings; print("Enter the password:"); $password=<>; @pw=split('',$password); $size=@pw; if($size==9){ if($password=~m/\w+\d+\@|#|\$|%|\\|\//i) { print("you're now authenticated\n"); } else{ print("Please enter the correct password\n"); } }

I need to include all special characters like `~!^&*()_-+={}[]|\'";:/?.><,.Is this possible

Replies are listed 'Best First'.
Re: How can I use all special characters in perl
by holli (Abbot) on Jul 03, 2019 at 11:53 UTC
    Imposing password rules onto you users does not improve security. It lessens it. Every rule helps an attacker to narrow down the search space (makes it easier to guess the password). If you want to good password security then require a minimum length of 10 (better 12) and make sure your system supports unicode so people can use accented characters.

    Obligatory xkcd. Also, it is not uncommon to check new passwords against a list of common passwords and reject them if neccessary.


    holli

    You can lead your users to water, but alas, you cannot drown them.
Re: How can I use all special characters in perl
by hippo (Archbishop) on Jul 03, 2019 at 12:09 UTC

    If this is just for your own learning experience then do take a look at character classes as other monks have already advised.

    However, if you intend to use this in production then please leverage the experience of others and consider something like Password::Policy instead.

Re: How can I use all special characters in perl
by Corion (Patriarch) on Jul 03, 2019 at 11:58 UTC

    I wrote a module to generate such regular expressions, but it's not yet available on CPAN. You can find it currently on Github at Regexp-PasswordValidation.

    The approach of the regular expressions it creates is to generate one lookahead group for each required character from a set:

    (?=(?:.*[A-Za-z].*){1}) # at least one of A-Za-z (?=(?:.*[0-9].*){1}) # at least one of 0-9 (?=(?:^.{8}$) # match exactly 8 charactters

    ... and so on.

    Combining these gives:

    qr/^ (?=(?:.*[A-Za-z].*){1}) # at least one of A-Za-z (?=(?:.*[0-9].*){1}) # at least one of 0-9 (?=(?:^.{8}$) # match exactly 8 charactters $ /x;
Re: How can I use all special characters in perl
by choroba (Cardinal) on Jul 03, 2019 at 11:47 UTC
    Update: I misread the question. You can still find some advice here, but my reply doesn't fully answer your question.

    Your regex checks that the password has at least one word character somewhere, followed by at least one digit, followed by an at-sign, or it contains an octothorpe, or it contains a dollar sign, or a percent sign, or a backslash, or a forward slash.

    Use a character class intead. You need to escape ], $, \, and - in it, nothing else. You need to escape a slash, too, because it's the delimiter of the whole regex.

    You can use a regex match to check both the valid characters and the length of the password:

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; print 'Enter the password: '; chomp( my $password = <> ); if ($password =~ /^[\w\d@#\$%`~!^&*()_\-+={}[\]|\\'";:\/?.><,]{8}$/) { say "You're now authenticated."; } else{ say 'Please enter the correct password'; }
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: How can I use all special characters in perl
by afoken (Chancellor) on Jul 03, 2019 at 22:29 UTC
    size must eqaul to 8

    OK for learning, bad for production code. Don't limit the password length, it that makes passwords weak. See also https://xkcd.com/936/. Of course, you may want to prevent short passwords, i.e. require a minimum length (8 chars minimum, more required when computers get faster).

    Also, you don't want to hardcode a password, or store it in plain text somewhere. State of the art is to use a salted hash (google it), i.e. generate a short random string (the salt), put original password and salt into a strong hash function, store salt and hash value. To verify an entered password, reuse the salt, put entered password and salt into the same hash function, and verify that the new hash value matches the stored hash value.

    Regarding your code, there is no need to split the input into an array. Use length to get the number of characters in a string. Also, you may want to use chomp on your input to remove the trailing newline.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: How can I use all special characters in perl
by ForgotPasswordAgain (Vicar) on Jul 04, 2019 at 14:54 UTC

    I see a few problems anyway:

    1. To check the length, there is a length function. No need to split it into an array.
    2. The \d and \w match more than you might think! As noted in perlrecharclass, "unless the /a modifier is in effect \d not only matches the digits '0' - '9', but also Arabic, Devanagari, and digits from other languages. This may cause some confusion, and some security issues".
    3. I doubt the order of type of characters matters, so you wouldn't want word characters followed digits, etc., but any of them in any order, so you'd use (as mentioned in other comments) a character class.

Re: How can I use all special characters in perl
by betmatt (Scribe) on Jul 06, 2019 at 14:25 UTC
    You might want to consider use an elsif statement, to screen out attempts to inject SQL components. Those people that try SQL injection are best kept away. Update: I was thinking combination of characters. Your right though below. There probably wouldn't be any cases where placeholders is not the best option.
      attempts to inject SQL components

      Preventing SQL injections is better done using placeholders instead of preventing certain characters from being used.