当前位置: 代码网 > it编程>前端脚本>Golang > golang实现openssl自签名双向认证的详细步骤

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

2024年05月18日 Golang 我要评论
第一步:生成ca、服务端、客户端证书1. 生成ca根证书 生成ca证书私钥openssl genrsa -out ca.key 4096创建ca.conf 文件[ req ]default_bits

第一步:生成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双向认证内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com