public static KeyPair genKeyPair(JSch jsch, int type, int key_size)
 {
     KeyPair kpair=null;
     if(type==DSA){ kpair=new KeyPairDSA(jsch); }
     else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
     if(kpair!=null)
     {
         kpair.generate(key_size);
     }
     return kpair;
 }
        public static KeyPair load(JSch jsch, String prvkey, String pubkey)
        {
            byte[] iv=new byte[8];       // 8
            bool encrypted=true;
            byte[] data=null;

            byte[] publickeyblob=null;

            int type=ERROR;
            int vendor=VENDOR_OPENSSH;

            try
            {
                //File file=new File(prvkey);
                FileStream fis=File.OpenRead(prvkey);
                byte[] buf=new byte[(int)(fis.Length)];
                int len=fis.Read(buf, 0, buf.Length);
                fis.Close();

                int i=0;

                while(i<len)
                {
                    if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I')
                    {
                        i+=6;
                        if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; }
                        else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
                        else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H')
                        { // FSecure
                            type=UNKNOWN;
                            vendor=VENDOR_FSECURE;
                        }
                        else
                        {
                            //System.outs.println("invalid format: "+identity);
                            throw new JSchException("invaid privatekey: "+prvkey);
                        }
                        i+=3;
                        continue;
                    }
                    if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==',')
                    {
                        i+=4;
                        for(int ii=0; ii<iv.Length; ii++)
                        {
                            iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+(a2b(buf[i++])&0xf));
                        }
                        continue;
                    }
                    if(buf[i]==0x0d &&
                        i+1<buf.Length && buf[i+1]==0x0a)
                    {
                        i++;
                        continue;
                    }
                    if(buf[i]==0x0a && i+1<buf.Length)
                    {
                        if(buf[i+1]==0x0a){ i+=2; break; }
                        if(buf[i+1]==0x0d &&
                            i+2<buf.Length && buf[i+2]==0x0a)
                        {
                            i+=3; break;
                        }
                        bool inheader=false;
                        for(int j=i+1; j<buf.Length; j++)
                        {
                            if(buf[j]==0x0a) break;
                            //if(buf[j]==0x0d) break;
                            if(buf[j]==':'){inheader=true; break;}
                        }
                        if(!inheader)
                        {
                            i++;
                            encrypted=false;    // no passphrase
                            break;
                        }
                    }
                    i++;
                }

                if(type==ERROR)
                {
                    throw new JSchException("invaid privatekey: "+prvkey);
                }

                int start=i;
                while(i<len)
                {
                    if(buf[i]==0x0a)
                    {
                        bool xd=(buf[i-1]==0x0d);
                        Array.Copy(buf, i+1,
                            buf,
                            i-(xd ? 1 : 0),
                            len-i-1-(xd ? 1 : 0)
                            );
                        if(xd)len--;
                        len--;
                        continue;
                    }
                    if(buf[i]=='-'){  break; }
                    i++;
                }
                data=Util.fromBase64(buf, start, i-start);

                if(data.Length>4 &&            // FSecure
                    data[0]==(byte)0x3f &&
                    data[1]==(byte)0x6f &&
                    data[2]==(byte)0xf9 &&
                    data[3]==(byte)0xeb)
                {

                    Buffer _buf=new Buffer(data);
                    _buf.getInt();  // 0x3f6ff9be
                    _buf.getInt();
                    byte[]_type=_buf.getString();
                    //System.outs.println("type: "+new String(_type));
                    byte[] _cipher=_buf.getString();
                    String cipher=Util.getString(_cipher);
                    //System.outs.println("cipher: "+cipher);
                    if(cipher.Equals("3des-cbc"))
                    {
                        _buf.getInt();
                        byte[] foo=new byte[data.Length-_buf.getOffSet()];
                        _buf.getByte(foo);
                        data=foo;
                        encrypted=true;
                        throw new JSchException("unknown privatekey format: "+prvkey);
                    }
                    else if(cipher.Equals("none"))
                    {
                        _buf.getInt();
                        _buf.getInt();

                        encrypted=false;

                        byte[] foo=new byte[data.Length-_buf.getOffSet()];
                        _buf.getByte(foo);
                        data=foo;
                    }
                }

                if(pubkey!=null)
                {
                    try
                    {
                        //file=new File(pubkey);
                        fis=File.OpenRead(pubkey);
                        buf=new byte[(int)(fis.Length)];
                        len=fis.Read(buf, 0, buf.Length);
                        fis.Close();

                        if(buf.Length>4 &&             // FSecure's public key
                            buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-')
                        {

                            bool valid=true;
                            i=0;
                            do{i++;}while(buf.Length>i && buf[i]!=0x0a);
                            if(buf.Length<=i) {valid=false;}

                            while(valid)
                            {
                                if(buf[i]==0x0a)
                                {
                                    bool inheader=false;
                                    for(int j=i+1; j<buf.Length; j++)
                                    {
                                        if(buf[j]==0x0a) break;
                                        if(buf[j]==':'){inheader=true; break;}
                                    }
                                    if(!inheader)
                                    {
                                        i++;
                                        break;
                                    }
                                }
                                i++;
                            }
                            if(buf.Length<=i){valid=false;}

                            start=i;
                            while(valid && i<len)
                            {
                                if(buf[i]==0x0a)
                                {
                                    Array.Copy(buf, i+1, buf, i, len-i-1);
                                    len--;
                                    continue;
                                }
                                if(buf[i]=='-'){  break; }
                                i++;
                            }
                            if(valid)
                            {
                                publickeyblob=Util.fromBase64(buf, start, i-start);
                                if(type==UNKNOWN)
                                {
                                    if(publickeyblob[8]=='d'){ type=DSA; }
                                    else if(publickeyblob[8]=='r'){ type=RSA; }
                                }
                            }
                        }
                        else
                        {
                            if(buf[0]=='s'&& buf[1]=='s'&& buf[2]=='h' && buf[3]=='-')
                            {
                                i=0;
                                while(i<len){ if(buf[i]==' ')break; i++;} i++;
                                if(i<len)
                                {
                                    start=i;
                                    while(i<len){ if(buf[i]==' ')break; i++;}
                                    publickeyblob=Util.fromBase64(buf, start, i-start);
                                }
                            }
                        }
                    }
                    catch//(Exception ee)
                    {
                    }
                }
            }
            catch(Exception e)
            {
                if(e is JSchException) throw (JSchException)e;
                throw new JSchException(e.ToString());
            }

            KeyPair kpair=null;
            if(type==DSA){ kpair=new KeyPairDSA(jsch); }
            else if(type==RSA){ kpair=new KeyPairRSA(jsch); }

            if(kpair!=null)
            {
                kpair.encrypted=encrypted;
                kpair.publickeyblob=publickeyblob;
                kpair.vendor=vendor;

                if(encrypted)
                {
                    kpair.iv=iv;
                    kpair.data=data;
                }
                else
                {
                    if(kpair.parse(data))
                    {
                        return kpair;
                    }
                    else
                    {
                        throw new JSchException("invaid privatekey: "+prvkey);
                    }
                }
            }

            return kpair;
        }