# mwiede/jsch: the maintained JSch fork for modern SSH servers

> A fork of JSch 0.1.55 that ships rsa-sha2-256 and rsa-sha2-512, disables the ssh-rsa signature algorithm by default, and tracks OpenSSH behaviour closely enough that it tracks the OpenSSH configuration format too. The cost is that the crypto algorithm order changed, so a connection that worked against an old server may need the deprecated algorithms turned back on.

**mwiede/jsch** — fork of the popular jsch library

- Repository: https://github.com/mwiede/jsch
- Stars: 1,067 · Forks: 199
- Language: Java
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/mwiede-jsch

## Why a fork of JSch 0.1.55 still matters

This repository is a fork of the popular JSch library, and the README's title says it plainly: Fork of JSch-0.1.55. The original README is kept in the repository, and the fork's own README sits alongside it.

The reason for the fork is given as a list of four points, with a blog post by the author as the longer explanation.

OpenSSH disabled ssh-rsa in release 8.8 by default, so a client that only speaks the old RSA/SHA1 signature algorithm can no longer connect to a modern server. The fork supports rsa-sha2-256 and rsa-sha2-512, which are the signature algorithms defined by RFC 8332, and the point is that the original JSch does not have them.

Second, it is a drop-in replacement. You change the dependency coordinates and you are good to go.

Third, there is no active maintenance of JSch at SourceForge, so the upstream will not gain the algorithm support either.

Fourth, the fork stays in sync with OpenJDK features so that there is no need for additional dependencies. That last point is the one that shapes the whole dependency story, and it is the reason the FAQ's answer about Bouncy Castle is a workaround rather than the default.

The artifact coordinates are `com.github.mwiede:jsch` on Maven Central, and the version lines tell their own story. The releases are jsch-2.28.8 from 2026-10-10, jsch-2.28.7 from 2026-08-20 and jsch-2.28.6 from 2026-07-29. Up until 0.2.26 the versioning followed the original JSch scheme, and from 2.27.0 the project switched to semantic versioning, expressing that the library API is stable and used in production. The last push was on 2026-10-14.

## Swapping the dependency, and the classpath trap

The migration instructions are the practical part of the README, and they come in two flavours because there are two ways JSch ends up on your classpath.

If you depend on JSch directly, you replace the dependency:

```xml
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
```

with

```xml
<dependency>
  <groupId>com.github.mwiede</groupId>
  <artifactId>jsch</artifactId>
  <version>2.28.0</version>
</dependency>
```

If JSch comes in transitively, through an artifact `foo:bar`, you add the new dependency and exclude the old one:

```xml
<dependency>
  <groupId>com.github.mwiede</groupId>
  <artifactId>jsch</artifactId>
  <version>2.28.0</version>
</dependency>
<dependency>
  <groupId>foo</groupId>
  <artifactId>bar</artifactId>
  <exclusions>
        <exclusion>  
          <groupId>com.jcraft</groupId>
          <artifactId>jsch</artifactId>
        </exclusion>
      </exclusions> 
</dependency>
```

The warning that comes with both is that you must make sure you only have one JSch dependency on your classpath, and the suggested way to check is the output of `mvn dependency:tree`.

There is one more exclusion the README mentions. The `com.jcraft:jsch.agentproxy.jsch`, `com.jcraft:jsch.agentproxy.core` and `com.jcraft:jsch.agentproxy.pageant` modules can also be excluded, because those modules were integrated into this fork, as the release notes of 0.1.66 record.

## ssh-rsa is off by default, and that is the breaking change

The FAQ question is the one every adopter hits: why do ssh-rsa type keys not work with this fork and my server?

As of the 0.2.0 release, the RSA/SHA1 signature algorithm is disabled by default. The stated reasons are that SHA1 is no longer considered secure by the general cryptographic community and that the fork strives to maintain secure choices for default algorithms. It also follows the lead of the OpenSSH project, which disabled RSA/SHA1 signatures by default as of OpenSSH release 8.8.

The good news is that ssh-rsa type keys continue to function by default with the RSA/SHA256 and RSA/SHA512 signature algorithms, which are the RFC 8332 algorithms.

The bad news is the case where your server only supports RSA/SHA1. The README then gives four ways to re-enable it.

