golang实现openssl自签名双向认证的详细步骤

 更新时间:2024年03月04日 14:36:04   作者:赴前尘  
这篇文章主要介绍了golang实现openssl自签名双向认证的详细步骤,本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

第一步:生成CA、服务端、客户端证书

1. 生成CA根证书 生成CA证书私钥

openssl genrsa -out ca.key 4096

创建ca.conf 文件

[ req ]
default_bits       = 4096
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
countryName_default         = CN
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = JiangSu
localityName                = Locality Name (eg, city)
localityName_default        = NanJing
organizationName            = Organization Name (eg, company)
organizationName_default    = Sheld
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost

生成根证书签发申请文件(csr文件)

openssl req \
  -new \
  -sha256 \
  -out ca.csr \
  -key ca.key \
  -config ca.conf

生成自签发根证书(crt文件)

openssl x509 \
    -req \
    -days 3650 \
    -in ca.csr \
    -signkey ca.key \
    -out ca.pem

2. 生成服务端证书

生成服务端私钥

openssl genrsa -out server.key 2048

创建 server.conf 文件

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
countryName_default         = CN
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = JiangSu
localityName                = Locality Name (eg, city)
localityName_default        = NanJing
organizationName            = Organization Name (eg, company)
organizationName_default    = Sheld
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost    # 此处尤为重要,需要用该服务名字填写到客户端的代码中
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1   = localhost
IP.1      = 127.0.0.1

生成服务端签发申请文件(csr文件)

openssl req \
  -new \
  -sha256 \
  -out server.csr \
  -key server.key \
  -config server.conf

使用CA证书签署服务器证书

openssl genrsa -out client.key 2048

3. 生成客户端证书

生成客户端私钥

openssl genrsa -out client.key 2048

创建 client.conf 文件

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
countryName_default         = CN
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = JiangSu
localityName                = Locality Name (eg, city)
localityName_default        = NanJing
organizationName            = Organization Name (eg, company)
organizationName_default    = Sheld
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost

生成客户端端签发申请文件(csr文件)

openssl req \
  -new \
  -sha256 \
  -out client.csr \
  -key client.key \
  -config client.conf

使用CA证书签署客户端器证书

openssl x509 \
    -req \
    -days 3650 \
    -CA ca.pem \
    -CAkey ca.key \
    -CAcreateserial \
    -in client.csr \
    -out client.pem

第二步:golang 服务端、客户端代码编写

1. 项目目录结构

在这里插入图片描述

2. 服务端代码:server.go

package main
import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net/http"
	"os"
)
type MyHandler struct {
}
func (h *MyHandler) ServeHTTP(w http.ResponseWriter,
	r *http.Request) {
	fmt.Fprint(w, "Hello, HTTPS!")
}
func main() {
	pool := x509.NewCertPool() // 创建证书池
	caCertPath := "./cert/ca.pem"
	caCrt, err := os.ReadFile(caCertPath) // 读取本地CA证书文件
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	pool.AppendCertsFromPEM(caCrt) // 将证书添加到证书池中
	s := &http.Server{ // 创建 HTTP服务器实例,并设置服务器的监听地址(本例中是127.0.0.1:8088)、处理器(即上面定义的myhandler结构体)、以及TLS配置。
		Addr:    "127.0.0.1:8088",
		Handler: &MyHandler{},
		TLSConfig: &tls.Config{
			ClientCAs:  pool,                           // 指定客户端需要验证的CA证书池(即上面创建的pool)
			ClientAuth: tls.RequireAndVerifyClientCert, // 要求客户端在发送请求时必须携带证书
		},
	}
	err = s.ListenAndServeTLS("./cert/server.pem", "./cert/server.key")
	if err != nil {
		fmt.Println("ListenAndServeTLS err:", err)
	}
}

3. 客户端代码:client.go

