http://www.perlmonks.org?node_id=476298

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

This maybe a jr. perl user question. But you guys were really helpful with the my last problem. anyways to the question. Is their any way to encrypt passwords within your code for example:

$password = "password";

If i leave this within my code anyone can get the password. what would be your guys suggestion on how to do this?

Edited by Arunbear: Changed title from 'crypt', as per Monastery guidelines

Replies are listed 'Best First'.
Re: Protecting passwords in source
by Codon (Friar) on Jul 19, 2005 at 23:55 UTC

    What do you mean by "anyone"? How secure do you want to be? What sort of environment are you work with? Do you not want to have the password written down anywhere or only accessible to a few people?

    One way to handle something like this, depending on your environment, is to have a configuration layer that gets read by your script. The password exists in that file only. The file is not kept under source control. It doesn't migrate between environments.

    Another thing that I have seen is you have a read-only user with passwords openly shared. The user can get execute priveledges on stored procedures (in the case of databases) that are owned by a priveledged user. The stored proc controls exactly what can be done. Non-priveledge users can only make changes via stored procs.

    Ivan Heffner
    Sr. Software Engineer, DAS Lead
    WhitePages.com, Inc.
Re: Protecting passwords in source
by GoCool (Scribe) on Jul 20, 2005 at 04:54 UTC
Re: Protecting passwords in source
by DaWolf (Curate) on Jul 20, 2005 at 02:42 UTC
    Your gut probably tells you that putting passwords in code is wrong. Well, it is. Actually storing passwords in plain text in any way (code, text files, databases, etc...) is ALWAYS a bad thing. Notice that I rarely use the word always =)

    Actually we usually don't put passwords in code. I (and this is only me, maybe - probably- someone does it better) do it like this:

    1) In the page that register users I turn the password into a md5 hash and store it in a db.

    2) In the login page, I get the user-typed password, make it into a md5 hash and then compare with the one in the db.

    Anyway, forget about the md5 part - there are tons of encrypting algorythms out there - but it's everything else that matters, meaning:

    1 - Don't EVER store passwords in plain text.
    2 - Don't put it in the code, store in a separate way.

    Regards,
      Ultimately a one-way hash is a good choice. Store your password as a hashed string. Hash the password the user inputs and compare it with the hash of your required password. You can use Digest::MD5 or something else if you'd like. Either way your password isn't visable in the source and is not reversable.

      However, as pointed out above, if everyone else has advanced privileges on the system they can just copy your program and change the hash, or change any part of the program to allow them access. So it is seemingly futile.

Re: Protecting passwords in source
by Fletch (Bishop) on Jul 19, 2005 at 23:55 UTC

    If you encrypted the password, you'd presumably then have to have a password to decrypt it and you're right back where you started from. Start by making the source only readable by the narrowest possible amount of people (possibly by making it setuid, but make sure you've read perldoc perlsec and trim the privileged code down to the bare minimum to get the job done). You could also use a source filter, but that also has limitations (see perldoc -q "hide the source").

    Depending on the application you might be able to use some other means of getting the password to your application (for instance running it under ssh-agent) or running as a different user (sudo or the like). More details about what you need the password for might help people steer you towards a more applicable solution.

    --
    We're looking for people in ATL

      "If you encrypted the password, you'd presumably then have to have a password to decrypt it and you're right back where you started from.

      Not neccessary. An alternative, actually much better, is to compare the crypted password, not to decrypt it. Decrypt could even be impossible. (You got two instances of crypted passwords to compare: 1) at the time when the password is created, you crypt it and store it in the system; 2) when someone try to login or whatever, he/she provides the password, you crypt it in the same way as in step 1, and compare the crypted version with what is stored in the system.)

        Decrypting may be impossible, but you don't have to decrypt it -- you just have to find something that creates the same string when encrypted using the same routines through brute force.

        Computer security is a bit of a misnomer -- it's never secure in an absolute sense, it just has an acceptable risk, normally by using mechanisms that will attempt to reduce a person's chance of managing to gain access without permission before the information loses its value down to an acceptable level.

        But now, we get to the real question -- why is the password in the file? All of these suggestions to store the password using a one way encryption are great, if the script is authenticating a user giving the password. If the script is a client, and needs the password to connect to another service, those suggestions aren't useful.

        The original poster might be interested in the thread Quest: a bulletproof-secure, automated scraper, which had a few suggestions on better protecting a password, but they all just slow down someone trying to get the password, and they're not likely to have a whole lot of help on a system where you don't trust people with root access, who could just change the code to write the unencypted/unobfuscated password before it makes use of it.

        What I took the OP to be asking was how to hide a password which they need to provide to something else (e.g. to a database or an Expect driven ssh session). In that case having a hashed password does you no good, which is why I didn't mention it (the original question was too vague to call it either way).

        --
        We're looking for people in ATL

