掘金 后端 ( ) • 2024-05-08 07:01

HTTP(Hypertext Transfer Protocol)和HTTPS(HTTP Secure)是用于web通信的协议。HTTP是一个无状态的协议,不加密传输的数据,使得它在数据传输过程中可能会被截获或篡改。而HTTPS是HTTP的安全版本,它通过SSL(Secure Sockets Layer)或TLS(Transport Layer Security)加密HTTP数据传输,提供数据完整性,确保数据加密和安全传输,防止被截获的数据被读取。

HTTP 示例

以下是一个用Java编写的简单HTTP服务器示例,使用了Java SE内置的com.sun.net.httpserver.HttpServer类。请注意,为了运行以下代码,你需要有JDK(Java Development Kit)安装在你的机器上。

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class SimpleHttpServer {
    public static void main(String[] args) throws IOException {
        int port = 8080;
        HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
        server.createContext("/", new MyHandler());
        server.setExecutor(null); // 使用默认执行器
        server.start();
        System.out.println("Server is listening on port " + port);
    }
    
    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            String response = "Welcome to the Simple HTTP Server!";
            exchange.sendResponseHeaders(200, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

运行这段代码会启动一个在8080端口监听的简单HTTP服务器。当你访问http://localhost:8080时,它会返回一条欢迎信息。

HTTPS 示例

接下来是一个使用Java创建HTTPS服务器的示例。这涉及到密钥库(keystore)的创建和管理,因为你需要一个服务器证书来建立SSL连接。

首先,你需要生成一个密钥库和自签名的证书。你可以使用keytool来完成,这是一个随Java JDK一起安装的工具。下面是生成密钥库的命令行示例:

keytool -genkeypair -alias example -keyalg RSA -validity 365 -keystore keystore.jks

这条命令会要求你输入keystore的密码和证书的相关信息。完成后,你将得到一个名为keystore.jks的密钥库文件。

下面是用Java编写的简单HTTPS服务器的代码:

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpsServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.io.FileInputStream;

public class SimpleHttpsServer {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        int port = 8443;
        String keystoreFilename = "keystore.jks";
        char[] storepass = "password".toCharArray();
        char[] keypass = "password".toCharArray();
        String alias = "example";

        HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 0);
        SSLContext sslContext = SSLContext.getInstance("TLS");

        // 初始化keystore
        KeyStore ks = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream(keystoreFilename);
        ks.load(fis, storepass);
        fis.close();

        // 设置key manager factory
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, keypass);

        // 设置trust manager factory
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(ks);

        // 使用key manager和trust manager设置SSLContext
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        server.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
            public void configure(HttpsParameters params) {
                try {
                    // 初始化SSL context
                    SSLContext c = getSSLContext();
                    SSLParameters sslparams = c.getDefaultSSLParameters();
                    params.setSSLParameters(sslparams);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.out.println("Failed to create HTTPS server");
                }
            }
        });

        server.createContext("/", new MyHandler());
        server.setExecutor(null); // 使用默认执行器
        server.start();
        System.out.println("Server is listening on port " + port);
    }
    
    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            String response = "Welcome to the Simple HTTPS Server!";
            exchange.sendResponseHeaders(200, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

运行以上代码将启动一个在8443端口监听的HTTPS服务器。当你访问https://localhost:8443时,你的浏览器可能会警告你证书不可信,这是因为它是自签名的。如果你接受风险并继续,你将看到返回的欢迎信息。

请注意,为了简化代码展示,以上示例中省略了错误处理和日志记录,这在生产环境中是必不可少的。此外,使用com.sun.*包中的类在生产级代码中通常不推荐,因为这些类在Java的不同版本中并不总是可用,而且它们不是Java标准API的一部分。在生产环境中,你可能会使用更成熟的框架和库,如Spring Framework,它提供了全面的HTTP和HTTPS支持。

HTTP(超文本传输协议)和HTTPS(安全超文本传输协议)主要有以下区别:

  1. 加密:

    • HTTP: 不加密,数据以明文形式传输,因此任何截获流量的第三方都可以看到数据内容。
    • HTTPS: 通过SSL或TLS协议对数据进行加密,只有客户端和服务器可以解密和访问信息,提供了数据传输的保密性。
  2. 端口号:

    • HTTP: 默认使用80端口。
    • HTTPS: 默认使用443端口。
  3. 安全性:

    • HTTP: 没有建立安全通道的能力,更容易受到中间人攻击(MITM),数据可能被窃听、篡改或伪造。
    • HTTPS: 通过SSL/TLS协议创建安全通道,在客户端和服务器之间建立信任,可以有效防范中间人攻击。
  4. 性能:

    • HTTP: 由于不需要进行加密和解密的过程,HTTP的性能通常比HTTPS要好。
    • HTTPS: 加密和解密过程需要消耗额外的服务器资源和时间,尽管现代硬件对此的优化已经减少了这种影响。
  5. URL前缀:

    • HTTP: 网址以http://开始。
    • HTTPS: 网址以https://开始。
  6. SSL证书:

    • HTTP: 不需要SSL证书。
    • HTTPS: 需要SSL证书来验证服务器的身份,并且这些证书通常由第三方权威机构(CA)签发。
  7. 搜索引擎优化(SEO):

    • HTTP: 没有HTTPS提供的安全增强,可能会被搜索引擎判定为不安全,这可能影响网站的搜索排名。
    • HTTPS: 被搜索引擎视为一个积极的排名信号,有助于提升网站的SEO表现。
  8. 隐私:

    • HTTP: 由于传输的数据未加密,个人隐私可能会暴露。
    • HTTPS: 提供了更强的隐私保护,因为传输的数据被加密。

简而言之,HTTPS可以被看作是HTTP的安全版。尽管HTTPS在性能上可能稍微有所牺牲,但它提供的安全性和数据保护远远超过了这点小的代价。如今,越来越多的网站和在线服务采用HTTPS,来确保用户数据的安全和隐私。