package main
import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io"
	"net/http"
	"os"
)
func main() {
	pool := x509.NewCertPool()    // 创建 x509.CertPool,用于存储CA证书
	caCertPath := "./cert/ca.pem" // 从文件中读取CA证书的内容
	caCrt, err := os.ReadFile(caCertPath)
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	pool.AppendCertsFromPEM(caCrt)                                               // 将CA证书添加到CertPool中
	cliCrt, err := tls.LoadX509KeyPair("./cert/client.pem", "./cert/client.key") //加载客户端证书和私钥
	if err != nil {
		fmt.Println("Loadx509keypair err:", err)
		return
	}
	tr := &http.Transport{ // 创建一个http.Transport,并配置TLS相关信息
		TLSClientConfig: &tls.Config{
			RootCAs:      pool,                      // 设置根证书池
			Certificates: []tls.Certificate{cliCrt}, // 设置客户端证书和私钥
		},
	}
	client := &http.Client{Transport: tr}             // 创建一个http.Client,并设置Transport为上面创建的Transport对象
	resp, err := client.Get("https://127.0.0.1:8088") // 使用创建的Client发送GET请求
	if err != nil {
		fmt.Println("Http Get error:", err)
		return
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body) // 读取并打印响应体的内容
	fmt.Println(string(body))
}

第三步:验证

1. 运行服务端

go run ./server/server.go

在这里插入图片描述

2. 运行客户端

运行客户端

go run ./client/client.go

在这里插入图片描述

到此这篇关于golang实现openssl自签名双向认证的详细步骤的文章就介绍到这了,更多相关golang双向认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 提升Go语言开发效率的小技巧实例(GO语言语法糖)汇总

    提升Go语言开发效率的小技巧实例(GO语言语法糖)汇总

    这篇文章主要介绍了提升Go语言开发效率的小技巧汇总,也就是Go语言的语法糖,掌握好这些可以提高我们的开发效率,需要的朋友可以参考下
    2022-11-11
  • golang实现简易的分布式系统方法

    golang实现简易的分布式系统方法

    这篇文章主要介绍了golang实现简易的分布式系统方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • 使用goland调试远程代码的操作步骤

    使用goland调试远程代码的操作步骤

    大家都知道如何在goland调试远程代码吗?今天小编给大家分享一篇教程帮助大家学习goland调试远程代码的操作步骤,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • 如何利用Golang写出高并发代码详解

    如何利用Golang写出高并发代码详解

    今天领导问起为什么用Golang,同事回答语法简单,语言新,支持高并发。那高并发到底如何实现,下面这篇文章主要给大家介绍了关于如何利用Golang写出高并发代码的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • Go语言操作MySql数据库的详细指南

    Go语言操作MySql数据库的详细指南

    数据的持久化是程序中必不可少的,所以编程语言中对数据库的操作是非常重要的一块,这篇文章主要给大家介绍了关于Go语言操作MySql数据库的相关资料,需要的朋友可以参考下
    2023-10-10
  • Go Slice进行参数传递如何实现详解

    Go Slice进行参数传递如何实现详解

    这篇文章主要为大家介绍了Go Slice进行参数传递如何实现的过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 一文带你吃透Go语言中的原子操作

    一文带你吃透Go语言中的原子操作

    原子操作是解决并发编程中共享数据访问问题的一种常见机制,下面就来和大家深入介绍原子操作的原理、用法以及在解决并发问题中的应用,需要的可以参考一下
    2023-06-06
  • golang为什么要统一错误处理

    golang为什么要统一错误处理

    这篇文章主要介绍了golang为什么要统一错误处理,统一错误处理的目的是为了前端开发接收到后端的statuscode,之后便于前端逻辑上开发以及开发,下文具体操作过程需要的小伙伴可以参考一下
    2022-04-04
  • 解决Go中拦截HTTP流数据时字段丢失的问题

    解决Go中拦截HTTP流数据时字段丢失的问题

    在开发高并发的Web应用时,尤其是在处理HTTP代理和流数据拦截的场景下,遇到数据丢失的问题并不罕见,最近,在一个项目中,我遇到了一个棘手的问题:在拦截并转发HTTP流数据的过程中,某些数据字段因为处理过快而被丢失,所以本文给大家介绍如何解决这个问题
    2024-08-08
  • golang中切片copy复制和等号复制的区别介绍

    golang中切片copy复制和等号复制的区别介绍

    这篇文章主要介绍了golang中切片copy复制和等号复制的区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04

最新评论