java 用httpClient 根据ca.crt、client.crt和client.key文件实现与服务端https通讯

文章详细描述了如何在Java中创建一个双向SSLSocketFactory,使用X.509证书进行服务器身份验证,以及如何设置HTTPS请求,包括私钥和CA证书的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >





    public static SSLConnectionSocketFactory getSSLSocktetBidirectional() throws Exception {
        SSLConnectionSocketFactory sslsf = null;

        try{
// CA certificate is used to authenticate server
            String linuxLocalIp = IpDataUtils.getSelfPublicIp();
            //正式环境代码,配置正常逻辑代码
          
            CertificateFactory cAf = CertificateFactory.getInstance("X.509");
            FileInputStream caIn = new FileInputStream(CA_PATH);
            X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
            KeyStore caKs = KeyStore.getInstance("JKS");
            caKs.load(null, null);
            //caKs.setCertificateEntry("ca-certificate", ca);
            caKs.setCertificateEntry("verify", ca);
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
            tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate us
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            FileInputStream crtIn = new FileInputStream(CRT_PATH);
            X509Certificate caCert = (X509Certificate) cf.generateCertificate(crtIn);
            crtIn.close();

            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(null, null);
            ks.setCertificateEntry("certificate", caCert);
            ks.setKeyEntry("private-key", getPrivateKey(KEY_PATH), PASSWORD.toCharArray(), new java.security.cert.Certificate[] { caCert });
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
            kmf.init(ks, PASSWORD.toCharArray());
// finally, create SSL socket factory
            SSLContext context = SSLContext.getInstance("TLSv1.2");
            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

            sslsf = new SSLConnectionSocketFactory(context,null, null,NoopHostnameVerifier.INSTANCE);
        }catch (Exception e){
            System.out.println("证书加载失败");
            e.printStackTrace();
        }

        return sslsf;
    }




  private static PrivateKey getPrivateKey(String path) throws Exception {
//byte[] buffer = Base64.getDecoder().decode(getPem(path));
// Base64 base64 = new Base64();
       
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] buffer = base64Decoder.decodeBuffer(getPem(path));
        BASE64Decoder decoder = new BASE64Decoder();
        //byte[] buffer = decoder.decodeBuffer(getPem(path));
        //PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(getPem(path)));

      /*  PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;*/

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }





private static String getPem(String path) throws Exception {
        FileInputStream fin = new FileInputStream(path);
        BufferedReader br = new BufferedReader(new InputStreamReader(fin));
        String readLine = null;
        StringBuilder sb = new StringBuilder();
        while ((readLine = br.readLine()) != null) {
            if (readLine.charAt(0) == '-') {
                continue;
            } else {
                sb.append(readLine);
                sb.append('\r');
            }
        }
        fin.close();
        return sb.toString();
    }

以上没什么就直接帖代码就行

