예제 #1
0
        public void EphemeralKeyLengthTest()
        {
            // The -1 is to account for the byte that BigInteger.ToByteArray() adds to account for the sign.
            var ephemeralLengthBits = (AuthenticationHelper.CreateBigIntegerRandom().ToBigEndianByteArray().Length - 1) * BitsInByte;

            Assert.True(ephemeralLengthBits >= EphemeralBitSize);
        }
예제 #2
0
        public void TestSrpProtocol()
        {
            // Choose hash algorithm, g, N, username, password, salt
            SHA256     sha256     = SHA256.Create();
            BigInteger g          = AuthenticationHelper.g;
            BigInteger N          = AuthenticationHelper.N;
            string     password   = "******";
            string     saltString = "fef2871d83ce2120f9c47a46db303d37"; //Does not have to always be this string
            BigInteger salt       = BigIntegerExtensions.FromUnsignedLittleEndianHex(saltString);

            // Compute x = H(s,p)
            byte[] passBytes  = Encoding.UTF8.GetBytes(password);
            byte[] userIdHash = sha256.ComputeHash(passBytes);
            byte[] saltBytes  = salt.ToByteArray();
            byte[] xBytes     = new byte[saltBytes.Length + userIdHash.Length];
            Buffer.BlockCopy(saltBytes, 0, xBytes, 0, saltBytes.Length);
            Buffer.BlockCopy(userIdHash, 0, xBytes, saltBytes.Length, userIdHash.Length);
            byte[]     xDigest = sha256.ComputeHash(xBytes);
            BigInteger x       = BigIntegerExtensions.FromUnsignedBigEndian(xDigest);

            // Compute v = g^x
            BigInteger v = BigInteger.ModPow(g, x, N);

            // Generate random a, b, A
            BigInteger a, b, A;

            do
            {
                a = AuthenticationHelper.CreateBigIntegerRandom();
                b = AuthenticationHelper.CreateBigIntegerRandom();
                A = BigInteger.ModPow(g, a, N);
            } while ((A.TrueMod(N)).Equals(BigInteger.Zero));

            // Calculate k = H(N, g)
            byte[] nBytes  = N.ToByteArray();
            byte[] gBytes  = g.ToByteArray();
            byte[] content = new byte[nBytes.Length + gBytes.Length];
            Buffer.BlockCopy(nBytes, 0, content, 0, nBytes.Length);
            Buffer.BlockCopy(gBytes, 0, content, nBytes.Length, gBytes.Length);
            byte[]     digest = sha256.ComputeHash(content);
            BigInteger k      = BigIntegerExtensions.FromUnsignedBigEndian(digest);

            //Calculate B = kv + g^b
            BigInteger B = k * v + (BigInteger.ModPow(g, b, N));

            // Calculate u = H(A,B)
            byte[] ABytes = A.ToByteArray();
            byte[] BBytes = B.ToByteArray();
            byte[] ABcat  = new byte[ABytes.Length + BBytes.Length];
            Buffer.BlockCopy(ABytes, 0, ABcat, 0, ABytes.Length);
            Buffer.BlockCopy(BBytes, 0, ABcat, ABytes.Length, BBytes.Length);
            byte[]     ABdigest = sha256.ComputeHash(ABcat);
            BigInteger u        = BigIntegerExtensions.FromUnsignedBigEndian(ABdigest);

            // Calculate user side userS = (B - kg^x) ^ (a + ux)
            BigInteger userS = BigInteger.ModPow((B - k * BigInteger.ModPow(g, x, N)), a + u * x, N);

            // Calculate user side userK = H(userS)
            byte[]     userSBytes  = userS.ToByteArray();
            byte[]     userSDigest = sha256.ComputeHash(userSBytes);
            BigInteger userK       = BigIntegerExtensions.FromUnsignedBigEndian(userSDigest);

            // Calculate host side hostS = (Av^u) ^ b
            BigInteger hostS = BigInteger.ModPow((A * BigInteger.ModPow(v, u, N)), b, N);

            // Calculate host side hostK = H(hostS)
            byte[]     hostSBytes  = hostS.ToByteArray();
            byte[]     hostSDigest = sha256.ComputeHash(hostSBytes);
            BigInteger hostK       = BigIntegerExtensions.FromUnsignedBigEndian(hostSDigest);

            Assert.Equal(hostS, userS);
            Assert.Equal(hostK, userK);
        }