private void updateKeys(KeyExchange kex) { byte[] K = kex.getK(); byte[] H = kex.getH(); HASH hash = kex.getHash(); // string[] guess=kex.guess; if (session_id == null) { session_id = new byte[H.Length]; Array.Copy(H, 0, session_id, 0, H.Length); } /* Initial IV client to server: HASH (K || H || "A" || session_id) Initial IV server to client: HASH (K || H || "B" || session_id) Encryption key client to server: HASH (K || H || "C" || session_id) Encryption key server to client: HASH (K || H || "D" || session_id) Integrity key client to server: HASH (K || H || "E" || session_id) Integrity key server to client: HASH (K || H || "F" || session_id) */ buf.reset(); buf.putMPInt(K); buf.putByte(H); buf.putByte((byte)0x41); buf.putByte(session_id); hash.update(buf.buffer, 0, buf.index); IVc2s = hash.digest(); int j = buf.index - session_id.Length - 1; buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); IVs2c = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); Ec2s = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); Es2c = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); MACc2s = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); MACs2c = hash.digest(); try { Type c; string method; method = guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]; c = Type.GetType(getConfig(method)); s2ccipher = (Cipher)(c.newInstance()); while (s2ccipher.getBlockSize() > Es2c.Length) { buf.reset(); buf.putMPInt(K); buf.putByte(H); buf.putByte(Es2c); hash.update(buf.buffer, 0, buf.index); byte[] foo = hash.digest(); byte[] bar = new byte[Es2c.Length + foo.Length]; Array.Copy(Es2c, 0, bar, 0, Es2c.Length); Array.Copy(foo, 0, bar, Es2c.Length, foo.Length); Es2c = bar; } s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c); s2ccipher_size = s2ccipher.getIVSize(); method = guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]; c = Type.GetType(getConfig(method)); s2cmac = (MAC)(c.newInstance()); s2cmac.init(MACs2c); //mac_buf=new byte[s2cmac.getBlockSize()]; s2cmac_result1 = new byte[s2cmac.getBlockSize()]; s2cmac_result2 = new byte[s2cmac.getBlockSize()]; method = guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]; c = Type.GetType(getConfig(method)); c2scipher = (Cipher)(c.newInstance()); while (c2scipher.getBlockSize() > Ec2s.Length) { buf.reset(); buf.putMPInt(K); buf.putByte(H); buf.putByte(Ec2s); hash.update(buf.buffer, 0, buf.index); byte[] foo = hash.digest(); byte[] bar = new byte[Ec2s.Length + foo.Length]; Array.Copy(Ec2s, 0, bar, 0, Ec2s.Length); Array.Copy(foo, 0, bar, Ec2s.Length, foo.Length); Ec2s = bar; } c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s); c2scipher_size = c2scipher.getIVSize(); method = guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]; c = Type.GetType(getConfig(method)); c2smac = (MAC)(c.newInstance()); c2smac.init(MACc2s); method = guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; initDeflater(method); method = guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; initInflater(method); } catch (Exception e) { if (e is JSchException) throw e; throw new JSchException(e.ToString(), e); //Console.Error.WriteLine("updatekeys: "+e); } }
private Cipher genCipher() { try { Type c; c = Type.GetType(JSch.getConfig("3des-cbc")); cipher = (Cipher)(c.newInstance()); } catch //(Exception e) { } return cipher; }
byte[] genKey(byte[] passphrase, byte[] iv) { if (cipher == null) cipher = genCipher(); if (hash == null) hash = genHash(); byte[] key = new byte[cipher.getBlockSize()]; int hsize = hash.getBlockSize(); byte[] hn = new byte[key.Length / hsize * hsize + (key.Length % hsize == 0 ? 0 : hsize)]; try { byte[] tmp = null; if (vendor == VENDOR_OPENSSH) { for (int index = 0; index + hsize <= hn.Length; ) { if (tmp != null) { hash.update(tmp, 0, tmp.Length); } hash.update(passphrase, 0, passphrase.Length); hash.update(iv, 0, iv.Length); tmp = hash.digest(); Array.Copy(tmp, 0, hn, index, tmp.Length); index += tmp.Length; } Array.Copy(hn, 0, key, 0, key.Length); } else if (vendor == VENDOR_FSECURE) { for (int index = 0; index + hsize <= hn.Length; ) { if (tmp != null) { hash.update(tmp, 0, tmp.Length); } hash.update(passphrase, 0, passphrase.Length); tmp = hash.digest(); Array.Copy(tmp, 0, hn, index, tmp.Length); index += tmp.Length; } Array.Copy(hn, 0, key, 0, key.Length); } } catch (Exception e) { Console.Error.WriteLine(e); } return key; }
private byte[] encrypt(byte[] plain, byte[][] _iv) { if (passphrase == null) return plain; if (cipher == null) cipher = genCipher(); byte[] iv = _iv[0] = new byte[cipher.getIVSize()]; if (random == null) random = genRandom(); random.fill(iv, 0, iv.Length); byte[] key = genKey(passphrase, iv); byte[] encoded = plain; // PKCS#5Padding { //int bsize=cipher.getBlockSize(); int bsize = cipher.getIVSize(); byte[] foo = new byte[(encoded.Length / bsize + 1) * bsize]; Array.Copy(encoded, 0, foo, 0, encoded.Length); int padding = bsize - encoded.Length % bsize; for (int i = foo.Length - 1; (foo.Length - padding) <= i; i--) { foo[i] = (byte)padding; } encoded = foo; } try { cipher.init(Cipher.ENCRYPT_MODE, key, iv); cipher.update(encoded, 0, encoded.Length, encoded, 0); } catch //(Exception e) { //Console.Error.WriteLine(e); } Util.bzero(key); return encoded; }