示例#1
0
        public bool ProcessZkInitiation(BinaryReader binReader, BinaryWriter binWriter, Stopwatch sw)
        {
            _username   = binReader.ReadString();
            _aEphemeral = binReader.ReadBytes(32);
            _logger.Debug("ZkInitiation client username received: {0}", _username);
            _logger.Debug("ZkInitiation client Ephemeral received: {0}", Convert.ToBase64String(_aEphemeral));
            _zkPasswordHash = _repository.GetPasswordHashSet(_username);
            if (null == _zkPasswordHash)
            {
                _logger.Debug("ZkInitiation client username not found. Authentication failed.");
                binWriter.Write(false);
                return(false);
            }
            _bRand            = _zkProtocol.CryptRand();
            _bEphemeral       = _zkProtocol.GetServerEphemeralB(_zkPasswordHash.Salt, _zkPasswordHash.Verifier, _bRand);
            _scramble         = _zkProtocol.CalculateRandomScramble(_aEphemeral, _bEphemeral);
            _serverSessionKey = _zkProtocol.ServerComputeSessionKey(_zkPasswordHash.Salt,
                                                                    _zkPasswordHash.Key, _aEphemeral, _bEphemeral, _scramble);

            binWriter.Write(true);
            binWriter.Write(_zkPasswordHash.Salt);
            _logger.Debug("ZkInitiation hash salt sent to client: {0}", Convert.ToBase64String(_zkPasswordHash.Salt));
            binWriter.Write(_bEphemeral);
            _logger.Debug("ZkInitiation server Ephemeral sent to client: {0}", Convert.ToBase64String(_bEphemeral));
            return(true);
        }
示例#2
0
        public bool ProcessZkInitiation(BinaryReader binReader, BinaryWriter binWriter, Stopwatch sw)
        {
            _username       = binReader.ReadString();
            _aEphemeral     = binReader.ReadBytes(32);
            _zkPasswordHash = _repository.GetPasswordHashSet(_username);
            if (null == _zkPasswordHash)
            {
                binWriter.Write(false);
                return(false);
            }
            _bRand            = _zkProtocol.CryptRand();
            _bEphemeral       = _zkProtocol.GetServerEphemeralB(_zkPasswordHash.Salt, _zkPasswordHash.Verifier, _bRand);
            _scramble         = _zkProtocol.CalculateRandomScramble(_aEphemeral, _bEphemeral);
            _serverSessionKey = _zkProtocol.ServerComputeSessionKey(_zkPasswordHash.Salt,
                                                                    _zkPasswordHash.Key, _aEphemeral, _bEphemeral, _scramble);

            binWriter.Write(true);
            binWriter.Write(_zkPasswordHash.Salt);
            binWriter.Write(_bEphemeral);
            return(true);
        }
        public void SimpleProtocolTest()
        {
            var sr = new ZkProtocol();
            var username = "******";
            var pwd = "cc3a6a12-0e5b-47fb-ae45-3485e34582d4";

            // prerequisit: generate password hash that would be stored on server
            var pwdHash = sr.HashCredentials(username, pwd);

            // Step 1. Client sends username and ephemeral hash of random number.
            var aRand = sr.CryptRand();
            var aClientEphemeral = sr.GetClientEphemeralA(aRand);
            // send username and aClientEphemeral to server

            // Step 2. Server looks up username, gets pwd hash, and sends client ephemeral has of params.
            var bRand = sr.CryptRand();
            var bServerEphemeral = sr.GetServerEphemeralB(pwdHash.Salt, pwdHash.Verifier, bRand);
            // send salt and bServerEphemeral to client
            var clientSalt = pwdHash.Salt;

            // Step 3. Client and server calculate random scramble of ephemeral hash values exchanged.
            var clientScramble = sr.CalculateRandomScramble(aClientEphemeral, bServerEphemeral);
            var serverScramble = sr.CalculateRandomScramble(aClientEphemeral, bServerEphemeral);

            var scrambleSame = clientScramble.IsEqualTo(serverScramble);

            // Step 4. Client computes session key
            var clientSessionKey = sr.ClientComputeSessionKey(clientSalt, username, pwd, aClientEphemeral, bServerEphemeral, clientScramble);

            // Step 5. Server computes session key
            var serverSessionKey = sr.ServerComputeSessionKey(pwdHash.Salt, pwdHash.Key, aClientEphemeral, bServerEphemeral, serverScramble);

            var sessionKeysSame = clientSessionKey.IsEqualTo(serverSessionKey);

            // Step 6. Client creates hash of session key and sends to server. Server creates same key and verifies.
            var clientSessionHash = sr.ClientCreateSessionHash(username, pwdHash.Salt, aClientEphemeral,
                bServerEphemeral, clientSessionKey);
            // send to server and server verifies
            // server validates clientSessionHash is same as serverClientSessionHash
            var serverClientSessionHash = sr.ClientCreateSessionHash(username, pwdHash.Salt, aClientEphemeral,
                bServerEphemeral, serverSessionKey);

            var clientEqualToServer = clientSessionHash.IsEqualTo(serverClientSessionHash);

            // Step 7. Server creates hash of session key and sends to client. Client creates same key and verifies.
            var serverSessionHash = sr.ServerCreateSessionHash(aClientEphemeral, clientSessionHash, serverSessionKey);
            // server sends serverSessionHash to client
            // validate that serverSessionHash is same as clientServerSessionHash
            var clientServerSessionHash = sr.ServerCreateSessionHash(aClientEphemeral, clientSessionHash, clientSessionKey);

            var serverEqualToClient = serverSessionHash.IsEqualTo(clientServerSessionHash);

            //proof
            Assert.IsTrue(sessionKeysSame);
            Assert.IsTrue(scrambleSame);
            Assert.IsTrue(clientEqualToServer);
            Assert.IsTrue(serverEqualToClient);

            var data = sr.Combine(sr.CryptRand(), sr.CryptRand(), sr.CryptRand());
            var crypto = new ZkCrypto(clientSessionKey, clientScramble);
            var encrypted = crypto.Encrypt(data);
            var decrypted = crypto.Decrypt(encrypted);
            var cryptSame = data.IsEqualTo(decrypted);
            Assert.IsTrue(cryptSame);
        }