mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Use natural BigNum sizes for SRP hash computations
TrinityCore/AzerothCore's UpdateBigNumbers uses BN_num_bytes (natural size without padding) when hashing values for u and M1. Our code was using fixed 32-byte padding which produces different hashes when any value (salt, A, B, N) has leading zeros in big-endian representation.
This commit is contained in:
parent
45fc9996e2
commit
933b50eab5
1 changed files with 25 additions and 21 deletions
|
|
@ -113,12 +113,13 @@ void SRP::computeSessionKey() {
|
|||
LOG_DEBUG("Computing session key");
|
||||
|
||||
// u = H(A | B) - scrambling parameter
|
||||
std::vector<uint8_t> A_bytes = A.toArray(true, 32); // 32 bytes, little-endian
|
||||
std::vector<uint8_t> B_bytes = B.toArray(true, 32); // 32 bytes, little-endian
|
||||
// Use natural BigNum sizes to match TrinityCore's UpdateBigNumbers behavior
|
||||
std::vector<uint8_t> A_bytes_u = A.toArray(true);
|
||||
std::vector<uint8_t> B_bytes_u = B.toArray(true);
|
||||
|
||||
std::vector<uint8_t> AB;
|
||||
AB.insert(AB.end(), A_bytes.begin(), A_bytes.end());
|
||||
AB.insert(AB.end(), B_bytes.begin(), B_bytes.end());
|
||||
AB.insert(AB.end(), A_bytes_u.begin(), A_bytes_u.end());
|
||||
AB.insert(AB.end(), B_bytes_u.begin(), B_bytes_u.end());
|
||||
|
||||
std::vector<uint8_t> u_bytes = Crypto::sha1(AB);
|
||||
u = BigNum(u_bytes, true);
|
||||
|
|
@ -176,8 +177,9 @@ void SRP::computeProofs(const std::string& username) {
|
|||
std::string upperUser = username;
|
||||
std::transform(upperUser.begin(), upperUser.end(), upperUser.begin(), ::toupper);
|
||||
|
||||
// Compute H(N) and H(g)
|
||||
std::vector<uint8_t> N_bytes = N.toArray(true, 32); // 32 bytes (256-bit prime)
|
||||
// Compute H(N) and H(g) using natural BigNum sizes
|
||||
// This matches TrinityCore/AzerothCore's UpdateBigNumbers behavior
|
||||
std::vector<uint8_t> N_bytes = N.toArray(true);
|
||||
std::vector<uint8_t> g_bytes = g.toArray(true);
|
||||
|
||||
std::vector<uint8_t> N_hash = Crypto::sha1(N_bytes);
|
||||
|
|
@ -192,31 +194,33 @@ void SRP::computeProofs(const std::string& username) {
|
|||
// Compute H(username)
|
||||
std::vector<uint8_t> user_hash = Crypto::sha1(upperUser);
|
||||
|
||||
// Get A, B, and salt as byte arrays
|
||||
std::vector<uint8_t> A_bytes = A.toArray(true, 32);
|
||||
std::vector<uint8_t> B_bytes = B.toArray(true, 32);
|
||||
std::vector<uint8_t> s_bytes = s.toArray(true, 32);
|
||||
// Get A, B, and salt as byte arrays — natural sizes for hash inputs
|
||||
std::vector<uint8_t> A_bytes = A.toArray(true);
|
||||
std::vector<uint8_t> B_bytes = B.toArray(true);
|
||||
std::vector<uint8_t> s_bytes = s.toArray(true);
|
||||
|
||||
// M1 = H( H(N)^H(g) | H(I) | s | A | B | K )
|
||||
std::vector<uint8_t> M1_input;
|
||||
M1_input.insert(M1_input.end(), Ng_xor.begin(), Ng_xor.end()); // 20 bytes
|
||||
M1_input.insert(M1_input.end(), user_hash.begin(), user_hash.end()); // 20 bytes
|
||||
M1_input.insert(M1_input.end(), s_bytes.begin(), s_bytes.end()); // 32 bytes
|
||||
M1_input.insert(M1_input.end(), A_bytes.begin(), A_bytes.end()); // 32 bytes
|
||||
M1_input.insert(M1_input.end(), B_bytes.begin(), B_bytes.end()); // 32 bytes
|
||||
M1_input.insert(M1_input.end(), K.begin(), K.end()); // 40 bytes
|
||||
M1_input.insert(M1_input.end(), Ng_xor.begin(), Ng_xor.end());
|
||||
M1_input.insert(M1_input.end(), user_hash.begin(), user_hash.end());
|
||||
M1_input.insert(M1_input.end(), s_bytes.begin(), s_bytes.end());
|
||||
M1_input.insert(M1_input.end(), A_bytes.begin(), A_bytes.end());
|
||||
M1_input.insert(M1_input.end(), B_bytes.begin(), B_bytes.end());
|
||||
M1_input.insert(M1_input.end(), K.begin(), K.end());
|
||||
|
||||
M1 = Crypto::sha1(M1_input); // 20 bytes
|
||||
M1 = Crypto::sha1(M1_input);
|
||||
|
||||
LOG_DEBUG("Client proof M1 calculated (", M1.size(), " bytes)");
|
||||
LOG_DEBUG(" M1 hash input sizes: Ng_xor=20 user=20 s=", s_bytes.size(),
|
||||
" A=", A_bytes.size(), " B=", B_bytes.size(), " K=", K.size());
|
||||
|
||||
// M2 = H( A | M1 | K )
|
||||
std::vector<uint8_t> M2_input;
|
||||
M2_input.insert(M2_input.end(), A_bytes.begin(), A_bytes.end()); // 32 bytes
|
||||
M2_input.insert(M2_input.end(), M1.begin(), M1.end()); // 20 bytes
|
||||
M2_input.insert(M2_input.end(), K.begin(), K.end()); // 40 bytes
|
||||
M2_input.insert(M2_input.end(), A_bytes.begin(), A_bytes.end());
|
||||
M2_input.insert(M2_input.end(), M1.begin(), M1.end());
|
||||
M2_input.insert(M2_input.end(), K.begin(), K.end());
|
||||
|
||||
M2 = Crypto::sha1(M2_input); // 20 bytes
|
||||
M2 = Crypto::sha1(M2_input);
|
||||
|
||||
LOG_DEBUG("Expected server proof M2 calculated (", M2.size(), " bytes)");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue