我决的他和你的程序无关,关键是服务器的配置和安装证书,证书如果要verisign的正式的肯定要话银子,可以自己颁发或着下个测试用的,就是不被信任。个个服务器的ssl培植不一样,你必须参考服务器的手册说明,比如apache可以下在ssl_mol和ssl_apache,是免费的,也有负费的,这些东西都有相关的安装配置说明,主要是 你的服务器种类。

解决方案 »

  1.   

    不需要实现,只需要配置一下服务器,具体的可参见Tomcat SSL Howto。
      

  2.   

    是这样,服务器是自己用java编写的。先肯定是用免费的来实现,也就是自己颁发的这种。
    我也用JDK的keytool程序生成了一个文件,但不知怎么用?
      

  3.   

    如果是tomcat的话,你可以到Apache的网站看看。很简单的
    如果用JDK1.4就很简单的,删掉server.xml里面的一段注释就可以了
      

  4.   

    to ChDw(米):
       能更详细点吗,如果用JDK的话。
      

  5.   

    如果你用JDK1.4,你可以先用它提供的keytool产生一个.keystore文件
    然后在tomcat4.0的conf目录中的server.xml找到文字
     <!-- Define an SSL HTTP/1.1 Connector on port 8443 -->
    然后把原有的注释去掉,使到
        <Connector className="org.apache.catalina.connector.http.HttpConnector"
                   port="8443" minProcessors="5" maxProcessors="75"
                   enableLookups="true"
           acceptCount="10" debug="0" scheme="https" secure="true">
          <Factory className="org.apache.catalina.net.SSLServerSocketFactory"
                   clientAuth="false" protocol="TLS"/>
        </Connector>
    生效,然后重新启动tomcat就可以了,默认断口是8443
      

  6.   

    我有不明白处:
      用keytool生成的key文件放在服务器端,还是分发给客户端?我需要的是仅对客户端进行安全认证。
      

  7.   

    其实,我是自己用java来编写服务器的,但我想跟TOMCAT等服务器配置的原理是一样的。
    但,我还是没明白,服务器是怎样来验证客户端的连接是否合法允许?
      

  8.   

    我再说几句,我是想用RSA算法来认证,它有密钥和公钥。
    但不知道它怎么生成?和SSL怎么联上?
      

  9.   

    呵呵,你要自己写Web服务器+SSL功能?这个就比较有难度了,建议先看看SSL的文档+Tomcat的源代码+JSSE文档。
    keytool除了生成公匙私匙外还要生成证书,这些都在服务器端,客户连接时会得到服务器的证书,其中包括服务器的公匙。
    一般的SSL不是来验证客户端连接是否合法的,而是让客户端验证服务器是合法的,(这个通过证书来实现),并保证客户端与服务器连接的安全。
      

  10.   

    tojimjxr(宝宝猫) :
      客户端怎么去验证服务器是合法的?证书?哪它怎么知道这证书是合法的?
      即使知道这证书是否合法,那假如其它人也用该证书,客户端怎么区别出他不是合法用户?
      

  11.   

    ssl是保证信息传输是加密的,不会被别人半路截到解密,而不是用来对客户端就行认证的。你搞错了吧!
      

  12.   

    一个普通的webserver,只支持GET方法:
    <BLOCKQUOTE><FONT SIZE="2" class=c face="Verdana, Arial">code:</font><HR><pre>
    import java.net.*;
    import java.io.*;
    import java.util.*;// Small, simple HTTP server
    public class HTTPServer {
    String NAME;
    String VERSION;
    int serverPort;// No command line parameters are required
    public static void main(String args[]){
    HTTPServer server = new HTTPServer("HTTPServer", "1.0", 80);
    server.run();
    }
    // Create an HTTPServer for a particular TCP port
    public HTTPServer(String name, String version, int port) {
    this.NAME = name;
    this.VERSION = version;
    this.serverPort = port;
    }
    // Display name and version number
    public void displayVersionInfo(){
    System.out.println(NAME+" version "+VERSION);
    }
    // Run until interrupted
    public void run() {
    displayVersionInfo();
    try {
    // Get a server socket
    ServerSocket server = getServerSocket();
    int localPort = server.getLocalPort();
    // Let us know that you're listening
    System.out.println(NAME+" is listening on port "+localPort+".");
    do {
    // Accept a connection
    Socket client = server.accept();
    // Handle the connection with a separate thread
    (new HTTPServerThread(client)).start();
    } while(true);
    } catch(Exception ex) {
    System.out.println("Unable to listen on "+serverPort+".");
    ex.printStackTrace();
    System.exit(1);
    }
    }
    // Get a server socket on the hard-wired server port
    ServerSocket getServerSocket() throws Exception {
    return new ServerSocket(serverPort);
    }
    }// Handle a single server connection
    class HTTPServerThread extends Thread {
    Socket client;
    // Keep track of the client socket
    public HTTPServerThread(Socket client) {
    this.client = client;
    }
    // Thread entry point
    public void run() {
    try {
    // Display info about the connection
    describeConnection(client);
    // Create a stream to send data to the client
    BufferedOutputStream outStream = new 
    BufferedOutputStream(client.getOutputStream());
    HTTPInputStream inStream = new HTTPInputStream(client.getInputStream());
    // Get the client's request
    HTTPRequest request = inStream.getRequest();
    // Display info about it
    request.log();
    // Sorry, we only handle gets
    if(request.isGetRequest())
    processGetRequest(request,outStream);
    System.out.println("Request completed. Closing connection.");
    }catch(IOException ex) {
    System.out.println("IOException occurred when processing request.");
    }
    try {
    client.close();
    }catch(IOException ex) {
    System.out.println("IOException occurred when closing socket.");
    }
    }
    // Display info about the connection
    void describeConnection(Socket client) {
    String destName = client.getInetAddress().getHostName();
    String destAddr = client.getInetAddress().getHostAddress();
    int destPort = client.getPort();
    System.out.println("Accepted connection to "+destName+" ("
    +destAddr+")"+" on port "+destPort+".");
    }
    // Process an HTTP GET
    void processGetRequest(HTTPRequest request,BufferedOutputStream outStream)
    throws IOException {
    /* If you want to use this in a secure environment then you should place some 
    restrictions on the requested file name */
    String fileName = request.getFileName();
    File file = new File(fileName);
    // Give them the requested file
    if(file.exists()) sendFile(outStream,file);
    else System.out.println("File "+file.getCanonicalPath()+" does not exist.");
    }
    // A simple HTTP 1.0 response
    void sendFile(BufferedOutputStream out,File file) {
    try {
    DataInputStream in = new DataInputStream(new FileInputStream(file));
    int len = (int) file.length();
    byte buffer[] = new byte[len];
    in.readFully(buffer);
    in.close();
    out.write("HTTP/1.0 200 OK\r\n".getBytes());
    out.write(("Content-Length: " + buffer.length + "\r\n").getBytes());
    out.write("Content-Type: text/html\r\n\r\n".getBytes());
    out.write(buffer);
    out.flush();
    out.close();
    System.out.println("File sent: "+file.getCanonicalPath());
    System.out.println("Number of bytes: "+len);
    }catch(Exception ex){
    try {
    out.write(("HTTP/1.0 400 " + "No can do" + "\r\n").getBytes());
    out.write("Content-Type: text/html\r\n\r\n".getBytes());
    }catch(IOException ioe) {
    }
    System.out.println("Error retrieving "+file);
    }
    }
    }// Convenience class for reading client requests
    class HTTPInputStream extends FilterInputStream {
    public HTTPInputStream(InputStream in) {
    super(in);
    }
    // Get a line
    public String readLine() throws IOException {
    StringBuffer result=new StringBuffer();
    boolean finished = false;
    boolean cr = false;
    do {
    int ch = -1;
    ch = read();
    if(ch==-1) return result.toString();
    result.append((char) ch);
    if(cr && ch==10){
    result.setLength(result.length()-2);
    return result.toString();
    }
    if(ch==13) cr = true;
    else cr=false;
    } while (!finished);
    return result.toString();
    }
    // Get the whole request
    public HTTPRequest getRequest() throws IOException {
    HTTPRequest request = new HTTPRequest();
    String line;
    do {
    line = readLine();
    if(line.length()&gt;0) request.addLine(line);
    else break;
    }while(true);
    return request;
    }
    }// Used to process GET requests
    class HTTPRequest {
    Vector lines = new Vector();public HTTPRequest() {
    }
    public void addLine(String line) {
    lines.addElement(line);
    }
    // Is this a GET or isn't it?
    boolean isGetRequest() {
    if(lines.size() &gt; 0) {
    String firstLine = (String) lines.elementAt(0);
    if(firstLine.length() &gt; 0)
    if(firstLine.substring(0,3).equalsIgnoreCase("GET"))
    return true;
    }
    return false;
    }
    // What do they want to get?
    String getFileName() {
    if(lines.size()&gt;0) {
    String firstLine = (String) lines.elementAt(0);
    String fileName = firstLine.substring(firstLine.indexOf(" ")+1);
    int n = fileName.indexOf(" ");
    if(n!=-1) fileName = fileName.substring(0,n);
    try {
    if(fileName.charAt(0) == '/') fileName = fileName.substring(1);
    } catch(StringIndexOutOfBoundsException ex) {}
    if(fileName.equals("")) fileName = "index.htm";
    if(fileName.charAt(fileName.length()-1)=='/')
    fileName+="index.htm";
    return fileName;
    }else return "";
    }
    // Display some info so we know what's going on
    void log() {
    System.out.println("Received the following request:");
    for(int i=0;i&lt;lines.size();++i)
    System.out.println((String) lines.elementAt(i));
    }
    }
      

  13.   

    扩展这个Webserver,以支持SSL:
    <BLOCKQUOTE><FONT SIZE="2" class=c face="Verdana, Arial">code:</font><HR><pre>
    Extending the HTTP sever with SSL support.
    import java.net.*;
    import java.io.*;
    import java.util.*;
    import java.security.*;
    import javax.net.*;
    import javax.net.ssl.*;
    import com.sun.net.ssl.*;public class SecureServer extends HTTPServer {
    String KEYSTORE = "certs";
    char[] KEYSTOREPW = "serverkspw".toCharArray();
    char[] KEYPW = "serverpw".toCharArray();
    boolean requireClientAuthentication;public static void main(String args[]){
    SecureServer server = new SecureServer();
    server.run();
    }
    public SecureServer(String name, String version, int port, 
    boolean requireClientAuthentication) {
    super(name, version, port);
    this.requireClientAuthentication = requireClientAuthentication;
    }
    public SecureServer() {
    this("SecureServer", "1.0", 443, false);
    }
    ServerSocket getServerSocket() throws Exception {
    // Make sure that JSSE is available
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    // A keystore is where keys and certificates are kept
    // Both the keystore and individual private keys should be password protected
    KeyStore keystore = KeyStore.getInstance("JKS");
    keystore.load(new FileInputStream(KEYSTORE), KEYSTOREPW);
    // A KeyManagerFactory is used to create key managers
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    // Initialize the KeyManagerFactory to work with our keystore
    kmf.init(keystore, KEYPW);
    // An SSLContext is an environment for implementing JSSE
    // It is used to create a ServerSocketFactory
    SSLContext sslc = SSLContext.getInstance("SSLv3");
    // Initialize the SSLContext to work with our key managers
    sslc.init(kmf.getKeyManagers(), null, null);
    // Create a ServerSocketFactory from the SSLContext
    ServerSocketFactory ssf = sslc.getServerSocketFactory();
    // Socket to me
    SSLServerSocket serverSocket = 
    (SSLServerSocket) ssf.createServerSocket(serverPort);
    // Authenticate the client?
    serverSocket.setNeedClientAuth(requireClientAuthentication);
    // Return a ServerSocket on the desired port (443)
    return serverSocket;
    }
    }
      

  14.   

    客户端编程一个浏览普通站点的简易浏览器:
    <BLOCKQUOTE><FONT SIZE="2" class=c face="Verdana, Arial">code:</font><HR><pre>
    import java.io.*;
    import java.net.*;
    import java.security.*;// A simple text-based browser
    public class Browser {
    String urlString;// You must supply the URL to be browsed
    public static void main(String[] args) throws Exception {
    if(args.length != 1) {
    System.out.println("Usage: java Browser url");
    System.exit(1);
    }
    Browser browser = new Browser(args[0]);
    browser.run();
    }
    // Construct a browser object
    public Browser(String urlString) {
    this.urlString = urlString;
    }
    // Get the URL
    public void run() throws Exception {
    URL url = new URL(urlString);
    HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
    System.out.println("THE HEADERS");
    System.out.println("-----------");
    for(int i=1;;++i) {
    String key;
    String value;
    if((key = urlc.getHeaderFieldKey(i)) == null) break;
    if((value = urlc.getHeaderField(i)) == null) break;
    System.out.println("KEY: " + key);
    System.out.println("VALUE: " + value);
    }
    BufferedReader reader = new BufferedReader(
    new InputStreamReader(urlc.getInputStream()));
    String line;
    System.out.println("THE CONTENT");
    System.out.println("-----------");
    while((line = reader.readLine()) != null) System.out.println(line);
    }
    }
    [/code]
    扩展对SSL的支持:
    <BLOCKQUOTE><FONT SIZE="2" class=c face="Verdana, Arial">code:</font><HR><pre>
    import java.io.*;
    import java.net.*;
    import java.security.*;// Extend Browser to use SSL
    public class SecureBrowser extends Browser {
    // Must supply URL in command line
    public static void main(String[] args) throws Exception {
    if(args.length != 1) {
    System.out.println("Usage: java SecureBrowser url");
    System.exit(1);
    }
    SecureBrowser browser = new SecureBrowser(args[0]);
    browser.run();
    }
    // Construct a SecureBrowser
    public SecureBrowser(String urlString) {
    super(urlString);
    // Register JSSE
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
    // Here's the trick!
    // Simply set the protocol handler property to use SSL.
    System.setProperty("java.protocol.handler.pkgs",
    "com.sun.net.ssl.internal.www.protocol");
    }
    }
      

  15.   

    代码太长,只好分开贴了,其实里面有很多没用的,不过我也没空区分了。
    你自己拣着看吧 :)至于服务器配置,iis4.x和5.0的ssl配置是不一样的,apache倒没问题
      

  16.   

    客户端通过证书来确认服务器确实是所要连接的服务器,并得到其公共密匙。证书的合法性由颁发证书的CA保证,比如说verisign。证书是与服务器的地址相联系的,所以别人得到这个证书没用。
      

  17.   

    to grantdyg(正确) :
       非常感谢,我将会去消化一下你的代码。
    to jimjxr(宝宝猫) :
       证书是与服务器的地址相联系的,那就是说被确认方的IP地址是不能变的?另外,我自己能作证书吗?不通过由颁发证书的CA。
      

  18.   

    很感谢大家的关心!
    我提示一下我要解决的问题:
    我要做一个在HTTP1.1协议基础上的服务器(并不是网站,仅在HTTP上传数据),但要保证此服务器的安全,仅让允许的客户端得到它的服务,而客户端可以假定服务器是确认的,不需对服务器认证。
    我看了一些文章,说SSL能保证网络的安全,但还不晓得怎么跟我的问题挂上。
      

  19.   

    你的服务器是ssl的,要访问你的网页当然需要认证。ssl实际上是http与tcp之间加的一层,它的安全性在于加密http请求,可以说是防窃听的,缺省情况下只进行server端的认证,客户端只要确认你的证书就可以访问。但是像你说的仅让允许的客户端得到服务,你再找找看吧 :)
      

  20.   

    ssl是对传输的数据加密,你可以看一下加密的概念加密和认证是不同的两件事情,但是加密是大部分安全事务的基础,包括认证你的问题一句话就能解决:你可以采用应用层认证,也就是自己编程解决为了防止明文发送你的认证信息,使用ssl,就这么简单