mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Display warning when generating brain wallets:
A brain wallet is a standard wallet that is generated not from a random seed but by hashing a user-supplied passphrase. Typically, human-selected passphrases can contain insufficient entropy. When generating a wallet from a passphrase, we include a warning to this effect. The warning would be incorrectly displayed even if the wallet was being generated from a seed.
This commit is contained in:
@@ -108,31 +108,42 @@ Json::Value walletPropose (Json::Value const& params)
|
||||
|
||||
Json::Value obj (Json::objectValue);
|
||||
|
||||
obj[jss::master_seed] = toBase58 (*seed);
|
||||
obj[jss::master_seed_hex] = strHex (seed->data(), seed->size());
|
||||
obj[jss::master_key] = seedAs1751 (*seed);
|
||||
auto const seed1751 = seedAs1751 (*seed);
|
||||
auto const seedHex = strHex (seed->data(), seed->size());
|
||||
auto const seedBase58 = toBase58 (*seed);
|
||||
|
||||
obj[jss::master_seed] = seedBase58;
|
||||
obj[jss::master_seed_hex] = seedHex;
|
||||
obj[jss::master_key] = seed1751;
|
||||
obj[jss::account_id] = toBase58(calcAccountID(publicKey));
|
||||
obj[jss::public_key] = toBase58(TOKEN_ACCOUNT_PUBLIC, publicKey);
|
||||
obj[jss::key_type] = to_string (keyType);
|
||||
obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size());
|
||||
|
||||
// If a passphrase was specified, and it was hashed and used as a seed
|
||||
// run a quick entropy check and add an appropriate warning, because
|
||||
// "brain wallets" can be easily attacked.
|
||||
if (params.isMember (jss::passphrase))
|
||||
{
|
||||
auto const entropy = estimate_entropy (
|
||||
params[jss::passphrase].asString());
|
||||
auto const passphrase = 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.";
|
||||
if (passphrase != seed1751 &&
|
||||
passphrase != seedBase58 &&
|
||||
passphrase != seedHex)
|
||||
{
|
||||
// 80 bits of entropy isn't bad, but it's better to
|
||||
// err on the side of caution and be conservative.
|
||||
if (estimate_entropy (passphrase) < 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;
|
||||
|
||||
@@ -40,6 +40,8 @@ struct key_strings
|
||||
char const* public_key;
|
||||
char const* public_key_hex;
|
||||
char const* secret_key_hex;
|
||||
char const* passphrase;
|
||||
char const* passphrase_warning;
|
||||
};
|
||||
|
||||
namespace common {
|
||||
@@ -58,6 +60,10 @@ static key_strings const secp256k1_strings =
|
||||
"aBQxK2YFNqzmAaXNczYcjqDjfiKkLsJUizsr1UBf44RCF8FHdrmX",
|
||||
"038AAE247B2344B1837FBED8F57389C8C11774510A3F7D784F2A09F0CB6843236C",
|
||||
"1949ECD889EA71324BC7A30C8E81F4E93CB73EE19D59E9082111E78CC3DDABC2",
|
||||
common::passphrase,
|
||||
"This wallet was generated using a user-supplied "
|
||||
"passphrase that has low entropy and is vulnerable "
|
||||
"to brute-force attacks.",
|
||||
};
|
||||
|
||||
static key_strings const ed25519_strings =
|
||||
@@ -69,6 +75,25 @@ static key_strings const ed25519_strings =
|
||||
"aKEQmgLMyZPMruJFejUuedp169LgW6DbJt1rej1DJ5hWUMH4pHJ7",
|
||||
"ED54C3F5BEDA8BD588B203D23A27398FAD9D20F88A974007D6994659CD7273FE1D",
|
||||
"77AAED2698D56D6676323629160F4EEF21CFD9EE3D0745CC78FA291461F98278",
|
||||
common::passphrase,
|
||||
"This wallet was generated using a user-supplied "
|
||||
"passphrase that has low entropy and is vulnerable "
|
||||
"to brute-force attacks.",
|
||||
};
|
||||
|
||||
static key_strings const strong_brain_strings =
|
||||
{
|
||||
"rBcvXmNb7KPkNdMkpckdWPpbvkWgcV3nir",
|
||||
"TED AVON CAVE HOUR BRAG JEFF RIFT NEAL TOLD FAT SEW SAN",
|
||||
"shKdhWka8hS7Es3bpctCZXBiAwfUN",
|
||||
"74BA8389B44F98CF41E795CD91F9C93F",
|
||||
"aBRL2sqVuzrsM6zikPB4v8UBHGn1aKkrsxhYEffhcQxB2LKyywE5",
|
||||
"03BD334FB9E06C58D69603E9922686528B18A754BC2F2E1ADA095FFE67DE952C64",
|
||||
"84262FB16AA25BE407174C7EDAB531220C30FA4D8A28AA9D564673FB3D34502C",
|
||||
"A4yKIRGdzrw0YQ$2%TFKYG9HP*&ok^!sy7E@RwICs",
|
||||
"This wallet was generated using a user-supplied "
|
||||
"passphrase. It may be vulnerable to brute-force "
|
||||
"attacks.",
|
||||
};
|
||||
|
||||
class WalletPropose_test : public ripple::TestSuite
|
||||
@@ -93,6 +118,7 @@ public:
|
||||
expectEquals (result[jss::key_type],
|
||||
params.isMember (jss::key_type) ? params[jss::key_type]
|
||||
: "secp256k1");
|
||||
BEAST_EXPECT(!result.isMember(jss::warning));
|
||||
|
||||
std::string seed = result[jss::master_seed].asString();
|
||||
|
||||
@@ -102,7 +128,7 @@ public:
|
||||
BEAST_EXPECT(result[jss::master_seed].asString() != seed);
|
||||
}
|
||||
|
||||
void testSecretWallet (Json::Value const& params, key_strings const& s)
|
||||
Json::Value testSecretWallet (Json::Value const& params, key_strings const& s)
|
||||
{
|
||||
Json::Value result = walletPropose (params);
|
||||
|
||||
@@ -116,6 +142,7 @@ public:
|
||||
expectEquals (result[jss::key_type],
|
||||
params.isMember (jss::key_type) ? params[jss::key_type]
|
||||
: "secp256k1");
|
||||
return result;
|
||||
}
|
||||
|
||||
void testSeed (boost::optional<std::string> const& keyType,
|
||||
@@ -128,7 +155,8 @@ public:
|
||||
params[jss::key_type] = *keyType;
|
||||
params[jss::seed] = strings.master_seed;
|
||||
|
||||
testSecretWallet (params, strings);
|
||||
auto const wallet = testSecretWallet (params, strings);
|
||||
BEAST_EXPECT(!wallet.isMember(jss::warning));
|
||||
}
|
||||
|
||||
void testSeedHex (boost::optional<std::string> const& keyType,
|
||||
@@ -141,7 +169,8 @@ public:
|
||||
params[jss::key_type] = *keyType;
|
||||
params[jss::seed_hex] = strings.master_seed_hex;
|
||||
|
||||
testSecretWallet (params, strings);
|
||||
auto const wallet = testSecretWallet (params, strings);
|
||||
BEAST_EXPECT(!wallet.isMember(jss::warning));
|
||||
}
|
||||
|
||||
void testLegacyPassphrase (char const* value,
|
||||
@@ -153,7 +182,11 @@ public:
|
||||
params[jss::key_type] = *keyType;
|
||||
params[jss::passphrase] = value;
|
||||
|
||||
testSecretWallet (params, strings);
|
||||
auto const wallet = testSecretWallet (params, strings);
|
||||
if (value == strings.passphrase)
|
||||
BEAST_EXPECT(wallet[jss::warning] == strings.passphrase_warning);
|
||||
else
|
||||
BEAST_EXPECT(!wallet.isMember(jss::warning));
|
||||
}
|
||||
|
||||
void testLegacyPassphrase(boost::optional<std::string> const& keyType,
|
||||
@@ -161,7 +194,7 @@ public:
|
||||
{
|
||||
testcase ("passphrase");
|
||||
|
||||
testLegacyPassphrase (common::passphrase, keyType, strings);
|
||||
testLegacyPassphrase (strings.passphrase, keyType, strings);
|
||||
testLegacyPassphrase (strings.master_key, keyType, strings);
|
||||
testLegacyPassphrase (strings.master_seed, keyType, strings);
|
||||
testLegacyPassphrase (strings.master_seed_hex, keyType, strings);
|
||||
@@ -682,11 +715,13 @@ public:
|
||||
testKeyType (boost::none, secp256k1_strings);
|
||||
testKeyType (std::string("secp256k1"), secp256k1_strings);
|
||||
testKeyType (std::string("ed25519"), ed25519_strings);
|
||||
testKeyType (std::string("secp256k1"), strong_brain_strings);
|
||||
testBadInput ();
|
||||
|
||||
testKeypairForSignature (boost::none, secp256k1_strings);
|
||||
testKeypairForSignature (std::string("secp256k1"), secp256k1_strings);
|
||||
testKeypairForSignature (std::string("ed25519"), ed25519_strings);
|
||||
testKeypairForSignature (std::string("secp256k1"), strong_brain_strings);
|
||||
testKeypairForSignatureErrors ();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user