最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解如何通過Java實(shí)現(xiàn)SSL交互功能

 更新時(shí)間:2023年04月26日 14:25:20   作者:上官冰  
這篇文章主要為大家詳細(xì)介紹了如何通過Java實(shí)現(xiàn)SSL交互功能,文中的示例代碼講解詳細(xì),對我們的學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下

創(chuàng)建證書

因?yàn)橐a(chǎn)生 key 信任庫,要求的密碼至少的 6位數(shù),所以密碼設(shè)為 123456

  • 首先 生成 根密鑰和根證書
  • 然后 生成 客戶端密鑰 和 客戶端證書,使用根證書對應(yīng)客戶端證書簽名,將根證書和簽名客戶端證書添加到密鑰庫中
  • 最后 同上生成 服務(wù)端簽名證書,并將根證書和服務(wù)端證書添加到 密鑰庫中。

對應(yīng)的腳本如下所示:

#!/bin/bash
# 加個(gè)前綴
PFX='file'
# Password 這里只能使用單引號
PASS='123456'
echo "---- 產(chǎn)生根相關(guān)文件 ----"
echo "創(chuàng)建自簽名的根密鑰"
openssl genrsa -out ${PFX}.rootkey.pem 2048
echo "生成根證書"
openssl req -x509 -new -key ${PFX}.rootkey.pem -out ${PFX}.root.crt -subj "/C=CN/ST=GD/L=GZ/O=RootCA/OU=RootCA/CN=RootCA"
echo "----- 產(chǎn)生客戶端相關(guān)文件 -----"
echo "生成客戶端密鑰"
openssl genrsa -out ${PFX}.clientkey.pem 2048
echo "生成客戶端證書請求文件,使用根證書進(jìn)行簽發(fā)"
openssl req -new -key ${PFX}.clientkey.pem -out ${PFX}.client.csr -subj "/C=CN/ST=GD/L=GZ/O=BMW/OU=Vehicle/CN=Vehicle1"
echo "用根證書來簽發(fā)客戶端請求文件,生成客戶端證書client.crt"
openssl x509 -req -in ${PFX}.client.csr -CA ${PFX}.root.crt -CAkey ${PFX}.rootkey.pem -CAcreateserial -days 3650 -out ${PFX}.client.crt
echo "打包客戶端資料為pkcs12格式(client.pkcs12)"
openssl pkcs12 -export -in ${PFX}.client.crt -inkey clientkey.pem -out ${PFX}.client.pkcs12 -passin "pass:$PASS" -passout "pass:$PASS"
echo "生成信任客戶端的keystore,把根證書以及需要信任的客戶端的證書添加到這個(gè)keystore"
keytool -importcert -alias ca -file ${PFX}.root.crt -keystore ${PFX}.clienttrust.jks -storepass "$PASS" <<EOF
是
EOF
keytool -importcert -alias clientcert -file ${PFX}.client.crt -keystore ${PFX}.clienttrust.jks -storepass "$PASS"
echo "--------產(chǎn)生服務(wù)端相關(guān)文件----"
echo "生成服務(wù)器端的密匙"
openssl genrsa -out ${PFX}.serverkey.pem 2048
echo "生成服務(wù)器端證書的請求文件。請求根證書來簽發(fā)"
openssl req -new -key ${PFX}.serverkey.pem -out ${PFX}.server.csr -subj "/C=CN/ST=GD/L=GZ/O=BMW/OU=IT/CN=Broker"
echo "用根證書來簽發(fā)服務(wù)器端請求文件,生成服務(wù)器端證書server.crt"
openssl x509 -req -in ${PFX}.server.csr -CA ${PFX}.root.crt -CAkey ${PFX}.rootkey.pem -CAcreateserial -days 3650 -out ${PFX}.server.crt
echo "打包服務(wù)器端資料為pkcs12格式(server.pkcs12 )"
openssl pkcs12 -export -in ${PFX}.server.crt -inkey ${PFX}.serverkey.pem -out ${PFX}.server.pkcs12 -passin "pass:$PASS" -passout "pass:$PASS"
echo "生成信任服務(wù)器端的keystore,把根證書以及需要信任的服務(wù)端的證書添加到這個(gè)keystore"
keytool -importcert -alias ca -file ${PFX}.root.crt -keystore ${PFX}.servertrust.jks -storepass "$PASS" <<EOF
是
EOF
keytool -importcert -alias servercert -file ${PFX}.server.crt -keystore ${PFX}.servertrust.jks -storepass "$PASS"

生成的文件目錄,如下圖所示:

