从java访问SMB2.1或SMB3共享?

由于Windows 2012R2不再支持SMB1协议而没有一些注册表黑客,在Java中只支持SMB2.1或SMB3的SMB共享中是否有任何成功? JCIFS库显然只是SMB1,所以它出来了。 我看到微软有一个用于Azure的Java库,但这似乎是利用服务而不是SMB。

我发现这个包可以用于SMB2和SMB3,名为smbj看看这个: https : //github.com/hierynomus/smbj

扩展@Breakidi答案,我刚刚在Android上使用了hierynomus/smbj v0.2.0并添加了SMB2支持。 它声称支持SMB2和SMB3,虽然类仅参考SMB2版本,但不确定,可能它是无关紧要的。

测试

我已经在一个案例中对运行SMB2的盒子进行了测试,然后SMB2和SMB3在另一个案例中打开。 我无法单独禁用SMB2并测试SMB3。

BouncyCastle的/ Spongycastle

在我的情况下需要使用Spongycastle(很可能是因为Android),因为类路径中缺少必需的MD4依赖。 我在class级中使用它连接到SMB:

 import org.spongycastle.jce.provider.BouncyCastleProvider; import java.security.Security; <...> static { Security.addProvider(new BouncyCastleProvider()); } 

正在上传文件

确保在DiskShare上调用openFile时设置正确的标志(通过查看源代码偏离过程):

 // required imports import com.hierynomus.msdtyp.AccessMask; import com.hierynomus.msfscc.FileAttributes; import com.hierynomus.mssmb2.SMB2CreateDisposition; import com.hierynomus.mssmb2.SMB2CreateOptions; import com.hierynomus.mssmb2.SMB2ShareAccess; import com.hierynomus.smbj.SMBClient; import com.hierynomus.smbj.SmbConfig; import com.hierynomus.smbj.auth.AuthenticationContext; import com.hierynomus.smbj.common.SMBApiException; import com.hierynomus.smbj.connection.Connection; import com.hierynomus.smbj.session.Session; import com.hierynomus.smbj.share.DiskShare; import com.hierynomus.smbj.share.File; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.HashSet; ... // connection params String sambaDomain = null; // can be null String sambaUsername = "iamuploader"; String sambaPass = "mysecret"; String sambaIP = "192.168.1.236"; String sambaSharedPath = "sharedfolder"; ... // upload method // usage: upload("file/whithin/folder.txt", fileBytes); public void upload(String filename, byte[] bytes) throws IOException { SmbConfig cfg = SmbConfig.builder().build(); SMBClient client = new SMBClient(cfg); Connection connection = client.connect(sambaIP); Session session = connection.authenticate(new AuthenticationContext(sambaUsername, sambaPass.toCharArray(), sambaDomain)); DiskShare share = (DiskShare) session.connectShare(sambaSharedPath); // this is com.hierynomus.smbj.share.File ! File f = null; int idx = filename.lastIndexOf("/"); // if file is in folder(s), create them first if(idx > -1) { String folder = filename.substring(0, idx); try { if(!share.folderExists(folder)) share.mkdir(folder); } catch (SMBApiException ex) { throw new IOException(ex); } } // I am creating file with flag FILE_CREATE, which will throw if file exists already if(!share.fileExists(filename)){ f = share.openFile(filename, new HashSet<>(Arrays.asList(AccessMask.GENERIC_ALL)), new HashSet<>(Arrays.asList(FileAttributes.FILE_ATTRIBUTE_NORMAL)), SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_CREATE, new HashSet<>(Arrays.asList(SMB2CreateOptions.FILE_DIRECTORY_FILE)) ); } if(f == null) return null; OutputStream os = f.getOutputStream(); os.write(bytes); os.close(); } 

Visuality Systems目前正在开发JNQ,它是基于Java的SMB,支持3.1.1。 由于该要求包含对Java 1.4的向后支持,因此开发进展缓慢。 SMB客户端将在即将到来的夏天的某个地方推出,服务器将在稍后推出。

当使用hierynomus / smbj v0.3.0时,我得到类似“ ClassNotFoundException: sun.security.provider.MD4 ”的exception,然后我使用以下代码来解决问题。

 SmbConfig cfg = SmbConfig.builder(). withMultiProtocolNegotiate(true). withSecurityProvider(new JceSecurityProvider(new BouncyCastleProvider())). build(); SMBClient client = new SMBClient(cfg);