【GO】29.go-gin支持ssl/tls,即https示例

这篇具有很好参考价值的文章主要介绍了【GO】29.go-gin支持ssl/tls,即https示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文为演示采用自签名证书

一.生成证书

通过openssl工具生成证书

1.1 安装openssl

macos通过brew安装

brew install openssl

1.2 生成跟证书私钥

openssl genrsa -out ca.key 4096

1.3 准备配置文件

vim 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          = Ted CA Test

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

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

该命令含义如下:

req——执行证书签发命令

-new——新证书签发请求

-key——指定私钥路径

-out——输出的csr文件的路径

1.4 自签发根证书(cer文件)

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

该命令的含义如下:

x509——生成x509格式证书

-req——输入csr文件

-days——证书的有效期(天)

-signkey——签发证书的私钥

-in——要输入的csr文件

-out——输出的cer证书文件

1.5 生成服务端私钥

openssl genrsa -out server.key 2048

1.6 准备配置文件,得到server.conf

vim 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          = server.com

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1   = server.com

生成服务端证书申请文件

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

参考1.3输入服务端证书信息

1.7 用CA证书签发服务端证书

openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -extensions req_ext -extfile server.conf

这里有必要解释一下这几个参数:

-CA——指定CA证书的路径

-CAkey——指定CA证书的私钥路径

-CAserial——指定证书序列号文件的路径

-CAcreateserial——表示创建证书序列号文件(即上方提到的serial文件),创建的序列号文件默认名称为-CA,指定的证书名称后加上.srl后缀

1.8 生成客户端私钥

openssl genrsa -out client.key 2048

1.9 准备配置文件,得到client.conf

vim client.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 = HeNan
localityName                = Locality Name (eg, city)
localityName_default        = AnYang
organizationName            = Organization Name (eg, company)
organizationName_default    = Sheld_client
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = server.com

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1   = server.com
DNS.2    = localhost

生成客户端证书申请文件

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

1.10 用跟证书签发客户端证书

openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAserial ca.srl -in client.csr -out client.crt -extensions req_ext -extfile client.conf

需要注意的是,上方签发服务端证书时已经使用-CAcreateserial生成过ca.srl文件,因此这里不需要带上这个参数了。

二. gin框架实现https,服务端不需要验证客户端证书的示例

2.1 项目引入gin框架

go get -u github.com/gin-gonic/gin

2.2 服务端代码

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.New()

    router.GET("/test", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "success",
        })
    })

    // 可以直接用
    //router.RunTLS("0.0.0.0:10679", "./certs/server.cer", "./certs/server.key")
    server := &http.Server{Addr: "0.0.0.0:10679", Handler: router}
    _ = server.ListenAndServeTLS("./certs/server.cer", "./certs/server.key")
}

2.3 安全提示

打开浏览器访问https://localhost:10679/test

因为浏览器并不信任证书的颁发机构,浏览器会有安全提示,当然可以点高级直接强行访问页面,同样可以返回结果,很多文章也是到这里就结束了。强迫症的我还是要解决一下。

certificate is not standards compliant,Go技术积累,golang,gin,开发语言,ssl/tls,https,Powered by 金山文档

2.4 给浏览器添加自己生成的CA证书

本文选择firefox浏览器,因为设置可以轻松添加信任CA证书。chrome则是直接掉起系统的证书,没有找到友好的办法自己添加

我们把CA证书(1.4节生成的ca.csr)添加到firefox证书颁发机构中去,这样浏览器就信任我们自制的CA证书了。路径为:设置->隐私与安全->查看证书->导入

certificate is not standards compliant,Go技术积累,golang,gin,开发语言,ssl/tls,https,Powered by 金山文档
certificate is not standards compliant,Go技术积累,golang,gin,开发语言,ssl/tls,https,Powered by 金山文档

由于我们证书配置的common name是server.com,因此需要修改本地hosts文件,将下面文字添加到hosts文件中

127.0.0.1 server.com

再次访问https://server.com:10679/test不再阻止

certificate is not standards compliant,Go技术积累,golang,gin,开发语言,ssl/tls,https,Powered by 金山文档

三.实现服务器和客户端双端验证

3.1 服务端代码

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "github.com/gin-gonic/gin"
    "io/ioutil"
    "log"
    "net"
    "net/http"
    "os"
    "os/signal"
    "syscall"
)

