in reply to How to hide a password in a script?

Don't store obfuscated passwords in a script. There will always be a Perl-genius somewhere who can figure it out. Better is to store a cryptographic one-way hash of the password. That makes the password itself inaccessible, no matter what (theoretically), while allowing for simple authentication. The idea is that when the user enters the password, it is hashed using the same algorithm that created the cryptographic hash you've got in your script. This is an irreversible process, but when the algorithm is applied to the password entered by the user, it will match the hashed value you've stored in the script, and you will thus be able to authenticate. However, it's impossible to take that hashed value and use it to figure out the original password.

The other good thing about this approach is that it is unnecessary to obfuscate the code that crypts the password to check against the encrypted hashed value stored in the script, because though the algorithm is known, no way of reversing is known. Most good encryption mechanisms operate this way; they produce irreversible results; results that are impossible to reverse-engineer into the original clear text, even though the encryption algorithm is known.

Update: As with most things in Perl, this has already been done, and tested exhaustively. I recommend the Digest::MD5 module. It will allow you to store a 128bit checksum (an MD5 hash) of the password, against which you can check passwords entered by the user, after passing their entry through the same MD5 algorithm. Bingo!

Update2: I wanted to comment on 'obfu' also. Don't view obfu as a means of writing code that cannot be deciphered. It is only a game, a toy, and at best, a means of exploring the dusty corners of Perl syntax. It's not a way to hide code. It's just for fun.


Dave

  • Comment on Re: How to hide a password in a script?

Replies are listed 'Best First'.
Re^2: How to hide a password in a script?
by dataking (Acolyte) on Aug 06, 2004 at 06:19 UTC
    davido: While I really appreciate your comments, this is a situation that cannot be satisfied by an encrypted solution. This is something that is on a fairly well protected network (1), gives access to a read-only user (2), and deals with a proprietary software client which doesn't support externally encrypted authentication methods(3). Finally, the reason for obfuscation, as opposed to encryption, is that the "stored" password has to be de-obfuscated in order to be passed to an expect program to log into another device (with the read-only account). So, disguising the password, and the disguising the code that disguises the password is sufficient for this particular situation. I understand and acknowledge the risks, and if the situation were different would most likely consider a (permanently) encrypted solution. However, for this particular situation, that simply won't work. Thus, the choice to go with obfuscation. We DO have a "Red Team" that likes to "play", but for the most part, they seem to be more concerned with the windows boxes in our environment, and this particular script resides on a Solaris box. Bottom line, encryption was considered as the preferred option, specifically SSH public key authentication, however, the device we're trying to connect to doesn't support it.

    In response to 'Update2', it's all a game anyway. ;) For this particular situation, I'm not too interested in completely prohibiting *someone* from getting the data (password). But I definitely want to make them work for it. ;)

    So, again, some tips on how to play "the game" would be much appreciated. :D Or at least directions to do some studying.

      Here's why it won't work: no matter how you obfuscate the password and the code to unobfuscate it, the program will still be able to generate the password. And that's where "Red Team" will strike. Observe:

      sub run { do_something(); my $data = get_data(); system("externalprogram -p $data"); } sub get_data { $data = unobfuscate(); return $data; }

      Along comes "Red Team" and tries to crack the system. They read the manual for "externalprogram" and find out that the "-p" flag is for the password, so they edit the run() subroutine to this:

      sub run { do_something(); my $data = get_data(); print "DING DING DING! PASSWORD = $data DING DING!\b"; system("externalprogram -p $data"); }

      If they have access to the script which generates the password, they can find out what the password is, no matter how you obfuscate it.

      Probably the best you can do is to chmod go-rwx script. Then they'll have to crack the user account or root to read the script.

        beable said --> "Probably the best you can do is to chmod go-rwx script. Then they'll have to crack the user account or root to read the script. "


        That's a given. ;)

      "and deals with a proprietary software client which doesn't support externally encrypted authentication methods"

      davido wasn't suggesting that the client did any encryption. All encrpytion is down by the script, nothing external. For example:

      $encrypted_passwd = 'ABS5SGh1EL6bk';  # crypt('secret', 'AB');
      
      $submitted_clear_text_passwd = ...from user input, client socket or whatever...;
      
      $submitted_encrypted_passwd = crypt($clear_text_passwd, substr($encrypted_passwd, 0, 2));
      if ($submitted_encrypted_passwd ne $encrypted_passwd)
      {
        # wrong password
        ...
        exit;
      }
      ...
      

      (Except use MD5 instead of crypt().)