aboutsummaryrefslogtreecommitdiffstats
path: root/doc/examples/passhash.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-02-01 17:28:20 +0000
committerlloyd <[email protected]>2010-02-01 17:28:20 +0000
commit121ca16daa158315682373213e150d9c18c28cdb (patch)
tree3dc90121a407ff31a89aa1d24632447b9993ccaa /doc/examples/passhash.cpp
parent05a9ad7281fb528636534a669db3ba8ae15b1d3b (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/examples/passhash.cpp')
-rw-r--r--doc/examples/passhash.cpp65
1 files changed, 7 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);
- }