在當今的互聯網時代,信息傳播的速度和互動的便捷性為我們的生活帶來了極大的便利。然而,隨之而來的數據安全與個人隱私保護問題也變得尤為緊迫。在這樣的背景下,HTTPS協議的普及已成為大勢所趨。
與傳統的HTTP相比,HTTPS在網站地址前綴的使用,為用戶與網站之間構建了一道堅固的安全屏障。本文將從安全性、信任度、合規性、性能及未來發展等多個方面,深入探討為什么越來越多的網站選擇以HTTPS開頭,而不是HTTP。
超文本傳輸協議(HTTP)是互聯網中最廣泛使用的協議之一,其主要工作方式是明文傳輸數據,這使得數據在傳輸過程中容易被監聽、截取和篡改。這種情況在處理如用戶名、密碼和信用卡號等敏感信息時,構成了嚴重的安全風險。
相比之下,HTTPS協議通過在HTTP上增加SSL/TLS加密,保障了數據在傳輸過程中的安全。SSL/TLS協議利用公鑰和私鑰的非對稱加密技術,以及會話密鑰的對稱加密技術,為數據包提供了強有力的加密保護。
HTTPS不僅提供數據加密,還包含重要的身份驗證功能。網站在啟用HTTPS時,必須從權威的證書頒發機構(CA)獲取SSL證書。該證書包含了網站的身份信息并經過數字簽名,確保用戶訪問的網站是真實可信的,而非假冒站點。
使用HTTPS的網站在搜索結果中的排名可能會優于HTTP網站。這不僅提升了網站的安全性,還間接提高了網站的搜索引擎可見度,吸引更多流量。
過去,由于加密過程可能導致頁面加載速度減慢,HTTPS被視為影響性能的因素。但隨著技術的進步,如HTTP/2、HTTP/3協議的引入以及TLS 1.3的高效加密算法,HTTPS的性能劣勢已大大縮小。甚至在某些情況下,得益于協議優化和瀏覽器預加載機制,HTTPS的性能表現優于HTTP。
綜上所述,網站選擇以HTTPS開頭而非HTTP,是互聯網發展至今的必然結果。HTTPS不僅確保數據安全傳輸,還在構建信任、優化搜索引擎排名、符合法規要求、提升用戶體驗以及適應技術發展趨勢等方面具有重要意義。
下面就從代碼實戰方向,詳述一下Java中如何實現HTTPS服務端、客戶端、簽名證書。
打開命令行工具(CMD 或終端),運行以下命令生成自簽名證書:
keytool -genkeypair -alias test -keyalg RSA -keysize 2048 -validity 365 -storetype PKCS12 -keystore test.p12 -storepass password
在運行上述命令時,您會被提示輸入一些信息,如下:
What is your first and last name? [Unknown]: Your NameWhat is the name of your organizational unit? [Unknown]: Your Organizational UnitWhat is the name of your organization? [Unknown]: Your OrganizationWhat is the name of your City or Locality? [Unknown]: Your CityWhat is the name of your State or Province? [Unknown]: Your StateWhat is the two-letter country code for this unit? [Unknown]: USIs CN=Your Name, OU=Your Organizational Unit, O=Your Organization, L=Your City, ST=Your State, C=US correct? [no]: yes
按照提示輸入相關信息,完成后自簽名證書將生成在 test.p12
文件中。
這個錯誤通常表示密鑰庫文件格式或其內容有問題。以下是一些可能的解決方案:
如果不想每次都手動輸入這些信息,可以在命令中使用 -dname 參數指定這些信息。例如:
keytool -genkeypair -alias test -keyalg RSA -keysize 2048 -validity 365 -keystore test.p12 -storetype PKCS12 -storepass password -dname "CN=Your Name, OU=Your Organizational Unit, O=Your Organization, L=Your City, ST=Your State, C=CN"
這個錯誤表明 test.p12 文件已經存在,但其中沒有內容。可能是在之前的嘗試中創建了這個文件,但沒有成功寫入任何數據。以下是解決方案:
刪除現有的空文件并重新生成
不需要在執行 keytool 命令之前手動創建 test.p12 文件。keytool 命令會自動生成并創建這個文件。如果 test.p12 文件已經存在,keytool 會更新這個文件中的密鑰對和證書。
刪除文件后,提示我keytool 錯誤: java.io.FileNotFoundException: test.p12 (拒絕訪問。)
確認當前用戶有權限
確保當前用戶對相關目錄和文件具有讀寫權限。如果您在 Windows 上運行命令提示符或在 Unix/Linux 系統上運行終端,嘗試使用管理員權限。
以超級用戶身份運行終端
在生成了自簽名證書之后,可以將其用于您的 HTTPS 服務器配置中。
使用生成的自簽名證書配置一個本地 HTTPS 服務器。
import com.sun.net.httpserver.HttpExchange;import com.sun.net.httpserver.HttpHandler;import com.sun.net.httpserver.HttpsConfigurator;import com.sun.net.httpserver.HttpsServer;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManagerFactory;import java.io.FileInputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.InetSocketAddress;import java.security.KeyStore;public class LocalHttpsServer { public static void main(String[] args) throws Exception { // 加載密鑰庫 char[] passphrase = "password".toCharArray(); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream("C://Program Files//Java//jdk1.8.0_60//bin//test.p12"), passphrase); // 初始化密鑰管理器工廠 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); // 初始化信任管理器工廠 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); // 初始化 SSL 上下文 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); // 創建 HTTPS 服務器 HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(8443), 0); httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); // 創建處理器 httpsServer.createContext("/api", new HttpHandler() { @Override public void handle(HttpExchange exchange) { try { if ("POST".equals(exchange.getRequestMethod()) && "application/json".equals(exchange.getRequestHeaders().getFirst("Content-Type"))) { InputStream is = exchange.getRequestBody(); StringBuilder jsonString = new StringBuilder(); int i; while ((i = is.read()) != -1) { jsonString.append((char) i); } System.out.println("Received JSON: " + jsonString.toString()); String response = "{/"message/":/"Received/"}"; exchange.getResponseHeaders().set("Content-Type", "application/json"); exchange.sendResponseHeaders(200, response.getBytes().length); OutputStream os = exchange.getResponseBody(); os.write(response.getBytes()); os.close(); } else { exchange.sendResponseHeaders(405, -1); // Method Not Allowed } } catch (Exception e) { e.printStackTrace(); } } }); // 啟動服務器 httpsServer.setExecutor(null); httpsServer.start(); System.out.println("HTTPS server started at https://localhost:8443/api"); }}
創建好 HTTPS 服務器后,您可以使用以下 Java 客戶端進行測試:
import javax.net.ssl.*;import java.io.OutputStream;import java.io.InputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.URL;import java.security.cert.X509Certificate;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;public class HttpsPostJsonClient { public static void main(String[] args) { String httpsURL = "https://localhost:8443/api"; String jsonInputString = "{/"param1/":/"value1/",/"param2/":/"value2/"}"; try { // 信任所有證書 TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) { return true; } }); // 創建 URL 對象 URL url = new URL(httpsURL); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); // 設置請求方法為 POST connection.setRequestMethod("POST"); // 允許寫入和讀取數據 connection.setDoOutput(true); connection.setDoInput(true); // 設置請求頭 connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); // 發送 POST 數據 try (OutputStream os = connection.getOutputStream()) { byte[] input = jsonInputString.getBytes("UTF-8"); os.write(input, 0, input.length); } // 讀取響應 try (InputStream is = connection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("Response: " + response.toString()); } } catch (Exception e) { System.out.println("exceptinotallow===: " + e); } }}
curl -X POST https://localhost:8443/api -H "Content-Type: application/json" -d '{"param1":"value1","param2":"value2"}' -k
通過上述步驟,您可以生成自簽名證書,并使用 Java 創建一個本地 HTTPS 服務器,接收 application/json 的 POST 請求,并通過 Java 客戶端進行測試。
HTTP 405 錯誤表示 "Method Not Allowed",即服務器端拒絕了請求方法。由于我們在示例中設定了服務器僅接受 POST 請求,如果客戶端發送了其他方法(例如 GET),服務器會返回 405 錯誤。
我們需要確保客戶端代碼確實發送了 POST 請求,并且服務器端處理程序正確設置。
我是因為設置請求頭時,寫的connection.setRequestProperty("Content-Type", "application/json; utf-8");,將其改為connection.setRequestProperty("Content-Type", "application/json");就解決了。
本文鏈接:http://www.tebozhan.com/showinfo-26-100467-0.html既然有了HTTP,為什么還要HTTPS?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: Springboot如何通過配置來決定使用的Web容器
下一篇: Token無感知刷新前端