Perl crypt function for more than 8 letters

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.

Leave a Reply

Your email address will not be published. Required fields are marked *