Globally, by adding `ssh-rsa` to the `jsch.server_host_key` and `jsch.client_pubkey` properties. Globally, by executing something similar to `JSch.setConfig("server_host_key", JSch.getConfig("server_host_key") + ",ssh-rsa")` plus the matching `PubkeyAcceptedAlgorithms` call. On a per-session basis, by doing the same with `session.setConfig` instead of `JSch.setConfig`. And by adding `ssh-rsa` to your OpenSSH type config file with the `HostKeyAlgorithms` and `PubkeyAcceptedAlgorithms` keywords, then using the `OpenSSHConfig` class.

The fourth option is the interesting one, because the repository has an `opensshFormat.md` file at the root, which is the reference for the OpenSSH config format that the library parses.

A separate FAQ entry covers the general case, that the fork is not 100 percent compatible with the original JSch, and that for compatibility with OpenSSH and improved security the order of crypto algorithms was changed.

## Modern key exchange algorithms, and when Bouncy Castle is needed

The other long FAQ entry covers the newer algorithms and the multi-release jar mechanism.

The minimum Java version is Java 8. The library is a Multi-Release jar, which means certain features are only available when a more recent Java version is used.

For ssh-ed25519 and ssh-ed448 you must use at least Java 15, or add Bouncy Castle, the `bcprov-jdk18on` artefact, to the classpath. For curve25519-sha256 and curve448-sha512 you need at least Java 11, or the same Bouncy Castle artefact. For chacha20-poly1305@openssh.com you must add Bouncy Castle.

The history is worth knowing, because it explains why you might find conflicting advice in different places. As of the 0.1.66 release, these algorithms can be used with older Java releases if Bouncy Castle is added to the classpath. As of the 0.1.72 release, chacha20-poly1305@openssh.com can only be used if Bouncy Castle is added to the classpath, so that one algorithm was tightened back.

The Bouncy Castle requirement is a direct consequence of the fourth reason for the fork, staying in sync with OpenJDK features so that no additional dependencies are needed. On a modern JDK the algorithms are in the platform; on Java 8 they are not, and the fallback is a third-party library.

So the dependency story is conditional. A service running on Java 21 gets the newer signature and key exchange algorithms with nothing added. A service stuck on Java 8 gets the older algorithm set plus an optional Bouncy Castle, and the README's per-algorithm table tells you exactly which ones need it.

## System properties for the crypto algorithm order

The second half of the compatibility FAQ entry is about the algorithm order, and it is a workaround for a problem the fork created deliberately.

For compatibility with OpenSSH and improved security, the order of crypto algorithms was changed. If you still want to use older or deprecated algorithms you need to change the configuration, with examples in issues 37 and 40.

To make that easier, starting with the 0.1.65 release, several system properties can be set at your application's startup. The list shown in the README starts with `jsch.kex`, which is analogous to `JSch.setConfig("kex", "...")`,.

The design is worth noting. A system property set at startup is a deployment-level decision, which is the right level for an algorithm order that differs between environments. A developer does not have to touch the code, and a staging environment can be configured differently from production without a rebuild.

It is a blunt instrument, though. The property applies to the whole process, so if you have one job that must talk to a legacy server and another that must not accept the legacy algorithms, they cannot be configured differently through system properties. For that case the per-session `session.setConfig` route, which the README also documents, is the one that works.

## The examples folder is the documentation

The README is honest about the documentation. It asks whether there is any documentation and answers: not much. Check the example code in the examples folder, and there are some wiki pages, namely Jsch-Configuration and Jsch-Logging.

The examples folder is substantial, with around twenty-five files, and the names describe the surface of the library. There is `Shell.java` and `Exec.java` for command execution, `Sftp.java`, `ScpFrom.java`, `ScpTo.java` and `ScpToNoneCipher.java` for file transfer, `PortForwardingL.java`, `PortForwardingR.java`, `SocketForwardingL.java` and `StreamForwarding.java` for port and stream forwarding, `JumpHosts.java` for proxying through a bastion, `KeyGen.java` and `KeyGenOpenSSHv1.java` for key generation, `KnownHosts.java` and `UserAuthKI.java` for host key and key pair verification, `Sudo.java`, `Daemon.java` and `Subsystem.java` for the less usual modes, `AES.java` and `Compression.java` for algorithm options, `OpenSSHConfig.java` for the config file format, `JSchWithAgentProxy.java` for agent forwarding, `ChangePassphrase.java` for key passphrases, `Logger.java` for the logging setup, and a `README` file of its own.

`JSchWithAgentProxy.java` connects back to the earlier note about the agent proxy modules having been integrated into the fork, and `OpenSSHConfig.java` is the example for the OpenSSH config parsing the FAQ recommends as the cleanest way to re-enable an old algorithm.

