B4J Library SSHJ - ssh, scp, sftp for Java

This is a wrapper for: https://github.com/hierynomus/sshj

Dependencies:
#AdditionalJar: slf4j-api-1.7.25
#AdditionalJar: sshj-0.23.0
#AdditionalJar: eddsa-0.2.0
#AdditionalJar: bcprov-jdk15on-159



You can download this libraries from:
slf4j-api-1.7.25: https://mvnrepository.com/artifact/org.slf4j/slf4j-api
sshj-0.23.0: https://mvnrepository.com/artifact/com.hierynomus/sshj
eddsa-0.2.0: https://mvnrepository.com/artifact/net.i2p.crypto/eddsa
(B4J) bcprov-jdk15on-159: https://www.bouncycastle.org/latest_releases.html
(B4A) prov-1.58.0.0.jar: https://mvnrepository.com/artifact/com.madgag.spongycastle/prov

*NOTE1* I tested this only with B4J, it should work for Android too!
*NOTE2* Also when running in Release you should set #MergeLibraries: False because of the bouncy castle dependency (bcprov-jdk15on-159) which is a signed jar, and when running with #MergeLibraries: True that jar is decompiled and compiled in your jar and therefore losses its signing.
*NOTE3* For Android you need to download spongy castle instead of bouncy castle. You can download it from https://mvnrepository.com/artifact/com.madgag.spongycastle/prov. I don't know if NOTE2 applies in this case.

First steps:
B4X:
    Dim ssh As SSHJ
    ssh.Initialize("ssh")
    '...... or ......
    ssh.Initialize2("ssh", 15) ' where 15 is the KeepAliveInterval - usefull for portforward and future sftp.
As connecting through ssh to a server wants to mean that is secure you have to add the server hostkey:
B4X:
ssh.LoadKnownHosts 'loads the known_hosts file from some default locations.
'or
ssh.LoadKnownHosts2("/tmp/known_hosts")
'or
ssh.AddHostKeyVerifier("SHA1:2Fo8c/96zv32xc8GZWbOGYOlRak=")
'or finnaly if you really trust the server and do not want to verify it's key
ssh.AddHostKeyPromiscuousVerifier
Next step is the authentication. You can supply multiple authentication methods:
B4X:
ssh.AddAuthPassword("youruserpass")
'or/and
ssh.AddAuthPublicKey("/location/to/my/key", "null if not encrypted")
'or/and
ssh.AddAuthPublicKey2("key-key-key-key...", "empty string if public key is in private key string", "null if not encrypted")
Finnaly now we connect:
B4X:
ssh.Connect("hostname/ip", 22, "yourusername")

All the execution methods (read details in ide) - Exec, Shell, SCPUpload, SCPDownload, LocalPortforwarder, RemotePortForwarder and all methods of SFTPClient - are async and work with Wait For feature of B4X.

Like always if you encounter problems i will do my best to help, but I'm no expert!

Edit by Erel: You need to add this line for it to work with the built-in packager:
B4X:
#PackagerProperty: VMArgs = --add-opens b4j/org.bouncycastle.jcajce.provider.asymmetric.ec=java.base
 

Attachments

  • SSHJ-v1.40.zip
    46.8 KB · Views: 594
Last edited by a moderator:

JackKirk

Well-Known Member
Licensed User
Plase help me!
My project run in debug mode good, but release mode run with error:

net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1]

I am way out of my depth here but have been using this library with success in a different context.

Just an observation - your problem seems to be similar to:
https://www.b4x.com/android/forum/threads/sshj-ssh-scp-sftp-for-java.88615/page-3#post-619235
(post 47 above)

Reading through subsequent posts it looks like the problem was solved at post 54 - although you might choke on using really old code.
 

Gandalf

Member
Licensed User
Just in case someone is annoyed by these errors:
B4X:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
This can be solved by downloading appropriate SLF4J version, extracting file slf4j-nop-1.7.25.jar to your Additional Libraries folder and putting
B4X:
#AdditionalJar: slf4j-nop-1.7.25.jar
into Region Project Attributes.
 

JackKirk

Well-Known Member
Licensed User
Last edited:

roerGarcia

Active Member
Licensed User
Sure

upload_2019-10-16_15-56-45.png

In this image, why the name of the object sftp (small caps) is not the same of the event SFTPUploadFinished (capitals) ?

is there any difference? What event should it be called? Is it coded? (Google Translated from spanish)
 

mindful

Active Member
Licensed User
If you initialize SSHJ without an event name (.Initialize("")) then you need to use WaitFor as you can see in the photo.

If you initialize SSHJ with an event name (.Initialize("ssh")) then when ftp upload is finished the SFTPUploadFinished event will be called (you need to have a sub named ssh_SFTPUploadFinished) ... type Public Sub -> Space -> a tooltip appears with the text "Press tab to insert event declaration" -> tab -> Now a list appears -> Find SSHJSFTPClient -> enter -> and a list of events appear -> choose what you need !
 

roerGarcia

Active Member
Licensed User
Thanks a lot!!!
Finally, this thing works as expected (in my mind ...)

I learned something today.

PD. and.... why the sub ssh SFTP Upload finished
does not seem to be executed ?
 
Last edited:

FrancescoS

Member
Licensed User
Hi mindful, great work, thanks !
Where can I find the list of all events that are handled if I use the 'Initialize ("ssh")' mode?
Thanks
 
Top