grpc、https、oauth2等认证专栏实战9:https双向认证介绍

发布于:2023-01-04 ⋅ 阅读:(202) ⋅ 点赞:(0)

已发表的技术专栏(订阅即可观看所有专栏)
0  grpc-go、protobuf、multus-cni 技术专栏 总入口

1  grpc-go 源码剖析与实战  文章目录

2  Protobuf介绍与实战 图文专栏  文章目录

3  multus-cni   文章目录(k8s多网络实现方案)

4  grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录


1、简单介绍双向认证

  • 客户端要验证服务器端的证书,同样,服务器端也要验证客户端的证书
  • 客户端一侧
    • 需要加载根证书,或者给服务器端颁发证书的父证书,用来证明服务器端证书的有效性
    • 客户端也需要加载自己的证书,以及证书密钥,将证书,证书密钥发送给服务器端,以供验证
  • 服务器端一侧:
    • 需要加载根证书,或者给客户端颁发证书的父证书,用来验证客户端证书的有效性
    • 服务器端一侧,需要加载自己的证书,证书密钥;将证书,证书密钥发送给客户端以供校验

2、制作证书

2.1、制作根证书

一次性方式生成根证书

openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 365 -out ca.crt -subj "/C=CN/ST=beijing/L=beijing/O=baidu/OU=bigdata/CN=www.golang.com/emailAddress=000000@qq.com"

在这里插入图片描述

2.2、制作服务器端证书

2.2.1、第一步:生成服务器端密钥和服务器端证书签名 (SAN类型,即多个域名生效)

openssl req -newkey rsa:2048 -nodes -keyout server.key \
    -subj "/C=CN/ST=beijing/L=beijing/O=baidu/OU=bigdata/CN=www.golang-server.com/emailAddress=123456789@qq.com" \
    -reqexts SAN \
    -config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:*.org.golang-server.com,DNS:www.golang-server.cn")) \
    -out server.csr

在这里插入图片描述

查看证书签名里,是否有SAN请求信息

openssl req -noout -text -in server.csr

在这里插入图片描述

2.2.2、第二步:根据CA证书,来颁发服务器端证书

openssl x509 -req -days 365 \
  -in server.csr -out server.crt \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -extensions SAN \
  -extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:*.org.golang-server.com,DNS:www.golang-server.cn"))

在这里插入图片描述

2.2.3、第三步:查看生成的证书

openssl x509 -in server.crt -noout -text 

在这里插入图片描述

2.3、制作客户端证书

2.3.1、第一步:生成服务器端密钥和服务器端证书签名 (非SAN类型,客户端不需要被访问,不需要添加额外的域名)

openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/C=CN/ST=beijing/L=beijing/O=baidu/OU=bigdata/CN=www.golang-client.com/emailAddress=987654321@qq.com"

在这里插入图片描述

2.3.2、第二步:根据CA证书,来颁发客户端证书

openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

在这里插入图片描述

2.3.3、第三步:查看客户端证书

openssl x509 -noout -text -in client.crt

在这里插入图片描述

3、服务器端

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net/http"
)

type MyMux struct {
}

func (p *MyMux) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	fmt.Fprintf(res, "this is http server!")
}

func main() {
	pool := x509.NewCertPool()
	caCertPath := "8-WithTransportCredentials/https/two-way-authentication/tls/ca.crt"

	caCrt, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	pool.AppendCertsFromPEM(caCrt)

	s := &http.Server{
		Addr:    ":8080",
		Handler: &MyMux{},
		TLSConfig: &tls.Config{
			ClientCAs:  pool,
			ClientAuth: tls.RequireAndVerifyClientCert,
		},
	}

	err = s.ListenAndServeTLS("8-WithTransportCredentials/https/two-way-authentication/tls/server.crt", "8-WithTransportCredentials/https/two-way-authentication/tls/server.key")
	if err != nil {
		fmt.Println("ListenAndServeTLS err:", err)
	}
}

在这里插入图片描述

4、客户端

4.1、方式一:使用go语言编写代码,来验证

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"
)

var client *http.Client

func init() {
	pool := x509.NewCertPool()
	caCertPath := "*****改成自己的地址******ca.crt"
	caCrt, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	pool.AppendCertsFromPEM(caCrt)

	clientCrt, err := tls.LoadX509KeyPair("*****改成自己的地址******client.crt", "*****改成自己的地址******client.key")
	if err != nil {
		fmt.Println("Loadx509keypair err:", err)
		return
	}

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			RootCAs:      pool,
			Certificates: []tls.Certificate{clientCrt},
		},
	}

	client = &http.Client{Transport: tr}
}

// 测试单向认证
func TestOneWayAuthentication(t *testing.T) {
	type test struct { // 定义test结构体
		url string
	}
	tests := map[string]test{ // 测试组
		"test1": {url: "https://www.golang-server.cn:8080/svc/hello-openssl"},
		"test2": {url: "https://www.golang-server.com:8080/svc/hello-openssl"},
		"test3": {url: "https://abc.org.golang-server.com:8080/svc/hello-openssl"},
		"test4": {url: "https://www.golang-server.cn:8080/svc/hello-openssl"},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试
			resp, err := client.Get(tc.url)
			if err != nil {
				fmt.Println("Get error:", err)
				return
			}
			defer resp.Body.Close()

			body, err := ioutil.ReadAll(resp.Body)
			fmt.Println(string(body))
		})
	}
}

在/etc/hosts里设置域名,进行测试
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2、方式二:通过命令行,来验证;如curl

在这里插入图片描述

4.3、方式三:通过Postman,来验证

4.3.1、第1步:添加根证书,客户端证书

在这里插入图片描述

在这里插入图片描述

最后,点击 左下角红色的Add

在这里插入图片描述

4.3.2、第2步:测试

在这里插入图片描述

下一篇文章

   oauth2认证方式介绍