Panda3D
 All Classes Functions Variables Enumerations
password_hash.cxx
00001 // Filename: password_hash.cxx
00002 // Created by:  drose (01Sep04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "password_hash.h"
00016 
00017 // The functions defined within this file rely on algorithms defined
00018 // within OpenSSL.
00019 #ifdef HAVE_OPENSSL
00020 
00021 #include "pnotify.h"
00022 #include "openssl/evp.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: password_hash
00026 //       Access: Published
00027 //  Description: Generates a non-reversible hash of a particular
00028 //               length based on an arbitrary password and a random
00029 //               salt.  This is much stronger than the algorithm
00030 //               implemented by the standard Unix crypt().
00031 //
00032 //               The resulting hash can be useful for two primary
00033 //               purposes: (1) the hash may be recorded to disk in
00034 //               lieu of recording plaintext passwords, for validation
00035 //               against a password entered by the user later (which
00036 //               should produce the same hash given a particular
00037 //               salt), or (2) the hash may be used as input to an
00038 //               encryption algorithm that requires a key of a
00039 //               particular length.
00040 //
00041 //               password is the text password provided by a user.
00042 //
00043 //               salt should be a string of arbitrary random bytes (it
00044 //               need not be crypotographically secure, just different
00045 //               for each different hash).
00046 //
00047 //               iters should be a number in the thousands to indicate
00048 //               the number of times the hash algorithm should be
00049 //               applied.  In general, iters should be chosen to make
00050 //               the computation as expensive as it can be and still
00051 //               be tolerable, to reduce the attractiveness of a
00052 //               brute-force attack.
00053 //
00054 //               keylen is the length in bytes of the required key
00055 //               hash.
00056 ////////////////////////////////////////////////////////////////////
00057 string
00058 password_hash(const string &password, const string &salt,
00059               int iters, int keylen) {
00060   nassertr(iters > 0 && keylen > 0, string());
00061   unsigned char *dk = (unsigned char *)PANDA_MALLOC_ARRAY(keylen);
00062   int result =
00063     PKCS5_PBKDF2_HMAC_SHA1((const char *)password.data(), password.length(),
00064                            (unsigned char *)salt.data(), salt.length(),
00065                            iters, keylen, dk);
00066   nassertr(result > 0, string());
00067 
00068   string hash((char *)dk, keylen);
00069   PANDA_FREE_ARRAY(dk);
00070   return hash;
00071 }
00072 
00073 
00074 
00075 #endif  // HAVE_OPENSSL
00076 
 All Classes Functions Variables Enumerations