Beispiel #1
0
        private SrpInteger ComputeHash(byte[] data)
        {
            var hash = Hasher.ComputeHash(data);

            return(SrpInteger.FromByteArray(hash));

            // should yield the same result:
            // var hex = hash.Aggregate(new StringBuilder(), (sb, b) => sb.Append(b.ToString("X2")), sb => sb.ToString());
            // return SrpInteger.FromHex(hex);
        }
Beispiel #2
0
        /// <summary>
        /// Derives the client session.
        /// </summary>
        /// <param name="clientSecretEphemeral">The client secret ephemeral.</param>
        /// <param name="serverPublicEphemeral">The server public ephemeral.</param>
        /// <param name="salt">The salt.</param>
        /// <param name="username">The username.</param>
        /// <param name="privateKey">The private key.</param>
        /// <returns>Session key and proof.</returns>
        public SrpSession DeriveSession(string clientSecretEphemeral, string serverPublicEphemeral, byte[] salt, string username, byte[] privateKey)
        {
            // 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
            var N = Parameters.Prime;
            var g = Parameters.Generator;
            var H = Parameters.Hash;

            // a — Secret ephemeral value
            // B — Public ephemeral value
            // s — User's salt
            // I — Username
            // x — Private key (derived from p and s)
            var a = SrpInteger.FromHex(clientSecretEphemeral);
            var B = SrpInteger.FromHex(serverPublicEphemeral);
            var s = SrpInteger.FromByteArray(salt);
            var I = username + string.Empty;
            var x = SrpInteger.FromByteArray(privateKey);

            // A = g^a (a = random number)
            var A = g.ModPow(a, N);

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

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

            // S = (B - kg^x) ^ (a + ux)
            var S = ComputeS(a, B, u, x);

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

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

            return(new SrpSession
            {
                Key = K.ToByteArray(),
                Proof = M1.ToByteArray(),
            });
        }
Beispiel #3
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.FromByteArray(clientSession.Proof);
            var K = SrpInteger.FromByteArray(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");
            }
        }