Warn if a low-entropy passphrase is used to create a wallet

This commit is contained in:
Nik Bougalis
2016-03-23 12:17:59 -07:00
parent fa02409c92
commit ab8102f927

View File

@@ -31,9 +31,36 @@
#include <ripple/rpc/handlers/WalletPropose.h>
#include <ed25519-donna/ed25519.h>
#include <boost/optional.hpp>
#include <cmath>
#include <map>
namespace ripple {
double
estimate_entropy (std::string const& input)
{
// First, we calculate the Shannon entropy. This gives
// the average number of bits per symbol that we would
// need to encode the input.
std::map<int, double> freq;
for (auto const& c : input)
freq[c]++;
double se = 0.0;
for (auto const& f : freq)
{
auto x = f.second / input.length();
se += (x) * log2(x);
}
// We multiply it by the length, to get an estimate of
// the number of bits in the input. We floor because it
// is better to be conservative.
return std::floor (-se * input.length());
}
// {
// passphrase: <string>
// }
@@ -56,7 +83,8 @@ Json::Value walletPropose (Json::Value const& params)
if (keyType == KeyType::invalid)
return rpcError(rpcINVALID_PARAMS);
if (params.isMember (jss::passphrase) || params.isMember (jss::seed) ||
if (params.isMember (jss::passphrase) ||
params.isMember (jss::seed) ||
params.isMember (jss::seed_hex))
{
seed = RPC::getSeedFromRPC (params);
@@ -91,6 +119,25 @@ Json::Value walletPropose (Json::Value const& params)
obj[jss::key_type] = to_string (keyType);
obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size());
if (params.isMember (jss::passphrase))
{
auto const entropy = estimate_entropy (
params[jss::passphrase].asString());
// 80 bits of entropy isn't bad, but it's better to
// err on the side of caution and be conservative.
if (entropy < 80.0)
obj[jss::warning] =
"This wallet was generated using a user-supplied "
"passphrase that has low entropy and is vulnerable "
"to brute-force attacks.";
else
obj[jss::warning] =
"This wallet was generated using a user-supplied "
"passphrase. It may be vulnerable to brute-force "
"attacks.";
}
return obj;
}