#編碼

編寫 SSL Server

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import java.net.Socket;

public class SSLServer {
    private SSLServerSocket sslServerSocket;

    public static void main(String[] args) throws Exception {
        SSLServer server = new SSLServer();
        server.initTestServer();
        server.process();
    }

    private SSLServerSocket initTestServer() throws Exception {
    // ssl-cert 放在 測試 resources 目錄下
        String certDic = SSLServer.class.getClassLoader().getResource("ssl-cert").getPath();
        sslServerSocket = initSocket(certDic + "/file.server.pkcs12",
                certDic + "/file.clienttrust.jks",
                "123456");
    // 如果為 false 表示單向認(rèn)證,否則為雙向認(rèn)證
        sslServerSocket.setNeedClientAuth(false);
        System.out.println("Server test initialted!");
        return sslServerSocket;
    }

    private SSLServerSocket initSocket(String keyPath, String trustPath, String password) throws Exception {
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        char[] keystorePass = password.toCharArray();
        context.init(SSLUtils.creatKey(keyPath, keystorePass).getKeyManagers(),
                SSLUtils.creatTrustJks(trustPath, keystorePass).getTrustManagers(),
                null);
        return (SSLServerSocket) context.getServerSocketFactory().createServerSocket(9999);
    }

//服務(wù)端回復(fù)客戶端
    private void process() throws Exception {
        String bye = "Hello, I am Server!";
        while (true) {
            Socket socket = sslServerSocket.accept();
            System.out.println("Received: " + SSLUtils.read(socket));
            SSLUtils.write(bye, socket);
        }
    }
}

編寫 SSL Client

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

public class SSLClient {
    private SSLSocket sslSocket;

    public static void main(String[] args) throws Exception {
        SSLClient client = new SSLClient();
        client.init();
        client.process();
    }

    private void init() throws Exception {
     // ssl-cert 放在 測試 resources 目錄下
        String certDic = this.getClass().getClassLoader().getResource("ssl-cert").getPath();
        initSocket(certDic + "/file.server.pkcs12", certDic + "/file.servertrust.jks", "123456");
        System.out.println("Client initiated.");
    }

    private void initSocket(String keystorePath, String trustStorePath, String password) throws Exception {
        char[] keystorePass = password.toCharArray();

        KeyManager[] keyManagers = null;
        KeyManagerFactory keyManagerFactory = SSLUtils.creatKey(keystorePath, keystorePass);
        if (keyManagerFactory != null) {
            keyManagers = keyManagerFactory.getKeyManagers();
        }

        TrustManager[] trustManagers = null;
        TrustManagerFactory trustManagerFactory = SSLUtils.creatTrustJks(trustStorePath, keystorePass);
        if (trustManagerFactory != null) {
            trustManagers = trustManagerFactory.getTrustManagers();
        }

        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(keyManagers, trustManagers, null);

        String host = "127.0.0.1";
        sslSocket = (SSLSocket) context.getSocketFactory().createSocket(host, 9999);
    }

    public void process() throws Exception {
        String hello = "Client Hello";
        SSLUtils.write(hello, sslSocket);
        System.out.println(SSLUtils.read(sslSocket));
    }

}

通用編碼

import org.apache.commons.lang3.StringUtils;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;

public class SSLUtils {

    public static void write(String message, Socket sslSocket) throws Exception {
        OutputStream out = sslSocket.getOutputStream();
        byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
        out.write(messageBytes, 0, messageBytes.length);
        out.flush();
    }

    public static String read(Socket sslSocket) throws Exception {
        InputStream in = sslSocket.getInputStream();
        byte[] buffer = new byte[50];
        in.read(buffer);
        return new String(buffer);
    }

    public static KeyManagerFactory creatKey(String keystorePath, char[] keystorePass) throws Exception {
        if (StringUtils.isEmpty(keystorePath)) {
            return null;
        }
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
        kmf.init(loadKeyStore(keystorePath, keystorePass), keystorePass);
        return kmf;
    }

    public static TrustManagerFactory creatTrustJks(String trustClientKeystorePath, char[] keystorePass) throws Exception {
        if (StringUtils.isEmpty(trustClientKeystorePath)) {
            return null;
        }
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
        tmf.init(loadKeyStore(trustClientKeystorePath, keystorePass));
        return tmf;
    }

    private static KeyStore loadKeyStore(String keystorePath, char[] keystorePass) throws Exception {
        KeyStore serverKeyStore = KeyStore.getInstance(StringUtils.substringAfterLast(keystorePath, "."));
        serverKeyStore.load(new FileInputStream(keystorePath), keystorePass);
        return serverKeyStore;
    }
}

