diff options
author | lloyd <[email protected]> | 2010-02-01 17:28:20 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-02-01 17:28:20 +0000 |
commit | 121ca16daa158315682373213e150d9c18c28cdb (patch) | |
tree | 3dc90121a407ff31a89aa1d24632447b9993ccaa /doc | |
parent | 05a9ad7281fb528636534a669db3ba8ae15b1d3b (diff) |
Password hashing is a pretty useful service, really. Move the guts of
the passhash example to the library. Support variable work factors;
default work factor of 10 takes about half a second to do one password
on my Core2. Switch to using SHA-512 instead of SHA-1 in PBKDF2. To keep
the output evenly sized for base64 purposes, reduce PBKDF2 output size by
one byte (to 112 bits).
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/passhash.cpp | 65 | ||||
-rw-r--r-- | doc/log.txt | 1 |
2 files changed, 8 insertions, 58 deletions
diff --git a/doc/examples/passhash.cpp b/doc/examples/passhash.cpp index 8c50de072..0949e944c 100644 --- a/doc/examples/passhash.cpp +++ b/doc/examples/passhash.cpp @@ -5,17 +5,11 @@ */ #include <botan/botan.h> -#include <botan/pbkdf2.h> -#include <botan/hmac.h> -#include <botan/sha160.h> +#include <botan/passhash.h> #include <iostream> #include <memory> -using namespace Botan; - -std::string password_hash(const std::string& pass, - RandomNumberGenerator& rng); -bool password_hash_ok(const std::string& pass, const std::string& hash); +#include <stdio.h> int main(int argc, char* argv[]) { @@ -33,14 +27,16 @@ int main(int argc, char* argv[]) if(argc == 2) { - AutoSeeded_RNG rng; + Botan::AutoSeeded_RNG rng; + + Botan::u32bit work_factor = 10; std::cout << "H('" << argv[1] << "') = " - << password_hash(argv[1], rng) << '\n'; + << Botan::password_hash(argv[1], rng, work_factor) << '\n'; } else { - bool ok = password_hash_ok(argv[1], argv[2]); + bool ok = Botan::password_hash_ok(argv[1], argv[2]); if(ok) std::cout << "Password and hash match\n"; else @@ -54,50 +50,3 @@ int main(int argc, char* argv[]) } return 0; } - -const u32bit SALT_BYTES = 8; // 64 bits of salt -const u32bit PBKDF_OUTPUT_LEN = 16; // 128 bits output -const u32bit KDF_ITERATIONS = 100000; - -std::string password_hash(const std::string& pass, - RandomNumberGenerator& rng) - { - PKCS5_PBKDF2 kdf(new HMAC(new SHA_160)); - - SecureVector<byte> salt(SALT_BYTES); - rng.randomize(&salt[0], salt.size()); - - // Encode the salt plus 96 bits of PBKDF2 output - - Pipe pipe(new Base64_Encoder); - pipe.start_msg(); - pipe.write(salt); - pipe.write(kdf.derive_key(PBKDF_OUTPUT_LEN, pass, - &salt[0], salt.size(), - KDF_ITERATIONS).bits_of()); - pipe.end_msg(); - - return pipe.read_all_as_string(); - } - -bool password_hash_ok(const std::string& pass, const std::string& hash) - { - Pipe pipe(new Base64_Decoder); - pipe.start_msg(); - pipe.write(hash); - pipe.end_msg(); - - SecureVector<byte> hash_bin = pipe.read_all(); - - if(hash_bin.size() != (PBKDF_OUTPUT_LEN + SALT_BYTES)) - return false; - - PKCS5_PBKDF2 kdf(new HMAC(new SHA_160)); - - SecureVector<byte> cmp = kdf.derive_key( - PBKDF_OUTPUT_LEN, pass, - &hash_bin[0], SALT_BYTES, - KDF_ITERATIONS).bits_of(); - - return same_mem(cmp.begin(), hash_bin.begin() + 6, 12); - } diff --git a/doc/log.txt b/doc/log.txt index 652ce7054..2e93cf207 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -6,6 +6,7 @@ - Perform CBC decryption in parallel where possible - Add SQLite3 db encryption codec, contributed by Olivier de Gaalon - Add a block cipher cascade construction + - Add support for password hashing for authentication (passhash.h) - Add support for Win32 high resolution system timers - Changed S2K interface: derive_key now takes salt, iteration count - Fix crash in GMP_Engine if library is shutdown and reinitialized |