private void testServerCatchesBadA(BigInteger N, BigInteger g) { byte[] I = Encoding.UTF8.GetBytes("username"); byte[] P = Encoding.UTF8.GetBytes("password"); byte[] s = new byte[16]; random.NextBytes(s); Srp6VerifierGenerator gen = new Srp6VerifierGenerator(); gen.Init(N, g, new Sha256Digest()); BigInteger v = gen.GenerateVerifier(s, I, P); Srp6Server server = new Srp6Server(); server.Init(N, g, v, new Sha256Digest(), random); server.GenerateServerCredentials(); try { server.CalculateSecret(BigInteger.Zero); Fail("Client failed to detect invalid value for 'A'"); } catch (CryptoException) { // Expected } try { server.CalculateSecret(N); Fail("Client failed to detect invalid value for 'A'"); } catch (CryptoException) { // Expected } }
private bool StandardAuthentication(IDigest hash, Stream stream, byte[] additionalChallenge) { // Authenticate (If mode = 1) // C <= S // byte PasswordHashMethod // byte SaltLength // byte[] Salt // int Iterations // byte SrpHashMethod // int Bit Strength // byte[] Public B (Size equal to SRP Length) // C => S // byte[] Public A (Size equal to SRP Length) // byte[] Client Proof: H(Public A | Public B | SessionKey) // C <= S // Bool Success (if false, done) // byte[] Server Proof: H(Public B | Public A | SessionKey) int srpNumberLength = ((int)m_user.SrpStrength) >> 3; stream.WriteByte((byte)PasswordHashMethod); stream.WriteByte((byte)m_user.Salt.Length); stream.Write(m_user.Salt); stream.Write(m_user.Iterations); stream.WriteByte((byte)SrpHashMethod); stream.Write((int)m_user.SrpStrength); stream.Flush(); //since computing B takes a long time. Go ahead and flush var param = SrpConstants.Lookup(m_user.SrpStrength); Srp6Server server = new Srp6Server(param, m_user.VerificationInteger); BigInteger pubB = server.GenerateServerCredentials(); byte[] pubBBytes = pubB.ToPaddedArray(srpNumberLength); stream.Write(pubBBytes); stream.Flush(); //Read from client: A byte[] pubABytes = stream.ReadBytes(srpNumberLength); BigInteger pubA = new BigInteger(1, pubABytes); //Calculate Session Key BigInteger S = server.CalculateSecret(hash, pubA); byte[] SBytes = S.ToPaddedArray(srpNumberLength); byte[] clientProofCheck = hash.ComputeHash(pubABytes, pubBBytes, SBytes, additionalChallenge); byte[] serverProof = hash.ComputeHash(pubBBytes, pubABytes, SBytes, additionalChallenge); byte[] clientProof = stream.ReadBytes(hash.GetDigestSize()); if (clientProof.SecureEquals(clientProofCheck)) { stream.Write(true); stream.Write(serverProof); stream.Flush(); byte[] K = hash.ComputeHash(pubABytes, SBytes, pubBBytes).Combine(hash.ComputeHash(pubBBytes, SBytes, pubABytes)); byte[] ticket = CreateSessionData(K, m_user); SessionSecret = K; stream.Write((short)ticket.Length); stream.Write(ticket); stream.Flush(); return true; } stream.Write(false); stream.Flush(); return false; }
private void testMutualVerification(BigInteger N, BigInteger g) { byte[] I = Encoding.UTF8.GetBytes("username"); byte[] P = Encoding.UTF8.GetBytes("password"); byte[] s = new byte[16]; random.NextBytes(s); Srp6VerifierGenerator gen = new Srp6VerifierGenerator(); gen.Init(N, g, new Sha256Digest()); BigInteger v = gen.GenerateVerifier(s, I, P); Srp6Client client = new Srp6Client(); client.Init(N, g, new Sha256Digest(), random); Srp6Server server = new Srp6Server(); server.Init(N, g, v, new Sha256Digest(), random); BigInteger A = client.GenerateClientCredentials(s, I, P); BigInteger B = server.GenerateServerCredentials(); BigInteger clientS = client.CalculateSecret(B); BigInteger serverS = server.CalculateSecret(A); if (!clientS.Equals(serverS)) { Fail("SRP agreement failed - client/server calculated different secrets"); } }