2010-03-24 70 views
3

我試圖向學生說明如何在java中使用https。但我有我的感覺我的例子是不是真的是最好的那裏...java中的HTTPS最終會出現奇怪的結果

該代碼適用於我的Windows 7:我啓動服務器,去https:// localhost:8080/somefile.txt我被要求信任證書,一切順利。 當我嘗試http(在接受證書之前或之後)我只是得到一個空白頁面,這對我來說沒問題。

但是當我在Windows XP上嘗試完全相同的東西時:同樣的事情,一切順利。但之後(首先接受證書後),我也可以通過http獲得所有文件! (如果我第一次嘗試HTTPHTTPS隨後接受證書,我沒有得到任何回答。)

我想提神,提神難一萬倍,但是這不應該是工作的,對不對?

我的代碼有什麼問題嗎?我不知道如果我用正確的方法來實現在這裏... HTTPS

package Security; 

import java.io.*; 
import java.net.*; 
import java.util.*; 
import java.util.concurrent.Executors; 
import java.security.*; 

import javax.net.ssl.*; 

import com.sun.net.httpserver.*; 


public class HTTPSServer 
{ 
    public static void main(String[] args) throws IOException 
    { 
     InetSocketAddress addr = new InetSocketAddress(8080); 
     HttpsServer server = HttpsServer.create(addr, 0); 

     try 
     { 
      System.out.println("\nInitializing context ...\n"); 
      KeyStore ks = KeyStore.getInstance("JKS"); 
      char[] password = "vwpolo".toCharArray(); 
      ks.load(new FileInputStream("myKeys"), password); 
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
      kmf.init(ks, password); 
      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(kmf.getKeyManagers(), null, null); 

      // a HTTPS server must have a configurator for the SSL connections. 
      server.setHttpsConfigurator (new HttpsConfigurator(sslContext) 
      { 
       // override configure to change default configuration. 
       public void configure (HttpsParameters params) 
       { 
        try 
        { 
         // get SSL context for this configurator 
         SSLContext c = getSSLContext(); 

         // get the default settings for this SSL context 
         SSLParameters sslparams = c.getDefaultSSLParameters(); 

         // set parameters for the HTTPS connection. 
         params.setNeedClientAuth(true); 
         params.setSSLParameters(sslparams); 
         System.out.println("SSL context created ...\n"); 
        } 
        catch(Exception e2) 
        { 
         System.out.println("Invalid parameter ...\n"); 
         e2.printStackTrace(); 
        } 
       } 
      }); 
     } 
     catch(Exception e1) 
     { 
      e1.printStackTrace(); 
     } 

     server.createContext("/", new MyHandler1()); 
     server.setExecutor(Executors.newCachedThreadPool()); 
     server.start(); 
     System.out.println("Server is listening on port 8080 ...\n"); 
    } 
} 

class MyHandler implements HttpHandler 
{ 
    public void handle(HttpExchange exchange) throws IOException 
    { 
     String requestMethod = exchange.getRequestMethod(); 
     if (requestMethod.equalsIgnoreCase("GET")) 
     { 
      Headers responseHeaders = exchange.getResponseHeaders(); 
      responseHeaders.set("Content-Type", "text/plain"); 
      exchange.sendResponseHeaders(200, 0); 

      OutputStream responseBody = exchange.getResponseBody(); 
      String response = "HTTP headers included in your request:\n\n"; 
      responseBody.write(response.getBytes()); 

      Headers requestHeaders = exchange.getRequestHeaders(); 
      Set<String> keySet = requestHeaders.keySet(); 
      Iterator<String> iter = keySet.iterator(); 
      while (iter.hasNext()) 
      { 
       String key = iter.next(); 
       List values = requestHeaders.get(key); 
       response = key + " = " + values.toString() + "\n"; 
       responseBody.write(response.getBytes()); 
       System.out.print(response); 
      } 

      response = "\nHTTP request body: "; 
      responseBody.write(response.getBytes()); 
      InputStream requestBody = exchange.getRequestBody(); 
      byte[] buffer = new byte[256]; 
      if(requestBody.read(buffer) > 0) 
      { 
       responseBody.write(buffer); 
      } 
      else 
      { 
       responseBody.write("empty.".getBytes()); 
      } 

      URI requestURI = exchange.getRequestURI(); 
      String file = requestURI.getPath().substring(1); 
      response = "\n\nFile requested = " + file + "\n\n"; 
      responseBody.write(response.getBytes()); 
      responseBody.flush(); 
      System.out.print(response); 

      Scanner source = new Scanner(new File(file)); 
      String text; 
      while (source.hasNext()) 
      { 
       text = source.nextLine() + "\n"; 
       responseBody.write(text.getBytes()); 
      } 
      source.close(); 

      responseBody.close(); 

      exchange.close(); 
     } 
    } 
} 
+0

這聽起來像一個瀏覽器問題。你使用什麼瀏覽器版本? – stevedbrown 2010-03-25 21:33:14

+1

我沒有看到任何代碼檢查連接是否安全。因此,您正在使用您正在使用的API和該瀏覽器中的某些默認設置來執行您想要的操作。更好的想法是檢查連接是否安全,或禁用非SSL連接。 – malaverdiere 2010-03-26 05:03:02

+0

我也一直在考慮這個問題(在一個只有SSL服務器的例子中,我嘗試了一些不同的(SSL,非SSL)客戶端;服務器接受了連接,但之後才崩潰) 檢查連接是否安全? (或者如何禁用非SSL連接?) – Senne 2010-03-26 09:09:12

回答

1

如果你只想做一個演示給學生,那麼我建議避免的花裏胡哨成熟的HTTP服務器正在運行。

我只是一個SSLServerSocket提供一個默認的HTML頁面,只要安全連接成功。