Panda3D
 All Classes Functions Variables Enumerations
password_hash.cxx
1 // Filename: password_hash.cxx
2 // Created by: drose (01Sep04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "password_hash.h"
16 
17 // The functions defined within this file rely on algorithms defined
18 // within OpenSSL.
19 #ifdef HAVE_OPENSSL
20 
21 #include "pnotify.h"
22 #include "openssl/evp.h"
23 #include "memoryHook.h"
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: password_hash
27 // Access: Published
28 // Description: Generates a non-reversible hash of a particular
29 // length based on an arbitrary password and a random
30 // salt. This is much stronger than the algorithm
31 // implemented by the standard Unix crypt().
32 //
33 // The resulting hash can be useful for two primary
34 // purposes: (1) the hash may be recorded to disk in
35 // lieu of recording plaintext passwords, for validation
36 // against a password entered by the user later (which
37 // should produce the same hash given a particular
38 // salt), or (2) the hash may be used as input to an
39 // encryption algorithm that requires a key of a
40 // particular length.
41 //
42 // password is the text password provided by a user.
43 //
44 // salt should be a string of arbitrary random bytes (it
45 // need not be crypotographically secure, just different
46 // for each different hash).
47 //
48 // iters should be a number in the thousands to indicate
49 // the number of times the hash algorithm should be
50 // applied. In general, iters should be chosen to make
51 // the computation as expensive as it can be and still
52 // be tolerable, to reduce the attractiveness of a
53 // brute-force attack.
54 //
55 // keylen is the length in bytes of the required key
56 // hash.
57 ////////////////////////////////////////////////////////////////////
58 string
59 password_hash(const string &password, const string &salt,
60  int iters, int keylen) {
61  nassertr(iters > 0 && keylen > 0, string());
62  unsigned char *dk = (unsigned char *)PANDA_MALLOC_ARRAY(keylen);
63  int result =
64  PKCS5_PBKDF2_HMAC_SHA1((const char *)password.data(), password.length(),
65  (unsigned char *)salt.data(), salt.length(),
66  iters, keylen, dk);
67  nassertr(result > 0, string());
68 
69  string hash((char *)dk, keylen);
70  PANDA_FREE_ARRAY(dk);
71  return hash;
72 }
73 
74 
75 
76 #endif // HAVE_OPENSSL
77