IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> HTTPS双向认证 -> 正文阅读

[网络协议]HTTPS双向认证

双向认证

C/S两端分别生成密钥对,交换公钥,基于公钥验证另一端。

第一步,创建密钥对,把公钥存储为自签名、PEM编码的证书。用openssl即可,这里以一个HTTPS服务端为例:

openssl req -nodes -x509 -newkey rsa:4096 -keyout serverKey.pem -out serverCrt.pem -days 365

serverKey.pem包含服务器的私钥,需要保护;serverCrt.pem包含服务器的公钥,用来分发。

客户端:

openssl req -nodes -x509 -newkey rsa:4096 -keyout clientKey.pem -out clientCrt.pem -days 365

服务端

https服务端源码:


func helloHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("Hello: %s\n", r.TLS.PeerCertificates[0].Subject.CommonName)
	fmt.Fprint(w, "Authentication successful")
}

func main() {
	var (
		err        error
		clientCert []byte
		pool       *x509.CertPool
		tlsConf    *tls.Config
		server     *http.Server
	)

	http.HandleFunc("/hello", helloHandler)

	if clientCert, err = ioutil.ReadFile("../client/clientCrt.pem"); err != nil {
		log.Fatalln(err)
	}
	pool = x509.NewCertPool()
	pool.AppendCertsFromPEM(clientCert)

	tlsConf = &tls.Config{
		ClientCAs:  pool,
		ClientAuth: tls.RequireAndVerifyClientCert,
		// RequireAndVerifyClientCert indicates that a client certificate should be requested
		// during the handshake, and that at least one valid certificate is required
		// to be sent by the client.
	}
	tlsConf.BuildNameToCertificate() // map domain to certificate

	server = &http.Server{
		Addr:      ":9443",
		TLSConfig: tlsConf,
	}
	log.Fatalln(server.ListenAndServeTLS("serverCrt.pem", "serverKey.pem"))
}

访问https://localhost:9443/hello,页面会显示Your connection isn’t private。服务端也显示:http: TLS handshake error from [::1]:1157: remote error: tls: unknown certificate

用curl测试:

$ sudo curl -ik -X GET --cert clientCrtBad.pem --key clientKeyBad.pem https://localhost:9443/hello
curl: (16) SSL_write() returned SYSCALL, errno = 32

服务端:

http: TLS handshake error from 127.0.0.1:33470: tls: failed to verify client certificate: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "Internet Widgits Pty Ltd")

再测试正确的密钥,请求连接成功:

$ sudo curl -ik -X GET --cert clientCrt.pem --key clientKey.pem https://localhost:9443/hello
HTTP/2 200 
content-type: text/plain; charset=utf-8
content-length: 25
date: Mon, 28 Feb 2022 14:00:00 GMT

Authentication successful

服务端也显示了 Hello:,完成了对客户端的验证。

客户端(问题残留)


func main() {
	var (
		err              error
		cert             tls.Certificate
		serverCert, body []byte
		pool             *x509.CertPool
		tlsConf          *tls.Config
		transport        *http.Transport
		client           *http.Client
		resp             *http.Response
	)

	if cert, err = tls.LoadX509KeyPair("clientCrt.pem", "clientKey.pem"); err != nil {
		log.Fatalln(err)
	}

	if serverCert, err = ioutil.ReadFile("../server/serverCrt.pem"); err != nil {
		log.Fatalln(err)
	}

	pool = x509.NewCertPool()
	pool.AppendCertsFromPEM(serverCert)

	tlsConf = &tls.Config{
		Certificates: []tls.Certificate{cert},
		RootCAs:      pool,
	}
	tlsConf.BuildNameToCertificate()

	transport = &http.Transport{
		TLSClientConfig: tlsConf,
	}
	client = &http.Client{
		Transport: transport,
	}

	if resp, err = client.Get("https://localhost:9443/hello"); err != nil {
		log.Fatalln(err)
	}
	if body, err = ioutil.ReadAll(resp.Body); err != nil {
		log.Fatalln(err)
	}
	defer resp.Body.Close()

	fmt.Printf("Success: %s\n", body)
}

不过在测试的时候因为域名问题报错了,暂未解决:

Get "https://localhost:9443/hello": x509: certificate is not valid for any names, but wanted to match localhost
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:49:22  更:2022-03-03 16:51:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:20:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码