測試

啟動(dòng) SSLServer 和 SSLClient 可以得到的結(jié)果如下所示:

使用 wireshark 抓包如下所示:

這就是對應(yīng)的 SSL 連接

到此這篇關(guān)于一文詳解如何通過Java實(shí)現(xiàn)SSL交互功能的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)SSL交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在Web項(xiàng)目中手機(jī)短信驗(yàn)證碼實(shí)現(xiàn)的全過程記錄

    在Web項(xiàng)目中手機(jī)短信驗(yàn)證碼實(shí)現(xiàn)的全過程記錄

    這篇文章主要給大家介紹了關(guān)于在Web項(xiàng)目中實(shí)現(xiàn)短信驗(yàn)證碼的全過程記錄,文中通過示例代碼介紹的非常詳細(xì),在文末跟大家提供了源碼下載,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • JPA?通過Specification如何實(shí)現(xiàn)復(fù)雜查詢

    JPA?通過Specification如何實(shí)現(xiàn)復(fù)雜查詢

    這篇文章主要介紹了JPA?通過Specification如何實(shí)現(xiàn)復(fù)雜查詢,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springboot 日志彩色消失的2種解決方案

    springboot 日志彩色消失的2種解決方案

    這篇文章主要介紹了springboot 日志彩色消失的2種解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot中如何通過cors協(xié)議解決跨域問題

    springboot中如何通過cors協(xié)議解決跨域問題

    這篇文章主要介紹了springboot中通過cors協(xié)議解決跨域問題,cors是一個(gè)w3c標(biāo)準(zhǔn),它允許瀏覽器(目前ie8以下還不能被支持)像我們不同源的服務(wù)器發(fā)出xmlHttpRequest請求,我們可以繼續(xù)使用ajax進(jìn)行請求訪問。具體內(nèi)容詳情大家跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • 一文搞懂Mybatis-plus的分頁查詢操作

    一文搞懂Mybatis-plus的分頁查詢操作

    說起分頁機(jī)制,相信我們程序員都不陌生,今天,我就給大家分享一下Mybatis-plus的分頁機(jī)制,供大家學(xué)習(xí)和Copy,感興趣的可以了解一下
    2022-06-06
  • 一文詳解Java屬性為什么不能是is開頭的boolean

    一文詳解Java屬性為什么不能是is開頭的boolean

    在Java實(shí)體類定義中,boolean類型的屬性命名常引發(fā)爭議,阿里巴巴Java開發(fā)手冊建議避免使用is作為布爾類型屬性的前綴,原因在于當(dāng)實(shí)體類被序列化或反序列化時(shí),基于JavaBean規(guī)范的框架可能會(huì)移除或忽略is,導(dǎo)致不一致的字段名,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • Mybatis批量修改時(shí)出現(xiàn)報(bào)錯(cuò)問題解決方案

    Mybatis批量修改時(shí)出現(xiàn)報(bào)錯(cuò)問題解決方案

    這篇文章主要介紹了Mybatis批量修改時(shí)出現(xiàn)報(bào)錯(cuò)問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot詳細(xì)講解日志文件

    SpringBoot詳細(xì)講解日志文件

    Spring Boot默認(rèn)使用SLF4J+Logback 記錄日志,并提供了默認(rèn)配置,即使我們不進(jìn)行任何額外配,也可以使用SLF4J+Logback進(jìn)行日志輸出
    2022-06-06
  • SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例

    SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例

    ,Spring Cloud作為一個(gè)強(qiáng)大的微服務(wù)框架,提供了豐富的功能和組件,本文主要介紹了SpringCloud創(chuàng)建多模塊項(xiàng)目的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • 聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的

    聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的

    這篇文章主要介紹了聊一聊jdk1.8中的ArrayList 底層數(shù)組是如何擴(kuò)容的,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論

武功县| 宁安市| 青川县| 景德镇市| 松阳县| 平山县| 浏阳市| 赤壁市| 祥云县| 清河县| 吉水县| 洪湖市| 米林县| 昭苏县| 台安县| 安阳市| 枣阳市| 汕头市| 永胜县| 都兰县| 和林格尔县| 台前县| 兴城市| 高碑店市| 宝应县| 逊克县| 梁山县| 凭祥市| 宁河县| 平泉县| 疏附县| 天全县| 古丈县| 永新县| 海城市| 黄陵县| 图片| 汉中市| 鹤壁市| 平定县| 皋兰县|