I am trying to implement Secure Remote Password (SRP-6a) protocol using iOS client and dot net core server. I am using https://github.com/Bouke/SRP at iOS client side and https://github.com/secure-remote-password/srp.net at dot net server side.
Here is my registration code at ios side.
let n = "ac6bdb41324a9a9bf166de5e1389582faf72b6651987ee07fc3192943db56050a37329cbb4a099ed8193e0757767a13dd52312ab4b03310dcd7f48a9da04fd50e8083969edb767b0cf6095179a163ab3661a05fbd5faaae82918a9962f0b93b855f97993ec975eeaa80d740adbf4ff747359d041d5c33ea71d281e446b14773bca97b43a23fb801676bd207a436c6481f1d2b9078717461a5b9d32e688f87748544523b524b0d57d5ea77a2775d2ecfa032cfbdbf52fb3786160279004e57ae6af874e7303ce53299ccc041c7bc308d82a5698f3a8d0c38271ae35f8e9dbfbb694b5c803d89f7ae435de236d525f54759b65e372fcd68ef20fa7111f9e4aff73";
let g = "02";
let userName = "alice";
let group = Group(prime: n, generator: g)!;
let password = "myPassword";
let regRequest = createSaltedVerificationKey(username: userName, password: password, group: group, algorithm: .sha512);
let salt = String(BigUInt(regRequest.salt), radix: 16, uppercase: false);
let verifier = String(BigUInt(regRequest.verificationKey), radix: 16, uppercase: false);
print("\n Salt: \(salt)\n Verifier: \(verifier)\n")
Server stores userName, slat and verifier.
During user authentication the process is as follows:
Step 1: client sends the username to server and server returns the salt.
Step 2: client generates its public key and send it to server
let client = Client(username: userName, password: password, group: group, algorithm: .sha512);
let (username, clientPublicKey) = client.startAuthentication();
let clientPubKey = String(BigUInt(clientPublicKey), radix: 16, uppercase: false);
print("\n clientPubKey: \(clientPubKey)\n");
Step 3: In response to client public key server shares it's own public key
var customParams = SrpParameters.Create<SHA512>(n, g);
var server = new SrpServer(customParams);
var serverEphemeral = server.GenerateEphemeral(verifier);
Console.WriteLine("Publickey: " + serverEphemeral.Public);
// server stores client public key, userName, and serverEphemeral.Secret
Step 4: Client calculates verifier
let saltString = "salt shared by server at Step 1";
let saltBigInt = BigUInt(saltString, radix: 16)!;
let salt = saltBigInt.serialize();
let serverPubKeyString = "Server public key in Step 3";
let serverPubKeyBigInt = BigUInt(serverPubKeyString, radix: 16)!;
let serverPublicKey = serverPubKeyBigInt.serialize();
do {
let clientKeyProof = try client.processChallenge(salt: salt, publicKey: serverPublicKey);
let clientKeyProofString = String(BigUInt(clientKeyProof), radix: 16, uppercase: false);
print("\n clientKeyProof: \(clientKeyProofString)\n");
} catch {
}
Step 5: client shares clientKeyProofString
with server and server verifies it.
var customParams = SrpParameters.Create<SHA512>(n, g);
var server2 = new SrpServer(customParams);
var serverSession = server2.DeriveSession(serverEphemeralSecret, clientPubKey, salt, userName, verifier, clientKeyProofString);
Console.WriteLine("ServerProof: " + serverSession.Proof);
In this step I am getting System.Security.SecurityException: Client provided session proof is invalid
.
Step 6: Client will verify serverProof
I am not able to proceed to step 6 as the exception on step 5. Any suggestion on what's going wrong here.