From ab8102f927e7db5fee19b453206249f446ab9c70 Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Wed, 23 Mar 2016 12:17:59 -0700 Subject: [PATCH] Warn if a low-entropy passphrase is used to create a wallet --- src/ripple/rpc/handlers/WalletPropose.cpp | 49 ++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/ripple/rpc/handlers/WalletPropose.cpp b/src/ripple/rpc/handlers/WalletPropose.cpp index c5e5a50df..a4da5e7eb 100644 --- a/src/ripple/rpc/handlers/WalletPropose.cpp +++ b/src/ripple/rpc/handlers/WalletPropose.cpp @@ -31,9 +31,36 @@ #include #include #include +#include +#include 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 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: // } @@ -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; }