private byte[] CalcSessionID()
        {
            MemoryStream  bos = new MemoryStream();
            SSHServerInfo si  = _cInfo._serverinfo;

            byte[] h = si.host_key_public_modulus.getBytes();
            byte[] s = si.server_key_public_modulus.getBytes();
            //System.out.println("len h="+h.Length);
            //System.out.println("len s="+s.Length);

            int off_h = (h[0] == 0? 1 : 0);
            int off_s = (s[0] == 0? 1 : 0);

            bos.Write(h, off_h, h.Length - off_h);
            bos.Write(s, off_s, s.Length - off_s);
            bos.Write(si.anti_spoofing_cookie, 0, si.anti_spoofing_cookie.Length);

            byte[] session_id = new MD5CryptoServiceProvider().ComputeHash(bos.ToArray());
            //System.out.println("sess-id-len=" + session_id.Length);
            return(session_id);
        }
        private void SendSessionKey(byte[] session_key)
        {
            try
            {
                //step1 XOR with session_id
                byte[] working_data = new byte[session_key.Length];
                byte[] session_id   = CalcSessionID();
                Array.Copy(session_key, 0, working_data, 0, session_key.Length);
                for (int i = 0; i < session_id.Length; i++)
                {
                    working_data[i] ^= session_id[i];
                }

                //step2 decrypts with RSA
                RSAPublicKey  first_encryption;
                RSAPublicKey  second_encryption;
                SSHServerInfo si = _cInfo._serverinfo;
                int           first_key_bytelen, second_key_bytelen;
                if (si.server_key_bits < si.host_key_bits)
                {
                    first_encryption   = new RSAPublicKey(si.server_key_public_exponent, si.server_key_public_modulus);
                    second_encryption  = new RSAPublicKey(si.host_key_public_exponent, si.host_key_public_modulus);
                    first_key_bytelen  = (si.server_key_bits + 7) / 8;
                    second_key_bytelen = (si.host_key_bits + 7) / 8;
                }
                else
                {
                    first_encryption   = new RSAPublicKey(si.host_key_public_exponent, si.host_key_public_modulus);
                    second_encryption  = new RSAPublicKey(si.server_key_public_exponent, si.server_key_public_modulus);
                    first_key_bytelen  = (si.host_key_bits + 7) / 8;
                    second_key_bytelen = (si.server_key_bits + 7) / 8;
                }

                BigInteger first_result  = RSAUtil.PKCS1PadType2(new BigInteger(working_data), first_key_bytelen, _param.Random).modPow(first_encryption.Exponent, first_encryption.Modulus);
                BigInteger second_result = RSAUtil.PKCS1PadType2(first_result, second_key_bytelen, _param.Random).modPow(second_encryption.Exponent, second_encryption.Modulus);

                //output
                SSH1DataWriter writer = new SSH1DataWriter();
                writer.Write((byte)_cInfo._algorithmForTransmittion);
                writer.Write(si.anti_spoofing_cookie);
                writer.Write(second_result);
                writer.Write(0);                 //protocol flags

                //send
                SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_SESSION_KEY, writer.ToByteArray());
                SSH1Packet.WriteTo(_stream);

                _sessionID = session_id;
            }
            catch (Exception e)
            {
                if (e is IOException)
                {
                    throw (IOException)e;
                }
                else
                {
                    string t = e.StackTrace;
                    throw new SSHException(e.Message);                     //IOException以外はみなSSHExceptionにしてしまう
                }
            }
        }