接下来

  
   public static  String CA_PATH = "C:/Users/lsy/Desktop/certs/ca.crt";
    public static  String CRT_PATH = "C:/Users/lsy/Desktop/certs/client.crt";
    public static  String KEY_PATH = "C:/Users/lsy/Desktop/certs/client.key";
    public static  String PASSWORD = "lisenyuan";

 public static String httpPost( List<shengxinFileDataVm> list) throws IOException {
        CloseableHttpClient httpClient = null;
        List<ShengxinDataAdd> listData=new ArrayList();
        JSONObject jsonObject = new JSONObject();
      /* Map map=new HashMap<>();*/
        ShengxinDataAdd shengxindataadd=new ShengxinDataAdd();
        StringBuffer sb1=new StringBuffer();
        StringBuffer sb2=new StringBuffer();
        String linuxLocalIp = IpDataUtils.getSelfPublicIp();
        String igIp=null;


        for (int i = 0; i < list.size(); i++) {

            ShengxinFileData shengxinFileData1 = list.get(i);
            sb1.append(shengxinFileData1.getSequencingNumber());
            sb1.append(",");
            sb2.append(shengxinFileData1.getSpecimenName());
            sb2.append(",");

        }
        shengxindataadd.setSequencingNumber(sb1.substring(0,sb1.length()-1));
        shengxindataadd.setSpecimenName(sb2.substring(0,sb2.length()-1));
        shengxindataadd.setTaskId(list.get(0).getTaskId().toString());
        shengxindataadd.setProjectNumber(list.get(0).getProjectNumber());
        shengxindataadd.setPanelNumber(list.get(0).getPanel());
        shengxindataadd.setFileType(list.get(0).getFileType());
        shengxindataadd.setContractNumber(list.get(0).getContractNumber());
        shengxindataadd.setCallback(igIp);
        String stringJSON = JSON.toJSONString(shengxindataadd);
        String result = null;
       // System.out.println("请求数据:"+jsonObject.toJSONString());
        System.out.println("请求数据:"+stringJSON);

        try{
            SSLConnectionSocketFactory sslsf = getSSLSocktetBidirectional();
//设置认证信息到httpclient
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }catch (Exception e){
            System.out.println("证书读取失败");
            e.printStackTrace();
            return "证书读取失败";

        }
// 根据默认超时限制初始化requestConfig
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(25000).setConnectTimeout(25000).build();
//post通讯初始化
        HttpPost httpPost = new HttpPost("https:");
// 设置报文头 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
/*        httpPost.addHeader("igIp", igIp);*/
//添加请求报文体
        StringEntity reqentity = new StringEntity(stringJSON, "UTF-8");
        httpPost.setEntity(reqentity);
// 设置请求器的配置
        httpPost.setConfig(requestConfig);
        try {
            CloseableHttpResponse response = null;
            InputStream reqin = null;
            try {
//打印请求报文体
                reqin = httpPost.getEntity().getContent();
                String reqBbody = StreamUtils.copyToString(reqin, StandardCharsets.UTF_8);
                System.out.println("请求数据:"+reqBbody);
//与服务端通讯
                response = httpClient.execute(httpPost);

//打印通讯状态
                System.out.println(JSONObject.toJSONString(response.getStatusLine()));
                JSONObject.toJSONString(response.getStatusLine());

                HttpEntity entity = response.getEntity();
                InputStream in = null;
                try {

                    in = entity.getContent();
                    String rspBbody = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
                    System.out.println("应答为:"+rspBbody);
                    in.close();

                    if(response.getStatusLine().getStatusCode()==200){
                        result="成功";
                    }else{
                        result="失敗";
                    }

// result = EntityUtils.toString(entity, "UTF-8");


                } catch (IOException e) {
                    System.out.println("服务端应答信息读取失败");
                    e.printStackTrace();
                    return "服务端应答信息读取失败";
                }finally {
                    if (in !=null){
                        in.close();
                    }
                }

            } catch (IOException e) {
                System.out.println("与服务端通讯失败");
                e.printStackTrace();
                return "与服务端通讯失败";
            }finally {
                try{
                //释放资源
                    if (httpClient != null){
                        httpClient.close();
                    }
                    if (response != null){
                        response.close();
                    }
                    if (reqin != null){
                        reqin.close();
                    }
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } finally {
            httpPost.abort();
        }
        return result;

    }

重要的来了,有人不知道哪里lisenyuan 这个字符串是怎么来的

keytool -import -alias mycert -keystore cacerts -file C:/Users/lsy/Desktop/certs/ca.crt

执行上面命令设置就行了

<think>我们正在讨论IEEE2030.5协议(也称为智能能源规范2.0)的开发配置。该协议基于REST架构,使用XML或JSON格式,并依赖于TLS/SSL进行安全通信。它主要用于智能电网设备之间的通信,如太阳能逆变器、电池存储系统等。 开发指南: 1.理解协议规范:首先需要详细阅读IEEE2030.5标准文档,了解其资源模型交互流程。 2.选择开发库:根据开发语言选择合适的库。例如,对于Java,可以使用Apache HttpClient;对于Python,可以使用requests库。 3.实现安全层:协议要求使用TLS1.2及以上版本,并且通常需要双向认证(客户端服务器都需要证书)。4.资源操作:实现GET、POST、PUT、DELETE等HTTP方法操作资源(如FunctionSetAssignments、EndDevice等)。 配置方法:1.证书配置:在客户端服务器端配置X.509证书,并建立信任链。2.网络配置:确保设备能够通过指定的端口(通常为443)进行通信。3.资源路径配置:根据设备类型配置正确的资源路径(如/sedp、/fsa等)。示例代码(Python使用requests库):```pythonimportrequests#配置客户端证书cert =('/path/to/client_cert.pem','/path/to/client_key.pem')#目标URL(以获取EndDevice资源为例)url ='https://server.example.com:443/edev'#发送GET请求response =requests.get(url,cert=cert,verify='/path/to/ca_cert.pem')#处理响应if response.status_code==200:print(response.text)#通常为XML或JSON格式else:print(f"请求失败,状态码:{response.status_code}")``` 注意事项: -在实际开发中,需要处理分页(Paginated List)订阅(Subscription)等复杂情况。 -协议要求时间同步,设备时间必须服务器时间保持一致(通常使用NTP)。§§相关问题§§1. IEEE2030.5协议中常用的资源有哪些?2.如何处理IEEE2030.5协议中的分页资源?3.在IEEE2030.5通信中如何实现事件订阅?4.如何调试IEEE2030.5协议通信中的常见错误?</think>### IEEE 2030.5协议开发配置指南 IEEE 2030.5(智能能源规范2.0)是智能电网设备通信的核心协议,基于REST架构实现分布式能源系统互操作。以下是开发配置的关键步骤: #### 一、开发基础 1. **协议核心特性** - 基于RESTful HTTP/HTTPS架构 - 使用XML或JSON数据格式(推荐XML) - 强制TLS 1.2+安全传输 - 资源模型包括:`EndDevice`, `FunctionSetAssignments`, `DERProgram`等 2. **开发环境搭建**: ```python # Python示例:安装基础库 pip install requests cryptography pyOpenSSL ``` #### 二、关键配置步骤 1. **证书配置**(双向认证) - 生成X.509v3证书链: ```bash # 生成CA证书 openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 365 ``` - 设备端需配置: - 客户端证书 - 私钥 - CA根证书 2. **服务端资源端点配置**: ```xml <!-- 示例:DER控制资源注册 --> <der:DERCapability xmlns:der="urn:ieee:std:2030.5:der"> <href>/der/1234</href> <derSettingsLink>/der/settings/1234</derSettingsLink> </der:DERCapability> ``` #### 三、通信实现示例 ```python import requests from requests.adapters import HTTPAdapter from urllib3.util.ssl_ import create_urllib3_context # 创建TLS上下文 ctx = create_urllib3_context() ctx.load_cert_chain('client.crt', 'client.key') ctx.load_verify_locations('ca.crt') # 创建安全会话 session = requests.Session() session.mount('https://', TLSAdapter(ctx)) # 获取设备资源 response = session.get( 'https://grid-server.example.com/edev', headers={'Content-Type': 'application/sep+xml'} ) print(response.text) # 输出XML格式资源描述 ``` #### 四、调试验证 1. **常用工具**: - **OpenSEP**:开源协议实现库 - **Postman**:配置双向证书测试API - **Wireshark**:过滤`tls and ip.addr==[目标IP]`分析TLS握手 2. **典型错误处理**: | 错误码 | 原因 | 解决方案 | |--------|-----------------------|-----------------------| | 401 | 证书验证失败 | 检查证书链完整性 | | 404 | 资源路径错误 | 验证EndDevice注册路径 | | 503 | 时间不同步 | 启用NTP时间同步 | > 注:协议要求设备时间误差必须小于±2秒[^IEEE2030.5-2018] #### 五、应用场景 1. 光伏逆变器功率调节 2. 电动汽车充电调度 3. 家庭能源管理系统(HEMS) 4. 需求响应事件处理
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值