# hierynomus/sshj: an SSHv2 client library for Java

> sshj is a Java library for SSH, SCP and SFTP built around a pluggable algorithm registry. It fits JVM services that need to speak SSH inside their own process, and it asks you to make a deliberate choice about host key verification.

**hierynomus/sshj** — ssh, scp and sftp for java

- Repository: https://github.com/hierynomus/sshj
- Stars: 2,662 · Forks: 620
- Language: Java
- License: Apache-2.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/hierynomus-sshj

## The problem sshj solves for JVM services

Calling out to the ssh binary from Java works until it does not. You inherit the local OpenSSH configuration, you parse stderr, you cannot easily reuse a connection, and every deployment needs the binary present. sshj puts the SSHv2 protocol inside the JVM: the README describes command, subsystem and shell channels, local and remote port forwarding, scp, and a complete SFTP version 0 to 3 implementation. That last point is the one that decides most adoptions. A service that must upload files to a customer's SFTP endpoint cannot do it with a shell command that behaves differently on each host.

The audience is Java developers who control both ends of the deployment. The library gives you the protocol; it does not give you a connection pool, a retry policy or a configuration file. If you are looking for a managed SSH server or a CLI wrapper, this is the wrong layer. If you are writing a batch job that reads a remote directory and writes a file back, it is the right one.

## How the connection and negotiation model works

The README lists the algorithms sshj ships with, and the list is long: aes-gcm and chacha20-poly1305 ciphers, curve25519-sha256@libssh.org and the diffie-hellman-group14/15/16/17/18 families for key exchange, ed25519 and ecdsa signatures, hmac-sha2 and etm MAC variants, and zlib compression. It also ships extended, non-official algorithms such as camellia ciphers and several diffie-hellman-group15/16/18 variants with @ssh.com suffixes. The practical consequence is that sshj can talk to older appliances that negotiate algorithms OpenSSH has long since dropped, and that is a deliberate trade-off rather than an accident.

Negotiation is not left entirely to the client list. The README states that sshj implements SSH Extension Negotiation (RFC 8308): it advertises ext-info-c and uses the server's server-sig-algs extension to prefer public-key signature algorithms the server actually accepts during publickey authentication. That matters when a server offers ssh-rsa but not ssh-ed25519, or the reverse. Instead of trying signatures in a fixed order and failing, the client can read what the server says it supports. The README does not describe a fallback when a server ignores the extension, so assume the client list order still governs in that case.

## Adding sshj to a Maven build and opening a session

The README gives the Maven coordinates directly. The groupId is com.hierynomus, the artifactId is sshj, and the current release line is 0.41.1. Add this to pom.xml:

```xml
<dependency>
  <groupId>com.hierynomus</groupId>
  <artifactId>sshj</artifactId>
  <version>0.41.1</version>
</dependency>
```

The README notes that binary releases are not hosted in the repository itself, only on Maven Central, so a build that resolves from a mirror or an internal proxy needs that repository available. If your build tool is not Maven, translate the same coordinates into its format.

The README does not include a minimal connection example in the text. It points instead at the examples directory, which is a separate Maven project: go into examples, run mvn eclipse:eclipse, import the project into Eclipse, change the login details (address, username and password) in the example classes, and run them. Treat those classes as the first real use rather than writing a session from scratch. Before that, confirm the runtime: the README lists Java 8 or higher, SLF4J 2.0.0 and Bouncy Castle as dependencies. One detail from the 0.39.0 release history is worth knowing because it changes your dependency tree: that release removed the hard dependency on Bouncy Castle, making it optional.

If you build sshj from source instead, the README gives ./gradlew clean build and asks for Java 6 with the unlimited strength JCE installed, which reflects the age of that instruction rather than the current dependency list.

## Host key verification is a decision you have to make

The README lists reading known_hosts files for host key verification as a feature, and separately lists a PromiscuousVerifier, which is the class people search for by name. The two are opposites. A known_hosts-backed verifier rejects a host whose key has changed; a promiscuous verifier accepts whatever key the server presents. The library ships both, and nothing in the README tells you which to use. That is a design choice with a security consequence, and it is the first thing to get right in a code review.

The second constraint is runtime-specific. The README states that SSH agent authentication over the SSH_AUTH_SOCK unix-domain socket supports RSA, ECDSA, Ed25519 and FIDO/U2F keys, but the built-in unix-domain socket transport requires a Java 16 or higher runtime. On older runtimes you must supply your own AgentConnection implementation. If your service runs on Java 8 or 11 and depends on agent auth, you are writing that adapter yourself. The README does not document a bundled alternative.

A third limitation is version-related and explicit. The README carries a warning that SSHJ versions up to and including 0.37.0 are vulnerable to CVE-2023-48795, the Terrapin attack, and instructs users to upgrade to 0.38.0 or higher. Any project pinned below 0.38.0 has a known protocol-level weakness, and the fix is an upgrade, not a configuration flag.

## Where sshj sits next to JSch and Apache MINA SSHD