var (
    caCert     string = "./certs/ca.crt"
    serverCert string = "./certs/server.crt"
    serverKey  string = "./certs/server.key"
)

func main() {
    router := gin.New()
    router.Use(gin.Logger())

    router.GET("/test", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "success",
        })
    })

    // 客户端CA证书
    certPool := x509.NewCertPool()
    ca, err := os.ReadFile(caCert)
    if err != nil {
        fmt.Printf("load ca err: %s", err)
        return
    }

    if ok := certPool.AppendCertsFromPEM(ca); !ok {
        fmt.Printf("certpool append ca fail.")
        return
    }

    // 可以直接用注释的代码代替最后两行
    //router.RunTLS("0.0.0.0:10679", "./cert/server.cer", "./cert/server.key")
    server := &http.Server{
        Addr:    "server.com:10679",
        Handler: router,
        TLSConfig: &tls.Config{
            ClientAuth: tls.RequireAndVerifyClientCert,
            //这里一定要注意,服务端设置ClientCAs,用于服务端验证客户端证书,客户端设置RootCAs,用户客户端验证服务端证书。设置错误或者设置反了都会造成认证不通过。
            //RootCAs:    certPool,
            ClientCAs: certPool,
        },
    }

    _ = server.ListenAndServeTLS(serverCert, serverKey)
}

3.2 客户端代码

package main

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

func main() {
    pool := x509.NewCertPool()
    caCrt, err := os.ReadFile("./certs/ca.crt")
    if err != nil {
        log.Fatal("read ca.crt file error:", err.Error())
    }
    pool.AppendCertsFromPEM(caCrt)
    cliCrt, err := tls.LoadX509KeyPair("./certs/client.crt", "./certs/client.key")
    if err != nil {
        log.Fatalln("LoadX509KeyPair error:", err.Error())
    }
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            //这里一定要注意,服务端设置ClientCAs,用于服务端验证客户端证书,客户端设置RootCAs,用户客户端验证服务端证书。设置错误或者设置反了都会造成认证不通过。
            RootCAs: pool,
            //ClientCAs:    pool,
            Certificates: []tls.Certificate{cliCrt},
        },
    }
    client := &http.Client{Transport: tr}
    resp, err := client.Get("https://server.com:10679/test")
    if err != nil {
        fmt.Printf("get failed. | err: %s\n", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))

}

四. 整理过程中遇到的bug

4.1 tls: failed to verify certificate: x509: “server.com” certificate is not standards compliant

remote error: tls: bad certificate

这两个报错可能就是客户端或服务端设置参数ClientCAs、RootCAs错误有关。

服务端设置ClientCAs,里面保存客户端的CA证书Pool,用于服务端验证客户端证书。

客户端设置RootCAs,里面保存服务端的CA证书Pool,用户客户端验证服务端证书。

设置错误或者设置反了都会造成认证不通过。

这就属于知道就很简单解决,但找不到错误就很崩溃,本人因为这个小bug竟然熬了一夜,说多了都是泪啊啊啊啊。。。

4.2 use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

这个报错原因是生成证书没有开启SAN扩展,go 1.15 版本开始废弃 CommonName,因此推荐使用 SAN 证书。 这就是1.6、1.9两节配置文件最下面做的事情。重新把证书生成一下。当然,自己生成的证书可以随便改,如果线上证书出现这种情况,我看有的说设置下环境变量GODEBUG 为 x509ignoreCN=0,不过我测试没有效果

这个问题的解决要感谢下面这个博主,我是看了这个帖子解决的问题。

https://blog.csdn.net/weixin_40280629/article/details/113563351

4.3 安全提示

参考2.3解决办法

4.4 证书commonName

这个字段是比较重要的,不要随便配置。服务端、客户端证书认证都会验证host name是否与其一致,不一致会造成认证失败。这也是为什么要修改hosts并用server.com来访问

睡觉睡觉。。。文章来源地址https://www.toymoban.com/news/detail-803588.html