Re: Protecting passwords in source
by Anonymous Monk on Jul 20, 2005 at 00:43 UTC
    Here is a little background on what i need. Im working with hp-ux where everyone and their brother has superuser privilegus. so their is no way to stop someone from getting in the code and seeing the password If it was hardcoded In. I just wondering if their was a way to have the code encrypt and decrypt the password. I know it would still would be easy to get the password but I just need the password to be hidden.
      So you're working on a system where people you don't trust have root? You're basically screwed. Since they have root there's nothing they can't do. For example, suppose you succeed in hiding the password in your script - what's to stop your adversary from making a copy of your script and changing it to do whatever she wants, using your password?

      I suggest you find a different machine to work on or convince the powers that be to restrict access to root.

      -sam

      just do a rot13, and get some little obfu, ie dont call it $passwd nor its (de)cypher function &decypher...
      Or/and write the password in hexa instead of Ascii, or mix everything...
      Eventually, put this pass and decypher code in a file called ".. " (with the trailing space) which will be called from your script.
      Mixing all of this can be really enough for a beginner admin...

      Eventually, use some Acme::Bleach or Acme::Morse or stuff like that...

      All this is useless against a smart user but should really do the job but remember: if you have a
      decypher($passwd);
      They will immediately do a
      print decypher($passwd);


      At least I would ^^

      P!
      As long as you know it's just obfuscated, not really protected, there are a lot of techniques you could use.

      Rot13 might work (tr[a-z][m-za-l]), or you could try unpacking it to a string of hex digits and then packing it back when you're ready to use it.

Re: Protecting passwords in source
by spiritway (Vicar) on Jul 20, 2005 at 03:33 UTC

    Encrypt the password. Don't decrypt it. When you enter your password, simply encrypt what you enter, and compare it to what is encrypted in the program.

    Example:

    'password' encrypts to 'D4k454NwEj3'.

    Put this into your program. When your program asks for the password, have it create the encrypted version of it, using the same algorithm. Then compare the two results. That way, your clear-text password is never kept on the disk, and your evil cow-orkers won't be able to get at it.

    Check the CPAN archives for encryption modules.

Re: Protecting passwords in source
by thor (Priest) on Jul 20, 2005 at 03:37 UTC
    It depends if you need the password in plaintext to pass to something else. If not, you could do a one time shot with the following:
    perl -le 'print crypt("your password here", "FO")'
    Then in your actual script
    my $password = getpassword(); if ( crypt($password, "FO") ne "crypted password from one-liner") { #your code here }
    However, this provides a false sense of security. There's nothing that prevents someone from copying your script and changing the conditional to if(1) {. One other caveat: don't bother picking a password that's longer than 8 characters; crypt truncates at 8 characters for historical reasons.

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

      However, this limitation can be readily circumvented by using md5crypt() instead (or, in Perl, Digest::MD5).
possible solution -> Bypass use of passwords
by TomDLux (Vicar) on Jul 20, 2005 at 19:39 UTC

    The problem is that anyone can read the password. So find a solution that doesn't involve passwords.

    if the problem is accessing a remote site or copying a file, use ssh/scp and the 'known-hosts' file, or use 'hosts.allow' and 'hosts.deny' on the remote site. There may be similar solutions to accessing databases.

    Tom

    --
    TTTATCGGTCGTTATATAGATGTTTGCA