/// <summary> /// /// </summary> /// <param name="clientId"></param> /// <param name="serverId"></param> /// <param name="clientKexInit"></param> /// <param name="serverKexInit"></param> public override void PerformClientExchange(String clientId, String serverId, byte[] clientKexInit, byte[] serverKexInit) { this.clientId = clientId; this.serverId = serverId; this.clientKexInit = clientKexInit; this.serverKexInit = serverKexInit; BigInteger q = p.subtract(BigInteger.ONE).divide(g); do { x = new BigInteger(p.bitLength(), new RNGCryptoServiceProvider()); }while((x.compareTo(BigInteger.ONE) < 0) && (x.compareTo(q) > 0)); e = g.modPow(x, p); if (e.compareTo(BigInteger.ONE) < 0 || e.compareTo(p.subtract(BigInteger.ONE)) > 0) { throw new SSHException("Key exchange failed to generate e value", SSHException.INTERNAL_ERROR); } SSHPacket packet = transport.GetSSHPacket(true); packet.WriteByte(SSH_MSG_KEXDH_INIT); packet.WriteBigInteger(e); transport.SendMessage(packet); packet = transport.NextMessage(); if (packet.MessageID != SSH_MSG_KEXDH_REPLY) { throw new SSHException("Expected SSH_MSG_KEXDH_REPLY but got message id " + packet.MessageID, SSHException.KEY_EXCHANGE_FAILED); } hostKey = packet.ReadBinaryString(); f = packet.ReadBigInteger(); signature = packet.ReadBinaryString(); secret = f.modPow(x, p); CalculateExchangeHash(); }