ESP32: новая derivation ключей

This commit is contained in:
AidarKC 2026-06-23 10:51:03 +04:00
parent b461431197
commit 2f65e63fbe
3 changed files with 43 additions and 26 deletions

View File

@ -392,6 +392,8 @@ struct DerivedKeyInfo {
static String gRootPubB58; static String gRootPubB58;
static String gRootPrivB58; static String gRootPrivB58;
static String gRecoveryPubB58;
static String gRecoveryPrivB58;
static String gBlockchainPubB58; static String gBlockchainPubB58;
static String gBlockchainPrivB58; static String gBlockchainPrivB58;
static String gDevicePubB58; static String gDevicePubB58;
@ -1206,10 +1208,17 @@ static void deriveKeyPairFromSecretSuffix(const uint8_t *secret32, const String
if (!secret32) { if (!secret32) {
return; return;
} }
String material = base64Std(secret32, 32) + "|" + suffix; const char *prefix = "SHiNE-key";
uint8_t seed[32] = {}; uint8_t seed[32] = {};
uint8_t pub[32] = {}; uint8_t pub[32] = {};
sha256calc(reinterpret_cast<const uint8_t *>(material.c_str()), material.length(), seed); std::vector<uint8_t> material;
material.reserve(10 + 1 + 32 + 1 + suffix.length());
material.insert(material.end(), prefix, prefix + strlen(prefix));
material.push_back(0);
material.insert(material.end(), secret32, secret32 + 32);
material.push_back(0);
material.insert(material.end(), suffix.c_str(), suffix.c_str() + suffix.length());
sha256calc(material.data(), material.size(), seed);
Ed25519::derivePublicKey(pub, seed); Ed25519::derivePublicKey(pub, seed);
privB58 = base58From32(seed); privB58 = base58From32(seed);
pubB58 = base58From32(pub); pubB58 = base58From32(pub);
@ -1218,6 +1227,8 @@ static void deriveKeyPairFromSecretSuffix(const uint8_t *secret32, const String
static void clearDerivedKeys() { static void clearDerivedKeys() {
gRootPubB58 = ""; gRootPubB58 = "";
gRootPrivB58 = ""; gRootPrivB58 = "";
gRecoveryPubB58 = "";
gRecoveryPrivB58 = "";
gBlockchainPubB58 = ""; gBlockchainPubB58 = "";
gBlockchainPrivB58 = ""; gBlockchainPrivB58 = "";
gDevicePubB58 = ""; gDevicePubB58 = "";
@ -1233,6 +1244,7 @@ static void refreshDerivedKeys() {
if (!gSecretConfigured) { if (!gSecretConfigured) {
return; return;
} }
deriveKeyPairFromSecretSuffix(gSecretBytes, "recovery.key", gRecoveryPubB58, gRecoveryPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "root.key", gRootPubB58, gRootPrivB58); deriveKeyPairFromSecretSuffix(gSecretBytes, "root.key", gRootPubB58, gRootPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "blockchain.key", gBlockchainPubB58, gBlockchainPrivB58); deriveKeyPairFromSecretSuffix(gSecretBytes, "blockchain.key", gBlockchainPubB58, gBlockchainPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "client.key", gDevicePubB58, gDevicePrivB58); deriveKeyPairFromSecretSuffix(gSecretBytes, "client.key", gDevicePubB58, gDevicePrivB58);
@ -6297,14 +6309,16 @@ static void drawSecretShowScreen() {
}; };
addKeyBlock("Secret (base58)", "master secret", gSecretBase58); addKeyBlock("Secret (base58)", "master secret", gSecretBase58);
addKeyBlock("Root key (base58)", "pub from sha256(base64(secret)|root.key)", gRootPubB58); addKeyBlock("Recovery key (base58)", "pub from SHA-256(SHiNE-key||secret||recovery.key)", gRecoveryPubB58);
addKeyBlock("Root key priv (base58)", "sha256(base64(secret)|root.key)", gRootPrivB58); addKeyBlock("Recovery key priv (base58)", "SHA-256(SHiNE-key||secret||recovery.key)", gRecoveryPrivB58);
addKeyBlock("Blockchain key (base58)", "pub from sha256(base64(secret)|bch.key)", gBlockchainPubB58); addKeyBlock("Root key (base58)", "pub from SHA-256(SHiNE-key||secret||root.key)", gRootPubB58);
addKeyBlock("Blockchain key priv (base58)", "sha256(base64(secret)|bch.key)", gBlockchainPrivB58); addKeyBlock("Root key priv (base58)", "SHA-256(SHiNE-key||secret||root.key)", gRootPrivB58);
addKeyBlock("Client key (base58)", "pub from sha256(base64(secret)|client.key)", gDevicePubB58); addKeyBlock("Blockchain key (base58)", "pub from SHA-256(SHiNE-key||secret||blockchain.key)", gBlockchainPubB58);
addKeyBlock("Client key priv (base58)", "sha256(base64(secret)|client.key)", gDevicePrivB58); addKeyBlock("Blockchain key priv (base58)", "SHA-256(SHiNE-key||secret||blockchain.key)", gBlockchainPrivB58);
addKeyBlock("Homeserver key (base58)", String("pub from sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPubB58); addKeyBlock("Client key (base58)", "pub from SHA-256(SHiNE-key||secret||client.key)", gDevicePubB58);
addKeyBlock("Homeserver key priv (base58)", String("sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPrivB58); addKeyBlock("Client key priv (base58)", "SHA-256(SHiNE-key||secret||client.key)", gDevicePrivB58);
addKeyBlock("Homeserver key (base58)", String("pub from SHA-256(SHiNE-key||secret||") + homeserverKeySuffix() + ")", gHomeserverPubB58);
addKeyBlock("Homeserver key priv (base58)", String("SHA-256(SHiNE-key||secret||") + homeserverKeySuffix() + ")", gHomeserverPrivB58);
} else { } else {
showMessageAt("Secret not set", 96); showMessageAt("Secret not set", 96);
} }

View File

@ -224,12 +224,14 @@ static int16_t gTouchLastY = 0;
struct DerivedKeyState { struct DerivedKeyState {
bool ready; bool ready;
uint8_t masterSecret[32]; uint8_t masterSecret[32];
uint8_t recoveryPub[32];
uint8_t recoverySk[64];
uint8_t rootPub[32]; uint8_t rootPub[32];
uint8_t rootSk[64]; uint8_t rootSk[64];
uint8_t blockchainPub[32]; uint8_t blockchainPub[32];
uint8_t blockchainSk[64]; uint8_t blockchainSk[64];
uint8_t clientPub[32]; uint8_t clientPub[32];
uint8_t deviceSk[64]; uint8_t clientSk[64];
}; };
static DerivedKeyState gDerivedKeys = {}; static DerivedKeyState gDerivedKeys = {};
@ -782,19 +784,20 @@ static void pushFixed(std::vector<uint8_t> &out, const uint8_t *data, size_t len
static bool deriveKeysFromMasterSecret(const uint8_t masterSecret[32]) { static bool deriveKeysFromMasterSecret(const uint8_t masterSecret[32]) {
memset(&gDerivedKeys, 0, sizeof(gDerivedKeys)); memset(&gDerivedKeys, 0, sizeof(gDerivedKeys));
memcpy(gDerivedKeys.masterSecret, masterSecret, 32); memcpy(gDerivedKeys.masterSecret, masterSecret, 32);
String secretB64 = base64Encode(masterSecret, 32); const char *prefix = "SHiNE-key";
if (secretB64.length() == 0) { const char *suffixes[4] = {"recovery.key", "root.key", "blockchain.key", "client.key"};
return false; uint8_t *pubs[4] = {gDerivedKeys.recoveryPub, gDerivedKeys.rootPub, gDerivedKeys.blockchainPub, gDerivedKeys.clientPub};
} uint8_t *sks[4] = {gDerivedKeys.recoverySk, gDerivedKeys.rootSk, gDerivedKeys.blockchainSk, gDerivedKeys.clientSk};
const char *suffixes[3] = {"root.key", "blockchain.key", "client.key"}; for (int i = 0; i < 4; i++) {
uint8_t *pubs[3] = {gDerivedKeys.rootPub, gDerivedKeys.blockchainPub, gDerivedKeys.clientPub}; std::vector<uint8_t> material;
uint8_t *sks[3] = {gDerivedKeys.rootSk, gDerivedKeys.blockchainSk, gDerivedKeys.deviceSk}; material.reserve(strlen(prefix) + 1 + 32 + 1 + strlen(suffixes[i]));
for (int i = 0; i < 3; i++) { material.insert(material.end(), prefix, prefix + strlen(prefix));
String material = secretB64 + "|" + suffixes[i]; material.push_back(0);
material.insert(material.end(), masterSecret, masterSecret + 32);
material.push_back(0);
material.insert(material.end(), suffixes[i], suffixes[i] + strlen(suffixes[i]));
uint8_t seed[32]; uint8_t seed[32];
if (!sha256String(material, seed)) { sha256Raw(material.data(), material.size(), seed);
return false;
}
if (crypto_sign_seed_keypair(pubs[i], sks[i], seed) != 0) { if (crypto_sign_seed_keypair(pubs[i], sks[i], seed) != 0) {
return false; return false;
} }
@ -1277,7 +1280,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
edBchData, edBchData,
createData); createData);
uint8_t txSignature[64]; uint8_t txSignature[64];
if (!signMessageEd25519(message, gDerivedKeys.deviceSk, txSignature)) { if (!signMessageEd25519(message, gDerivedKeys.clientSk, txSignature)) {
messageOut = "Не удалось подписать Solana-транзакцию"; messageOut = "Не удалось подписать Solana-транзакцию";
return false; return false;
} }

View File

@ -1,2 +1,2 @@
client.version=1.2.234 client.version=1.2.235
server.version=1.2.220 server.version=1.2.221