I noticed while testing a new security module for my web interface that the password was working even when I added characters to the end of it. You see, I was trying to test the security module to ensure that when the wrong password was entered, the program would deny my access. I found the opposite to be true.
When I added a 1 to the password, the script let me in. I was pretty alarmed by this and spent a good bit of time retracing the logic until I discovered that the crypt function ignores any letters after the first 8. You can duplicate the issue with this code snippet:
sub _cust_crypt { my ($password) = @_; return crypt($password, "0Kry0N4ut"); }
I googled the issue as you probably did to find this page, and I found there were a number of ways to encrypt passwords, but nothing that I could implement in a few minutes.
Encrypt Every 8 Letters Separately:
A pretty simple solution became apparent in a few minutes. I’d just chop the password up into eight-letter groupings and concatenate them all together to form my encrypted password.
sub _cust_crypt { my ($password) = @_; $cryptedPass = ""; for $set ( unpack("(A8)*", $password)){ $cryptedPass .= crypt($set, "0Kry0N4ut"); } return $cryptedPass; }
The real beauty of this subroutine is that you can modify it to further obfuscate passwords by:
- encrypting 1-8 letters at a time ( see the bold/italics section above to specify a different number of letters) .
- rotate the salt depending on the username, or use the username as salt (show in bold above)
- reverse the order of concatenation of the encrypted segments.
- duplicate or triplicate the concatenation to make the stored passwords very long.
So long as no one has your source code, you can get a pretty good security system with the strategy above.