Deterministic random password generator

I wrote some C ++ software to generate deterministic random passwords based on user input. Users will provide a sentence and a word, and these lines will be used as input for PBKDF2 . Then the bytes from the PBKDF2 output will be used to randomly select characters for the password.

Here is an example output:

./a.out "ned was here." facebook
Bit_strength: 43.5-bits.
Password_length: 8
uT3=de+D

./a.out "ned was here." "stack overflow"
Bit_strength: 69.5-bits.
Password_length: 12
qO0+Zqp<X<`W

./a.out "ned was here." beer
Bit_strength: 199.3-bits.
Password_length: 32
sV2;MMD|=swA&M`mVk1v{M:3\\<_*<tl 

: . Mersenne Twister ( ) PBKDF2 . . - , , , ? (RNG, , ..), . .

std::string deterministic_password( const std::string& sentence, const std::string& word, boost::uint8_t pass_length )
{
    bool have_lower = false;
    bool have_upper = false;
    bool have_number = false;
    bool have_special = false;
    bool requirements_met = false;

    std::string password;

    if ( pass_length > 64 )
        pass_length = 64;

    // Our character sets
    const std::string lower_chars( "abcdefghijkmnpqrstuvwxyz" );  // no l or o
    const std::string upper_chars( "ABCDEFGHJKLMNPQRSTUVWXYZ" );  // no I or O
    const std::string number_chars( "23456789" );                 // no 1 or 0
    const std::string special_chars( "~!#%^&_[]{}()<>;:,.?" );
    const std::string all_chars( lower_chars + upper_chars + number_chars + special_chars );

    // The maps that we'll pick chars from
    std::map<boost::uint8_t, char> lower_map, upper_map, number_map, special_map, all_map;;

    // Populate the maps
    for ( boost::uint8_t i = 0; i != lower_chars.size(); ++i )
    {
        lower_map[i] = lower_chars[i];
    }

    for ( boost::uint8_t i = 0; i != upper_chars.size(); ++i )
    {
        upper_map[i] = upper_chars[i];
    }

    for ( boost::uint8_t i = 0; i != number_chars.size(); ++i )
    {
        number_map[i] = number_chars[i];
    }

    for ( boost::uint8_t i = 0; i != special_chars.size(); ++i )
    {
        special_map[i] = special_chars[i];
    }

    for ( boost::uint8_t i = 0; i != all_chars.size(); ++i )
    {
        all_map[i] = all_chars[i];
    }

    std::map<boost::uint8_t, char>::const_iterator lower_it   =  lower_map.begin();
    std::map<boost::uint8_t, char>::const_iterator upper_it   =  upper_map.begin();
    std::map<boost::uint8_t, char>::const_iterator number_it  =  number_map.begin();
    std::map<boost::uint8_t, char>::const_iterator special_it =  special_map.begin();
    std::map<boost::uint8_t, char>::const_iterator all_it     =  all_map.begin();

    char seed_bits[512];

    CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf;
    pbkdf.DeriveKey(
             // buffer that holds the derived key 
             (byte *)seed_bits,
             // Length of derived key in bytes
             512,
             // purpose byte. unused by this PBKDF implementation. 
             0,
             // sentence bytes (User provided) 
             (const byte *)sentence.data(),
             sentence.size(),
             // word bytes (User provided. This is salt)
             (const byte *)word.data(),
             word.size(),
             // iteration count
             32768,
             0 );

    double bit_strength = 0; 

    for( boost::uint16_t i = 0; i != 512; ++i )
    {
        if ( have_lower and have_upper and have_number and have_special )
        {
            requirements_met = true;
        }

        if ( requirements_met and (password.size() == pass_length) )
        {
            break;
        }

        boost::uint8_t number = seed_bits[i];

        lower_it = lower_map.find(number);
        upper_it = upper_map.find(number);
        number_it = number_map.find(number);
        special_it = special_map.find(number);
        all_it = all_map.find(number);

        if ( lower_it != lower_map.end() and !have_lower )
        {
            //std::cout << (boost::uint16_t)lower_it->first << " " << lower_it->second << "\n";
            password.push_back(lower_it->second);
            have_lower = true;
            bit_strength += log(lower_map.size())/log(2);
            continue;
        }

        if ( upper_it != upper_map.end() and !have_upper )
        {
            //std::cout << (boost::uint16_t)upper_it->first << " " << upper_it->second << "\n";
            password.push_back(upper_it->second);
            have_upper = true;
            bit_strength += log(upper_map.size())/log(2);
            continue;
        }

        if ( number_it != number_map.end() and !have_number )
        {
            //std::cout << (boost::uint16_t)number_it->first << " " << number_it->second << "\n";
            password.push_back(number_it->second);
            have_number = true;
            bit_strength += log(number_map.size())/log(2);
            continue;
        }

        if ( special_it != special_map.end() and !have_special )
        {
            //std::cout << (boost::uint16_t)special_it->first << " " << special_it->second << "\n";
            password.push_back(special_it->second);
            have_special = true;
            bit_strength += log(special_map.size())/log(2);
            continue;
        }

        if ( all_it != all_map.end() and requirements_met and (password.size() != pass_length) )
        {
            //std::cout << (boost::uint16_t)all_it->first << " " << all_it->second << "\n";
            password.push_back(all_it->second);
            bit_strength += log(all_map.size())/log(2);
            continue;
        }
    }

    std::cout.precision(1);
    std::cout.imbue(std::locale(""));
    std::cout << std::fixed << "Bit_strength: " << bit_strength << "-bits." << "\n";
    std::cout << "Password_length: " << password.size() << "\n";
    std::cout << password << "\n";
    std::cout << "\n";

    return password;
}
+3
1

- mersenne twister rng .

, random_device, , . uniform__int_disribution, , , "". rng - , pbkdf2 . , unifrom_int_distribution.

pbkdf2. , . , , , . 256 , 92 . 256-92 * 2 72. , 72 . , , , , .

, pbkdf2 . pbkdf2 160 . , uint8, ( , 8) . , pbkdf2 , raw , , 0 2 ^ 8-1, .

Mersenne Twister . PBKDF2 PRNG. , - , , . , , , .

Mersenne Twister

wikipedia :

Thee ( Blum Blum Shub). (624 MT19937, , )

, , ,

crypboost:: random:: uniform_int_distribution , /?, , , , , , . , , - , rng , , matlab mathematica, -, . , , , .

, PBKDF2 (.. ). , , 0, 1 . 0, 2 ^ 64 -1.

, ( , ).

, , , . ,

+1

All Articles