Skip to content

Commit 1626946

Browse files
fix(aes): Update StoredKey to generate new AES and Scrypt parameters for encoded private key
1 parent 65a1276 commit 1626946

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/Keystore/StoredKey.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,16 @@ StoredKey::StoredKey(StoredKeyType type, std::string name, const Data& password,
9898
const auto cipherParams = AESParameters::AESParametersFromEncryption(encryption);
9999
const auto scryptParams = ScryptParameters::getPreset(encryptionLevel);
100100
payload = EncryptedPayload(password, data, cipherParams, scryptParams);
101+
101102
if (encodedStr) {
102103
const auto bytes = reinterpret_cast<const uint8_t*>(encodedStr->c_str());
103104
const auto encodedData = Data(bytes, bytes + encodedStr->size());
104-
encodedPayload = EncryptedPayload(password, encodedData, cipherParams, scryptParams);
105+
106+
// Generate new parameters with random iv and salt for the encoded private key.
107+
const auto cipherParamsEncoded = AESParameters::AESParametersFromEncryption(encryption);
108+
const auto scryptParamsEncoded = ScryptParameters::getPreset(encryptionLevel);
109+
110+
encodedPayload = EncryptedPayload(password, encodedData, cipherParamsEncoded, scryptParamsEncoded);
105111
}
106112
const char* uuid_ptr = Rust::tw_uuid_random();
107113
id = std::make_optional<std::string>(uuid_ptr);

tests/common/Keystore/StoredKeyTests.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,50 @@ TEST(StoredKey, CreateMultiAccounts) { // Multiple accounts from the same wallet
764764
}
765765
}
766766

767+
TEST(StoredKey, CreateWithEncodedPrivateKeyAddDefaultAddress) {
768+
// Use a hex-encoded private key
769+
const auto privateKeyHex = "3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266";
770+
auto key = StoredKey::createWithEncodedPrivateKeyAddDefaultAddress("name", gPassword, coinTypeBc, privateKeyHex);
771+
772+
EXPECT_EQ(key.type, StoredKeyType::privateKey);
773+
EXPECT_EQ(key.accounts.size(), 1ul);
774+
EXPECT_EQ(key.accounts[0].coin, coinTypeBc);
775+
EXPECT_EQ(key.accounts[0].address, "bc1q375sq4kl2nv0mlmup3vm8znn4eqwu7mt6hkwhr");
776+
777+
// Verify that the raw private key bytes can be decrypted from `payload`
778+
const Data& decryptedKey = key.payload.decrypt(gPassword);
779+
EXPECT_EQ(hex(decryptedKey), privateKeyHex);
780+
781+
// Verify that the encoded private key string can be decrypted from `encodedPayload`
782+
ASSERT_TRUE(key.encodedPayload.has_value());
783+
const Data& decryptedEncoded = key.encodedPayload->decrypt(gPassword);
784+
EXPECT_EQ(string(decryptedEncoded.begin(), decryptedEncoded.end()), privateKeyHex);
785+
786+
// Validate the JSON structure
787+
const auto json = key.json();
788+
EXPECT_EQ(json["name"], "name");
789+
EXPECT_EQ(json["type"], "private-key");
790+
EXPECT_EQ(json["version"], 3);
791+
EXPECT_TRUE(json.count("encodedCrypto") != 0);
792+
793+
// Retrieve iv and salt from `crypto` (payload) and `encodedCrypto` (encodedPayload)
794+
const auto payloadIv = json["crypto"]["cipherparams"]["iv"].get<std::string>();
795+
const auto payloadSalt = json["crypto"]["kdfparams"]["salt"].get<std::string>();
796+
797+
const auto encodedIv = json["encodedCrypto"]["cipherparams"]["iv"].get<std::string>();
798+
const auto encodedSalt = json["encodedCrypto"]["kdfparams"]["salt"].get<std::string>();
799+
800+
// iv and salt must be non-empty hex strings
801+
EXPECT_EQ(payloadIv.size(), 32ul); // 16 bytes as hex
802+
EXPECT_EQ(payloadSalt.size(), 64ul); // 32 bytes as hex
803+
EXPECT_EQ(encodedIv.size(), 32ul);
804+
EXPECT_EQ(encodedSalt.size(), 64ul);
805+
806+
// iv and salt must differ between `payload` and `encodedPayload`
807+
EXPECT_NE(payloadIv, encodedIv);
808+
EXPECT_NE(payloadSalt, encodedSalt);
809+
}
810+
767811
TEST(StoredKey, CreateWithMnemonicAlternativeDerivation) {
768812
const auto coin = TWCoinTypeSolana;
769813
auto key = StoredKey::createWithMnemonicAddDefaultAddress("name", gPassword, gMnemonic, coin);

0 commit comments

Comments
 (0)