已发表的技术专栏(订阅即可观看所有专栏)
0 grpc-go、protobuf、multus-cni 技术专栏 总入口
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步:测试 |

下一篇文章
版权声明:本文为u011582922原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。