Beispiel #1
0
        /// <summary>
        /// Verifies the session using the server-provided session proof.
        /// </summary>
        /// <param name="clientPublicEphemeral">The client public ephemeral.</param>
        /// <param name="clientSession">The client session.</param>
        /// <param name="serverSessionProof">The server session proof.</param>
        public void VerifySession(string clientPublicEphemeral, SrpSession clientSession, string serverSessionProof)
        {
            // H — One-way hash function
            var H = Parameters.Hash;

            // A — Public ephemeral values
            // M — Proof of K
            // K — Shared, strong session key
            var A = SrpInteger.FromHex(clientPublicEphemeral);
            var M = SrpInteger.FromHex(clientSession.Proof);
            var K = SrpInteger.FromHex(clientSession.Key);

            // H(A, M, K)
            var expected = H(A, M, K);
            var actual   = SrpInteger.FromHex(serverSessionProof);

            if (actual != expected)
            {
                // fixme: .code, .statusCode, etc.
                throw new SecurityException("Server provided session proof is invalid");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Generates the random salt of the same size as a used hash.
        /// </summary>
        public string GenerateSalt()
        {
            var hashSize = Parameters.HashSizeBytes;

            return(SrpInteger.RandomInteger(hashSize).ToHex());
        }
Beispiel #3
0
        /// <summary>
        /// Derives the server session.
        /// </summary>
        /// <param name="serverSecretEphemeral">The server secret ephemeral.</param>
        /// <param name="clientPublicEphemeral">The client public ephemeral.</param>
        /// <param name="salt">The salt.</param>
        /// <param name="username">The username.</param>
        /// <param name="verifier">The verifier.</param>
        /// <param name="clientSessionProof">The client session proof value.</param>
        /// <returns>Session key and proof.</returns>
        public SrpSession DeriveSession(string serverSecretEphemeral, string clientPublicEphemeral, string salt, string username, string verifier, string clientSessionProof)
        {
            // N — A large safe prime (N = 2q+1, where q is prime)
            // g — A generator modulo N
            // k — Multiplier parameter (k = H(N, g) in SRP-6a, k = 3 for legacy SRP-6)
            // H — One-way hash function
            // PAD — Pad the number to have the same number of bytes as N
            var N   = Parameters.Prime;
            var g   = Parameters.Generator;
            var k   = Parameters.Multiplier;
            var H   = Parameters.Hash;
            var PAD = Parameters.Pad;

            // b — Secret ephemeral values
            // A — Public ephemeral values
            // s — User's salt
            // p — Cleartext Password
            // I — Username
            // v — Password verifier
            var b = SrpInteger.FromHex(serverSecretEphemeral);
            var A = SrpInteger.FromHex(clientPublicEphemeral);
            var s = SrpInteger.FromHex(salt);
            var I = username + string.Empty;
            var v = SrpInteger.FromHex(verifier);

            // B = kv + g^b (b = random number)
            var B = ((k * v) + g.ModPow(b, N)) % N;

            // A % N > 0
            if (A % N == 0)
            {
                // fixme: .code, .statusCode, etc.
                throw new SecurityException("The client sent an invalid public ephemeral");
            }

            // u = H(PAD(A), PAD(B))
            var u = H(PAD(A), PAD(B));

            // S = (Av^u) ^ b (computes session key)
            var S = ComputeS(A, b, u, v);

            // K = H(S)
            var K = H(S);

            // M = H(H(N) xor H(g), H(I), s, A, B, K)
            var M = H(H(N) ^ H(g), H(I), s, A, B, K);

            // validate client session proof
            var expected = M;
            var actual   = SrpInteger.FromHex(clientSessionProof);

            if (actual != expected)
            {
                // fixme: .code, .statusCode, etc.
                throw new SecurityException("Client provided session proof is invalid");
            }

            // P = H(A, M, K)
            var P = H(A, M, K);

            return(new SrpSession
            {
                Key = K.ToHex(),
                Proof = P.ToHex(),
            });
        }