The repository root is a Maven project with a `pom.xml`, the `mvnw` and `mvnw.cmd` wrappers, a `.mvn/` directory, a `.sdkmanrc` for the JDK version and a `.devcontainer/` directory. There is a `ChangeLog` file and a `ChangeLog.md`, an `eclipse-java-google-style.xml` for the code style, and separate licence files for the parts of the original library that carried their own terms, `LICENSE.JZlib.txt` and `LICENSE.jBCrypt.txt`, next to `LICENSE.txt`.

## Where mwiede/jsch is the wrong choice

The first wrong case is a team that could use a maintained SSH library with an active upstream of its own. This is a fork of a codebase whose original is no longer maintained, which is a perfectly good thing to depend on and a poor thing to build a new platform on. If you are writing a new service and choosing an SSH client, the choice is between this and something else, and the question of who maintains it in five years is a real one.

The second is a deployment that still depends on RSA/SHA1 and cannot reconfigure it. A server that only offers ssh-rsa needs the four documented workarounds, whether as a system property, a global config call, a per-session config call or an OpenSSH config file. That is a decision to keep a deprecated algorithm alive, and it should be a decision with an expiry date.

The third is a codebase on Java 8 that needs the newer key exchange algorithms. Then Bouncy Castle comes in as a dependency, and the fork's fourth reason for existing, staying in sync with OpenJDK so no extra dependencies are needed, no longer holds for you.

The fourth is a team that never had JSch. The library is an old codebase with an old API, and the README's own compatibility notes describe how much of the original behaviour changed. Adopting it for a new project means adopting its API and its conventions, and a modern alternative would give you a smaller surface.

The fifth is an organisation that needs a clear licence story. The repository carries three licence files, `LICENSE.txt` plus the JZlib and jBCrypt ones, because the fork inherited code with its own terms. A team that has to answer a licence question about every artefact in its dependency tree will want to read all three.

## Conclusion

mwiede/jsch suits a Java team that is still on JSch and needs to keep talking to servers that turned off ssh-rsa, and that would rather swap a Maven coordinate than port an SSH client. It does not suit a team that wants a modern SSH library with an active upstream of its own, because this is a fork of a codebase whose original is unmaintained, and it does not suit a deployment that needs the old RSA/SHA1 behaviour without reconfiguring it. Before adopting it, check the algorithm list your server offers, because the order of crypto algorithms changed for OpenSSH compatibility, and remember that the `com.jcraft` artifact and this one must not both be on the classpath, which the README suggests checking with `mvn dependency:tree`.

## FAQ

### Why is mwiede/jsch a fork of JSch 0.1.55?

Because OpenSSH disabled ssh-rsa by default in release 8.8 and the original JSch has no active maintenance, so it never gained rsa-sha2-256 and rsa-sha2-512 support. The fork also stays in sync with OpenJDK features so that no extra dependencies are needed.

### How do I replace com.jcraft:jsch with this fork?

Change the groupId to com.github.mwiede and the version to a 2.x release. If JSch comes in transitively you must also exclude the com.jcraft one, and you should check with `mvn dependency:tree` that only one JSch is on the classpath.

### Why does my ssh-rsa key no longer work with mwiede/jsch?

Since the 0.2.0 release the RSA/SHA1 signature algorithm is disabled by default, following OpenSSH release 8.8. The key still works with rsa-sha2-256 and rsa-sha2-512, and RSA/SHA1 can be re-enabled through the `jsch.server_host_key` and `jsch.client_pubkey` properties, the JSch or session config calls, or an OpenSSH config file.

### Do I need Bouncy Castle to use the modern SSH algorithms?

Only on older Java versions. ssh-ed25519 and ssh-ed448 need Java 15 or later, curve25519-sha256 and curve448-sha512 need Java 11 or later, and chacha20-poly1305@openssh.com always needs Bouncy Castle, with the bcprov-jdk18on artefact on the classpath.

### What is the minimum Java version for mwiede/jsch?

Java 8. The library is a Multi-Release jar, so several newer algorithms are only available when you run on a more recent Java version or add Bouncy Castle to the classpath.

## Sources

- [Issues](https://github.com/mwiede/jsch/issues)
- [mwiede/jsch on GitHub](https://github.com/mwiede/jsch)
- [README](https://github.com/mwiede/jsch/blob/master/README.md)
- [Releases](https://github.com/mwiede/jsch/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mwiede-jsch