The two names that come up in the related searches are JSch and Apache MINA SSHD, and the difference is mostly about what each project chooses to be. JSch is the older client library that many Java projects still depend on; sshj covers the same client ground with a different algorithm registry and a different API surface, and it is the one whose README documents FIDO/U2F security keys, RFC 8308 extension negotiation and SSH_AUTH_SOCK agent support in the same place. If your current code is on JSch and you need any of those three, the migration is the point of the change.

Apache MINA SSHD is a different shape of project. It is a full SSH implementation that can act as a server as well as a client, with its own I/O layer. sshj is client-side: the README describes command, subsystem and shell channels, port forwarding, scp and SFTP, all from the connecting side. If you need to accept inbound SSH connections in your JVM, sshj is not the tool, and no amount of configuration changes that. If you only need to connect outward, sshj is the smaller dependency.

The README itself links to an external SSH Implementation Comparison rather than arguing the case, which is a reasonable position: algorithm coverage is checkable, and the comparison page is where to check it.

## Release cadence, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-21. Releases 0.41.0 and 0.41.1 both landed on that day, with 0.40.0 on 2026-06-29. The README states that starting from version 0.40.0, release notes are published as GitHub Releases, and that the history inside the README covers releases up to and including 0.39.0. That is a documentation split worth remembering: if you are reading README.adoc for changelog detail, it stops at 0.39.0, and you need the GitHub Releases page for anything after.

The licence is Apache-2.0, and the repository carries LICENSE and NOTICE files at the top level, which is the usual arrangement for that licence. Nothing in the README adds terms beyond it. That is a statement about what the repository contains, not legal advice; if you redistribute sshj inside a product, read the LICENSE and NOTICE files yourself.

The upgrade cost is dominated by dependencies rather than API churn. The 0.39.0 notes list upgraded dependencies and the removal of the hard Bouncy Castle dependency, so a project that relied on sshj pulling Bouncy Castle transitively had to add it explicitly. The README lists SLF4J 2.0.0, which is a major-version line; a project still on SLF4J 1.x will feel that in its logging setup before it feels anything in the SSH code.

## What to verify before you commit to sshj

Check three things in order. First, your Java runtime: Java 8 or higher is the stated floor, but agent authentication over SSH_AUTH_SOCK needs Java 16 or higher unless you write your own AgentConnection. Second, your host key policy: decide between a known_hosts-backed verifier and PromiscuousVerifier before the first commit, because retrofitting verification after a service is in production is harder than starting with it. Third, your algorithm requirements: if you are connecting to an old appliance, confirm in the README's algorithm lists that the cipher, key exchange and MAC you need are present, including the extended non-official ones.

If all three check out, the examples directory is the fastest path to a working session, and the Maven coordinates above are the whole install. If any of them fails, the gap is usually a runtime version or a missing adapter rather than a missing feature.

## Conclusion

Adopt sshj when you need SSH, SCP or SFTP inside a JVM process and you want to control the algorithm set and the host key check yourself. Skip it if you want a managed daemon or a shell wrapper. Before writing code, confirm your runtime is Java 8 or higher, check that your build resolves com.hierynomus:sshj at 0.41.1, and decide explicitly how known_hosts or a PromiscuousVerifier will be wired.

## FAQ

### How do I add hierynomus/sshj to a Maven project?

Add a dependency with groupId com.hierynomus, artifactId sshj and the version you want, for example 0.41.1. The README notes that binary releases are not hosted in the repository but can be downloaded from Maven Central.

### Does hierynomus/sshj support SSH agent authentication?

Yes, over the SSH_AUTH_SOCK unix-domain socket, for RSA, ECDSA, Ed25519 and FIDO/U2F keys. The README states the built-in unix-domain socket transport requires a Java 16 or higher runtime, and on older runtimes you must supply your own AgentConnection implementation.

### Which Java version does hierynomus/sshj require?

The README lists Java 8 or higher as a dependency, alongside SLF4J 2.0.0 and Bouncy Castle. Some features raise that floor: agent authentication over the unix-domain socket needs Java 16 or higher.

### Is hierynomus/sshj affected by CVE-2023-48795?

The README warns that SSHJ versions up to and including 0.37.0 are vulnerable to CVE-2023-48795, the Terrapin attack, and instructs users to upgrade to 0.38.0 or higher.

### Can hierynomus/sshj act as an SSH server?

The README describes it as an SSHv2 library for Java covering command, subsystem and shell channels, port forwarding, scp and SFTP from the client side. Nothing in the README describes accepting inbound SSH connections.

## Sources

- [hierynomus/sshj on GitHub](https://github.com/hierynomus/sshj)
- [Issues](https://github.com/hierynomus/sshj/issues)
- [License: Apache-2.0](https://github.com/hierynomus/sshj/blob/master/LICENSE)
- [README](https://github.com/hierynomus/sshj/blob/master/README.md)
- [Releases](https://github.com/hierynomus/sshj/releases)

---

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