2011-07-28 208 views
3

我編寫FTPS服務器,並且我在AUTH TLS命令後有ssl連接問題。 簡單的例子:連接到FTPS服務器

try 
{ 
    int ServerPort = 21; 
    ServerSocket FtpExServer = new ServerSocket(ServerPort); 
    while(true) 
    { 
     Socket S = FtpExServer.accept(); 
     InputStreamReader ISR = new InputStreamReader(S.getInputStream()); 
     OutputStreamWriter OSW = new OutputStreamWriter(S.getOutputStream()); 
     BufferedReader ClientSocketReader = new BufferedReader(ISR); 
     PrintWriter ClientSocketWriter = new PrintWriter(OSW, true); 

     ClientSocketWriter.println("220 Welcome to FTP server."); 
     print(ClientSocketReader.readLine()); 
     ClientSocketWriter.println("234 AUTH TLS successful"); 

     char[] passphrase = "pass".toCharArray(); 
     char[] cpassphrase = "cpass".toCharArray(); 
     KeyStore keystore = KeyStore.getInstance("JKS"); 
     keystore.load(new FileInputStream("keystore.jks"), passphrase); 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
     kmf.init(keystore, cpassphrase); 
     SSLContext context = SSLContext.getInstance("TLS"); 
     KeyManager[] keyManagers = kmf.getKeyManagers(); 
     context.init(keyManagers, null, null); 
     SSLServerSocketFactory ssf = context.getServerSocketFactory(); 

     SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(990); 
       ss.setSoTimeout(2000);   
       SSLSocket s = (SSLSocket)ss.accept(); 

     ISR = new InputStreamReader(s.getInputStream()); 
     OSW = new OutputStreamWriter(s.getOutputStream()); 
     ClientSocketReader = new BufferedReader(ISR); 
     ClientSocketWriter = new PrintWriter(OSW, true); 

     ClientSocketWriter.println("234 AUTH TLS successful"); 
     print(ClientSocketReader.readLine()); 
     ClientSocketWriter.println("331 Password required for smie"); 
     print(ClientSocketReader.readLine()); 
     ClientSocketWriter.println("230 User smie logged in"); 
     print(ClientSocketReader.readLine()); 
     ClientSocketWriter.println("215 UNIX Type: L8"); 
     print(ClientSocketReader.readLine()); 
     ClientSocketWriter.println("550 Command not suported."); 
    } 
} 
catch(Exception e) 
{ 
    print(e); 
} 

描述:FTP客戶端(例如MoveITFreely)連接到服務器的端口21發送命令 「AUTH TLS」 之後,服務器發送 「234 AUTH TLS成功」。現在客戶端必須連接到端口990(?)上的服務器,但客戶端不連接並且獲取超時異常。

我做錯了什麼?

回答

7

存在兩種將SSL添加到FTP的方法。

第一種方法稱爲隱式SSL。這意味着服務器正在偵聽端口990,當客戶端連接到它時,首先執行SSL/TLS協商,然後將建立的連接用作通信的命令通道(對於數據通道SSL握手也在類似的方式)。

第二種方法是您嘗試使用的方法。它被稱爲顯式SSL。客戶端在端口21上連接,發送AUTH TLS並在現有連接上啓動SSL協商。數據通道可以安全或不安全,具體取決於您的需要(您可以使用PROT命令指定此通道)。

您混合了這些方法。我建議你在繼續閱讀之前閱讀detailed explanation in Wikipedia。然後閱讀RFC for explicit TLS

更新:你也需要SSLClientSocket,而不是SSLServerSocket。

+0

謝謝信息!告訴我如何從現有的Socket創建SSL連接? – smie

+1

@ user857923請參閱SSLSocketFactory.createSocket()方法(http://download.oracle.com/javase/1.4.2/docs/api/javax/net/ssl/SSLSocketFactory.html#createSocket(java.net.Socket,%) 20java.lang.String,%20int,%20boolean) –

+0

它的幫助!感謝Zenya! – smie