Panda3D
|
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