SSL (Secure Sockets Layer) 及其繼任者 TLS (Transport Layer Security) 是保障客戶端與服務端通信安全的標準協議。核心機制:
生產環境建議使用 CA 機構簽發證書(如 DigiCert、Let's Encrypt)。開發/測試環境可用自簽名證書,成本為零。以下所有操作在 F:\ca 目錄下進行,JDK 版本 1.7+。
keytool -genkeypair -v -alias server -keyalg RSA -validity 3650 \ -keystore ./server.keystore -storepass 123456 -keypass 123456 \ -dname "CN=127.0.0.1,OU=rm,O=rm,L=gz,ST=gd,C=cn"
關鍵點:CN 必須設置為服務端的 IP 或域名,否則客戶端驗證會失敗。
keytool -exportcert -alias server -keystore ./server.keystore \ -file ./server.cer -storepass 123456
keytool -importcert -alias serverca -keystore ./server_trust.keystore \ -file ./server.cer -storepass 123456
keytool -genkeypair -v -alias client -dname "CN=rorymo" -keyalg RSA \ -validity 3650 -keypass 123456 -keystore ./client.p12 \ -storepass 123456 -storetype PKCS12
keytool -exportcert -alias client -file ./client.cer \ -keystore ./client.p12 -storepass 123456 -storetype PKCS12
keytool -importcert -alias clientca -keystore ./server_trust.keystore \ -file ./client.cer -storepass 123456
keytool -list -keystore ./server_trust.keystore -storepass 123456
應看到 serverca 和 clientca 兩條受信任證書條目。
server.keystore 和 server_trust.keystore 複製到 Tomcat 根目錄(如 F:\ca\apache-tomcat-7.0.64)。conf/server.xml,在 <Service> 下添加 Connector:<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true" maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="${catalina.base}/server.keystore"
keystorePass="123456"
truststoreFile="${catalina.base}/server_trust.keystore"
truststorePass="123456" />
關鍵屬性解析:
clientAuth="true":啟用雙向認證(強制要求客戶端提供證書)。keystoreFile:服務端私鑰證書庫(含私鑰)。truststoreFile:服務端信任庫(含受信任的客戶端 CA 證書)。@WebServlet("/SSLServlet")
public class SSLServlet extends HttpServlet {
private static final String REQUEST_ATTR_CERT = "javax.servlet.request.X509Certificate";
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain;charset=UTF-8");
PrintWriter out = resp.getWriter();
X509Certificate[] certs = (X509Certificate[]) req.getAttribute(REQUEST_ATTR_CERT);
if (certs != null) {
out.println("檢測到 " + certs.length + " 個客戶端證書");
for (int i = 0; i < certs.length; i++) {
X509Certificate cert = certs[i];
out.println("證書主體: " + cert.getSubjectDN());
out.println("有效性: " + (verify(cert) ? "有效" : "已過期/無效"));
out.println("詳細信息:\n" + cert.toString());
}
} else if ("https".equalsIgnoreCase(req.getScheme())) {
out.println("HTTPS 請求,但無可用客戶端證書");
} else {
out.println("非 HTTPS 請求,無法獲取客戶端證書");
}
}
private boolean verify(X509Certificate cert) {
try { cert.checkValidity(); return true; }
catch (Exception e) { return false; }
}
}
web.xml 強制特定路徑使用 SSL<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/SSLServlet</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
僅對 /SSLServlet 強制 HTTPS,其他路徑保持 HTTP,兼顧安全與性能。
client.p12,按提示導入「個人」存儲區(Chrome/Edge 使用系統憑證存儲,Firefox 需在瀏覽器內導入)。https://127.0.0.1:8443/SSL/SSLServlet,瀏覽器彈窗選擇客戶端證書 → 確定。server.cer 導入系統「受信任的根證書頒發機構」存儲區。重啟瀏覽器後再次訪問,地址欄顯示綠色安全鎖,無警告。
| 命令 | 用途 |
|---|---|
-genkeypair | 生成密鑰對與自簽名證書 |
-exportcert | 導出公鑰證書文件 |
-importcert | 導入證書到信任庫 |
-list | 查看密鑰庫條目 |
-delete | 刪除條目 |
-keypasswd | 修改私鑰密碼 |
-storepasswd | 修改密鑰庫密碼 |
關鍵參數說明:-alias 別名、-dname 證書主體信息、-validity 有效天數、-storetype 庫類型(JKS/PKCS12)、-keypass 私鑰密碼、-storepass 庫密碼。
本文完整演示了:自簽名 CA 體系構建、服務端/客戶端證書生成與信任鏈建立、Tomcat 雙向 SSL 配置、Web 層證書解析、瀏覽器端證書導入與驗證全流程。掌握此技能,可為內部系統、API 網關、管理後台提供強身份認證保障。