当前位置: 首页 > news >正文

java使用https协议访问(自签名证书,运行时指定信任库(不修改系统证书))

需求:在本地实现java的文字聊天功能。编写两个java对象,一个对象代表服务器,一个对象代表客端,一个代表客户端。客户端输入文字,服务器端接收并响应结果给客户端。

前置条件:首先生成密钥库和证书

# 生成服务器密钥库和自签名证书
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -storetype JKS -keystore server.keystore -validity 365 -storepass serverpass -keypass serverpass -dname "CN=localhost, OU=Example, O=Example, L=City, ST=State, C=US"# 导出服务器证书
keytool -exportcert -alias server -keystore server.keystore -file server.crt -storepass serverpass# 生成客户端信任库并导入服务器证书
keytool -importcert -alias server -file server.crt -keystore client.truststore -storepass clientpass -noprompt

服务器端口代码如下:

package com.example.demo.demos;import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;public class Server {private static int requestCount = 0; // 计数器记录请求次数public static void main(String[] args) {try {// 加载服务器密钥库(包含私钥和证书)KeyStore keyStore = KeyStore.getInstance("JKS");keyStore.load(new FileInputStream("server.keystore"), "serverpass".toCharArray());// 创建密钥管理器工厂KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(keyStore, "serverpass".toCharArray());// 创建SSL上下文并初始化SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), null, null);// 创建SSL服务器套接字工厂SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();// 创建SSL服务器套接字并绑定端口SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(8443);// 启用所有支持的密码套件和协议sslServerSocket.setEnabledCipherSuites(sslServerSocket.getSupportedCipherSuites());sslServerSocket.setEnabledProtocols(sslServerSocket.getSupportedProtocols());System.out.println("服务器已启动,等待客户端连接...");// 接受客户端连接SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();// 处理客户端请求try (BufferedReader in = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true)) {String inputLine;while ((inputLine = in.readLine()) != null) {requestCount++; // 每次请求计数器+1String response = String.format("第%d次返回结果:%s", requestCount, inputLine); // 格式化响应内容System.out.println("客户端消息: " + inputLine);out.println(response); // 发送格式化后的响应}}sslSocket.close();sslServerSocket.close();} catch (Exception e) {e.printStackTrace();}}
}

客户端代码:

package com.example.demo.demos;import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;public class Client {public static void main(String[] args) {try {// 加载客户端信任库(包含服务器证书)KeyStore trustStore = KeyStore.getInstance("JKS");trustStore.load(new FileInputStream("client.truststore"), "clientpass".toCharArray());// 创建信任管理器工厂TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(trustStore);// 创建SSL上下文并初始化SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(null, tmf.getTrustManagers(), null);// 创建SSL套接字工厂SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();// 创建SSL套接字并连接到服务器SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket("localhost", 8443);// 启用所有支持的密码套件和协议sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());// 向服务器发送消息try (PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {System.out.println("请输入内容:");String userInput;while ((userInput = stdIn.readLine()) != null) {out.println(userInput);System.out.println("服务器返回: " + in.readLine());System.out.println("请继续输入内容:");}}sslSocket.close();} catch (Exception e) {e.printStackTrace();}}
}

关键配置说明

  1. 服务器配置

    • 使用server.keystore存储服务器私钥和证书
    • 通过KeyManagerFactory加载服务器密钥库
    • 服务器使用默认信任库验证客户端证书(如果需要双向认证)
  2. 客户端配置

    • 使用client.truststore存储信任的服务器证书
    • 通过TrustManagerFactory加载客户端信任库
    • 客户端通过SSLContext初始化自定义信任管理器

结果:客户端多次输入,服务器均正常返回。

http://www.xdnf.cn/news/665695.html

相关文章:

  • 城市污水管网流量在线监测方案
  • VPet虚拟桌宠,一款桌宠软件,支持各种互动投喂等. 开源免费并且支持创意工坊
  • 如何搭建perfino监控(分析java服务性能)
  • 从姿势到心态:痉挛性斜颈的多维护理方案
  • old语音识别科大讯飞+deepseek api
  • SOC-ESP32S3部分:13-定时器
  • 删掉省市区的市辖区
  • 推理模型 vs 非推理模型:核心区别及优劣势解析
  • 3.微服务架构编码Base工程模块构建
  • 【stm32开发板】产品设计流程及元件选型
  • 创业团队建设与管理(一)
  • 牛客round94E
  • 「Unity3D」TextMeshPro的TMP_InputField在改变高度时,其中textComponent移动的问题解决
  • VMware Live Recovery 和 VMware Data Recovery区别
  • python 报错记录-Linux 退出python环境
  • Python Day34
  • 聚合CPA/CPS拉新分销平台开发:2025年核心功能与未来趋势解析
  • HarmonyOS运动开发:如何绘制运动速度轨迹
  • day 22 练习——泰坦尼克号幸存者预测
  • Dify中的GoogleSearch工具插件开发例子
  • 华为OD机试真题——新工号中数字的最短长度(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • 【AI论文】LLaDA-V:具备视觉指令微调能力的大型语言扩散模型
  • 基于 LoRA 和 GRPO 的 Qwen2.5-3B 数学推理模型微调示例
  • java学习日志——Spring Security介绍
  • 二维坐标变换、三维坐标变换、综合变换
  • 人工智能工程师学习路线总结(上)
  • MySQL的日志和备份
  • 热点数据的统计到应用
  • C 语言学习笔记二
  • 202505系分论文《论模型驱动分析方法及应用》