From 430a21306389ae98719a701ca3bfd74328ee699d Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 5 Feb 2026 12:46:53 -0800 Subject: [PATCH] Fix SRP authentication producing wrong proofs Two bugs that caused the server to always reject our login proof: - N was hashed as 256 bytes (2048 bits) instead of 32 bytes (256 bits), producing completely wrong H(N)^H(g) and therefore wrong M1 - Session key computation B-k*g^x could go negative; OpenSSL's BN_mod_exp doesn't handle negative bases. Add k*N before subtracting (standard TrinityCore approach) to keep the value positive --- src/auth/srp.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/auth/srp.cpp b/src/auth/srp.cpp index 754dc235..c7cc6756 100644 --- a/src/auth/srp.cpp +++ b/src/auth/srp.cpp @@ -127,21 +127,20 @@ void SRP::computeSessionKey() { // Compute session key: S = (B - kg^x)^(a + ux) mod N - // Step 1: kg^x + // Step 1: kg^x mod N BigNum gx = g.modPow(x, N); BigNum kgx = k.multiply(gx); - // Step 2: B - kg^x - BigNum B_minus_kgx = B.subtract(kgx); + // Step 2: B - kg^x (add k*N first to prevent negative result) + BigNum kN = k.multiply(N); + BigNum diff = B.add(kN).subtract(kgx); - // Step 3: ux + // Step 3: a + ux BigNum ux = u.multiply(x); - - // Step 4: a + ux BigNum aux = a.add(ux); - // Step 5: (B - kg^x)^(a + ux) mod N - S = B_minus_kgx.modPow(aux, N); + // Step 4: (B + kN - kg^x)^(a + ux) mod N + S = diff.modPow(aux, N); LOG_DEBUG("Session key S calculated"); @@ -178,7 +177,7 @@ void SRP::computeProofs(const std::string& username) { std::transform(upperUser.begin(), upperUser.end(), upperUser.begin(), ::toupper); // Compute H(N) and H(g) - std::vector N_bytes = N.toArray(true, 256); // Full 256 bytes + std::vector N_bytes = N.toArray(true, 32); // 32 bytes (256-bit prime) std::vector g_bytes = g.toArray(true); std::vector N_hash = Crypto::sha1(N_bytes);