Secure password storage

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alvaro G. Vicario

    Secure password storage

    I’m writing a web application that needs to keep passwords in a database.
    These passwords are for third-party services and are different from the
    regular login passwords.

    I don’t like storing this sensitive info as plain text and one-way hashing
    is not an option because I need the actual passwords. I’ve done some quick
    research and it seems that symmetric encryption algorithms (blowfish, AES…)
    provide a reasonable solution—I don’t need a 100% hacker-proof system but I
    don’t want my security to be too dumb.

    These encryption methods, of course, rely on secret keys. And that’s my
    doubt: how do I keep these keys so the system is not too insecure? An
    include file with a constant or variable must be world-readable if I want
    to use if from a web site. If I use the regular login password as key (it’s
    stored as an MD5 hash so it has to be typed every time), users will lose
    all their passwords whenever they forget their login info.

    I’d appreciate any tips or suggestions, as well as links where this
    specific problem is discussed.


    --
    -+ http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
    ++ Mi sitio sobre programación web: http://bits.demogracia.com
    +- Mi web de humor con rayos UVA: http://www.demogracia.com
    --
  • Mark

    #2
    Re: Secure password storage


    Alvaro G. Vicario wrote:
    I'm writing a web application that needs to keep passwords in a database.
    These passwords are for third-party services and are different from the
    regular login passwords.
    >
    I don't like storing this sensitive info as plain text and one-way hashing
    is not an option because I need the actual passwords. I've done some quick
    research and it seems that symmetric encryption algorithms (blowfish, AES....)
    provide a reasonable solution-I don't need a 100% hacker-proof system butI
    don't want my security to be too dumb.
    >
    These encryption methods, of course, rely on secret keys. And that's my
    doubt: how do I keep these keys so the system is not too insecure? An
    include file with a constant or variable must be world-readable if I want
    to use if from a web site. If I use the regular login password as key (it's
    stored as an MD5 hash so it has to be typed every time), users will lose
    all their passwords whenever they forget their login info.
    >
    I'd appreciate any tips or suggestions, as well as links where this
    specific problem is discussed.
    >
    >
    --
    -+ http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
    ++ Mi sitio sobre programación web: http://bits.demogracia.com
    +- Mi web de humor con rayos UVA: http://www.demogracia.com
    --
    I'm probably the most educated person in this field, but if you just
    store one key in a PHP file, it would be pretty hard to hack wouldn't
    it? Don't put it in a database or anything, just include it where ever
    you do your checking.

    $key = 'aerg34aerg324e th'; // random

    Since it's all done server-side no one would have access to it, unless
    they got your FTP info.

    And, better yet, add their username to it (not their password which
    they might forget) and then run your blowfish algorithm on it.

    For my passwords, I've been using md5($password.$ key), but I guess
    that's not an option for you, like you said, so do
    blowfish($passw ord.$username.$ key); or something..

    Comment

    • Andy Hassall

      #3
      Re: Secure password storage

      On Mon, 3 Jul 2006 19:05:55 +0200, "Alvaro G. Vicario"
      <webmaster@NOSP AMdemogracia.co mwrote:
      >I’m writing a web application that needs to keep passwords in a database.
      >These passwords are for third-party services and are different from the
      >regular login passwords.
      >
      >I don’t like storing this sensitive info as plain text and one-way hashing
      >is not an option because I need the actual passwords. I’ve done some quick
      >research and it seems that symmetric encryption algorithms (blowfish, AES…)
      >provide a reasonable solution—I don’t need a 100% hacker-proof system but I
      >don’t want my security to be too dumb.
      >
      >These encryption methods, of course, rely on secret keys. And that’s my
      >doubt: how do I keep these keys so the system is not too insecure?
      The first thing to ask is what do you trust?

      Are you the administrator of the machine, and/or do you trust the person with
      root, and are you the only user of the system? If all of the above, storing the
      key on the machine _may_ be acceptable, but it still depends on the sensitivity
      of the data.

      If you don't explicitly trust the admin, then you can't store the keys on the
      server for the reasons you state, because you can't keep a secret hidden in
      that case.
      >An include file with a constant or variable must be world-readable if I want
      >to use if from a web site.
      Careful there - it needs to be web-server readable, which is not quite as
      broad as world-readable - although in shared hosting it's practically the same.

      There are ways to configure your webserver to run specific scripts under your
      own user credentials instead of "nobody" or whatever generic user that they're
      normally run as. This means that you would be able to access a file that is
      readable by your user only, and inaccessible to other users.

      To read the file, other users on the machine would have to break into your
      account, either to read it directly, or to change the ownership on their own
      scripts to run as you. This doesn't protect at all from abuse by root, but
      works against other normal users.

      Look up "suexec" and "cgiwrap". Since these generally run as CGI instead of
      module you lose some performance, but you can localise the impact to just the
      scripts that need it.
      >If I use the regular login password as key (it’s
      >stored as an MD5 hash so it has to be typed every time), users will lose
      >all their passwords whenever they forget their login info.
      Is that necessarily a bad thing?

      If it is, I wonder if there's an approach you could use where the data is
      encrypted against _two_ secret keys; the user's own login credentials, and an
      administrator key that only you know, and don't store on the machine.

      That way, if a user loses their password, you can do a password reset, decrypt
      their data using your admin key, and re-encrypt it using their new password.

      --
      Andy Hassall :: andy@andyh.co.u k :: http://www.andyh.co.uk
      http://www.andyhsoftware.co.uk/space :: disk and FTP usage analysis tool

      Comment

      • Colin McKinnon

        #4
        Re: Secure password storage

        Mark wrote:
        >
        Alvaro G. Vicario wrote:
        >I'm writing a web application that needs to keep passwords in a database.
        >These passwords are for third-party services and are different from the
        >regular login passwords.
        >>
        >
        I'm probably the most educated person in this field, but if you just
        store one key in a PHP file, it would be pretty hard to hack wouldn't
        it? Don't put it in a database or anything, just include it where ever
        you do your checking.
        >
        $key = 'aerg34aerg324e th'; // random
        >
        A solution is either secure by design or its insecure. That suggestion is
        insecure.

        better solutions (?):

        1) keep all the passwords in a file encrypted with a master key. Don't keep
        the key on the server - ask the user to supply it. Note that you'll
        probably end up storing it in cleartext in a session which is nearly as bad
        as keeping it in a PHP file though, and it's not very handy when you want
        to share the passwords.

        2) use shared secret encryption. While this will allow you to have multiple
        users securely accessing the password (use a quorum of 2 and keep one
        password on the server unencrypted, and one encrypted with the users
        password) it doesn't scale well and is difficult to manage. Still have
        session isolation problem.

        3) use assymetric encryption to distribute the password to the users (stored
        on the server) - each users copy is encrypted using their public key. User
        needs to provide their passphrase to decrypt using their public key on the
        server. This is very secure and scales well. Still doesn't solve the
        session isolation problem though.

        There are ways to solve the session isolation problem...but you've probably
        got enough to think about.

        C.

        Comment

        • Jeff North

          #5
          Re: Secure password storage

          On Mon, 3 Jul 2006 19:05:55 +0200, in comp.lang.php "Alvaro G.
          Vicario" <webmaster@NOSP AMdemogracia.co m>
          <3dekivjoxckt$. v0ni2i9uhbld$.d lg@40tude.netwr ote:
          >| I’m writing a web application that needs to keep passwords in a database.
          >| These passwords are for third-party services and are different from the
          >| regular login passwords.
          >|
          >| I don’t like storing this sensitive info as plain text and one-way hashing
          >| is not an option because I need the actual passwords. I’ve done some quick
          >| research and it seems that symmetric encryption algorithms (blowfish, AES…)
          >| provide a reasonable solution—I don’t need a 100% hacker-proof system but I
          >| don’t want my security to be too dumb.
          You don't mention what database you are using but if you are using
          mySQL 5.x then your half way there (but any database that allows VIEWS
          will suffice).

          What I have done is created 2 Views.
          One to retrieve the decrypted password.
          One to update/change the user details that also encrypts the password.

          The 'get' view looks similar to:
          VIEW vw_get_user_det ails AS
          SELECT ID,UName,AES_DE CRYPT(Pword,'<3 6 character encrypt string>') AS
          pword from usersInfo;

          In php all you will see when validating a user is:
          SELECT * FROM vw_get_user_det ails WHERE Uname='$txtUnam e' AND
          Pword='$txtPWor d'";

          The $txtUname and $txtPword have been 'escaped' to prevent SQL
          injection.

          Alternatively you could use .htaccess file if your host allows it.
          ---------------------------------------------------------------
          jnorthau@yourpa ntsyahoo.com.au : Remove your pants to reply
          ---------------------------------------------------------------

          Comment

          Working...