到了这里,关于【GO】29.go-gin支持ssl/tls,即https示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go语言网络编程入门:TCP、HTTP、JSON序列化、Gin、WebSocket、RPC、gRPC示例

    在本文中,我们将介绍Go语言中的网络编程的不同方式,包括TCP、HTTP、Gin框架、WebSocket、RPC、gRPC的介绍与连接实例,并对所有示例代码都给出了详细的注释,最后对每种模式进行了总结。 TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,提供

    2024年02月16日
    浏览(59)
  • Win2008系统IIS7配置ssl证书,类型绑定https时,主机名为灰色无法填写状态,配置微信小程序时配置TLS1.2及以上版本支持

    一、申请ssl证书,本人证书是使用的腾讯云的免费的ssl证书。 申请证书流程不做介绍,可以参考:腾讯云SSL证书—1.申请免费公网SSL证书-腾讯云开发者社区-腾讯云 二、下载证书,解压后得到文件  三、打开IIS管理器  四、选择证书,填入密码  ------------------------------------

    2024年02月03日
    浏览(41)
  • SSL、TLS、HTTPS的关系

    SSL(Secure Sockets Layer),安全套接字协议 TLS(Transport Layer Security),传输层安全性协议 TLS是SSL的升级版,两者几乎是一样的 HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer),建立在SSL协议之上的HTTP协议 介绍下 HTTPS 中间人攻击 参考答案: 针对 HTTPS 攻击主要有 SSL 劫持攻击和

    2024年02月07日
    浏览(39)
  • https 中 ssl/tls 的握手

    如果使用了 https 协议,那么在建立 tcp 连接之后,还会进行 tls 握手。也就是 https 的证书验证和密钥传输的过程。简化的流程如下: 客户端发送请求 服务端返回证书 客户端验证证书,提取公钥,生成对称加密的密钥,用公钥加密后发送给服务端 服务端收到请求,用私钥揭秘

    2024年01月23日
    浏览(41)
  • curl请求https证书过期的问题:SSL certificate problem: certificate has expired

    写了两个系统,系统A使用 curl 去请求系统B,但是不知道为什么会报错 SSL certificate problem: certificate has expired 系统A使用了 https 但是系统B没有使用 https 系统A的SSL并未过期,而且在两个系统在同一台服务器时并未报错,所以不是SSL证书的问题 解决办法: 关闭curl对证书验证,可

    2024年02月16日
    浏览(53)
  • HTTPS、对称/非对称加密、SSL/TLS

    问题描述:HTTP的请求和响应都是明文传输,有安全隐患 HTTPS :HTTPS并不是一个单独的协议,是在 TCP 和 HTTP 之间加入了 SSL/TLS 安全协议,使得报文能够加密传输,SSL是TLS的前身,现在使用的大多都是TLS。 对称加密 :发送方和接收方约定一个同样的规则也就是同一个密钥来对

    2024年04月10日
    浏览(45)
  • 解决GO安装gin框架(go get -u github.com/gin-gonic/gin)超时问题

    🍊gin框架github地址:https://github.com/gin-gonic/gin         按照官方文档安装gin,但是尝试了好几次,包括使用国内网络或者使用梯子,都超时失败了,爆了如下超时错误 🍊 解决方法如下 1、先查看go相关的配置 如上显示GOPROXY配置是https://proxy.golang.org,这个地址已经被墙了,

    2024年02月11日
    浏览(59)
  • linux 使用steam++,steam社区页面报错:Invalid SSL Certificate The SSL certificate for https://steamcommunity.c

    解决方法: 在Chrome浏览器中导入证书: chrome搜索栏输入 chrome://settings/certificates ,选择导入证书 格式需要勾选所有文件,路径在 /home/user/.local/share/Steam++/ 三个全部勾选,点击确定后重新启动steam++和steam即可

    2024年02月12日
    浏览(73)
  • 配置SSL/TLS以启用HTTPS加密通信

    简介 在本教学文章中,我们将学习如何配置Nginx以支持安全套接字层(SSL/TLS),从而启用HTTPS并提供加密通信。SSL/TLS是一种安全协议,用于确保在网络上进行的通信的保密性和完整性。本教程将介绍如何生成SSL证书,配置Nginx以使用SSL/TLS,并启用HTTPS。 前提条件 在开始本教

    2024年02月15日
    浏览(59)
  • HTTPS加密协议详解:TLS/SSL握手过程

    基于RSA握手和密钥交换的客户端验证服务器为示例详解TLS/SSL握手过程。 (1).client_hello 客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息如下: 支持的最高TSL协议版本version,从低到高依次 SS

    2024年02月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包