ninio-ssh/src/main/java/com/davfx/ninio/ssh/UncipheringConnection.java
public void init(String encryptionAlgorithm, String cipherAlgorithm, int keyLength, String macAlgorithm, byte[] K, byte[] H, byte[] sessionId) throws GeneralSecurityException {
		MessageDigest sha = MessageDigest.getInstance("SHA-1");

		sha.reset();
		sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('B').append(sessionId).finish());
		byte[] iv = sha.digest();

		sha.reset();
		sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('D').append(sessionId).finish());
		byte[] cipherKey = sha.digest();

		try {
			cipher = Cipher.getInstance(encryptionAlgorithm + "/" + cipherAlgorithm + "/NoPadding");

			iv = CipherUtils.expandKey(K, H, iv, sha, cipher.getBlockSize());
			cipherKey = CipherUtils.expandKey(K, H, cipherKey, sha, keyLength);

			iv = CipherUtils.shrinkKey(iv, cipher.getBlockSize());
			cipherKey = CipherUtils.shrinkKey(cipherKey, keyLength);

			cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cipherKey, encryptionAlgorithm), new IvParameterSpec(iv));

			sha.reset();
			sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('F').append(sessionId).finish());
			byte[] macKey = sha.digest();

			mac = Mac.getInstance(macAlgorithm);

			macKey = CipherUtils.expandKey(K, H, macKey, sha, mac.getMacLength());
			macKey = CipherUtils.shrinkKey(macKey, mac.getMacLength());

			mac.init(new SecretKeySpec(macKey, macAlgorithm));
			
			firstBuffer = ByteBuffer.allocate(cipher.getBlockSize());
			macBuffer = ByteBuffer.allocate(mac.getMacLength());
		} catch (GeneralSecurityException e) {
			cipher = null;
			mac = null;
			throw e;
		}
	}
public void init(String encryptionAlgorithm, String cipherAlgorithm, int keyLength, String macAlgorithm, byte[] K, byte[] H, byte[] sessionId) throws GeneralSecurityException {
		MessageDigest sha = MessageDigest.getInstance("SHA-1");

		sha.reset();
		sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('B').append(sessionId).finish());
		byte[] iv = sha.digest();

		sha.reset();
		sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('D').append(sessionId).finish());
		byte[] cipherKey = sha.digest();

		try {
			cipher = Cipher.getInstance(encryptionAlgorithm + "/" + cipherAlgorithm + "/NoPadding");

			iv = CipherUtils.expandKey(K, H, iv, sha, cipher.getBlockSize());
			cipherKey = CipherUtils.expandKey(K, H, cipherKey, sha, keyLength);

			iv = CipherUtils.shrinkKey(iv, cipher.getBlockSize());
			cipherKey = CipherUtils.shrinkKey(cipherKey, keyLength);

			cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cipherKey, encryptionAlgorithm), new IvParameterSpec(iv));

			sha.reset();
			sha.update(new SshPacketBuilder().writeMpInt(K).append(H).writeByte('F').append(sessionId).finish());
			byte[] macKey = sha.digest();

			mac = Mac.getInstance(macAlgorithm);

			macKey = CipherUtils.expandKey(K, H, macKey, sha, mac.getMacLength());
			macKey = CipherUtils.shrinkKey(macKey, mac.getMacLength());

			mac.init(new SecretKeySpec(macKey, macAlgorithm));
			
			firstBuffer = ByteBuffer.allocate(cipher.getBlockSize());
			macBuffer = ByteBuffer.allocate(mac.getMacLength());
		} catch (GeneralSecurityException e) {
			cipher = null;
			mac = null;
			throw e;
		}
	}
/*
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)