当前位置: 首页 > news >正文

【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 mainimport ("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

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

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

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

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

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

127.0.0.1 server.com

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

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

3.1 服务端代码

package mainimport ("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 mainimport ("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来访问

睡觉睡觉。。。

相关文章:

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

本文为演示采用自签名证书一.生成证书通过openssl工具生成证书1.1 安装opensslmacos通过brew安装brew install openssl1.2 生成跟证书私钥openssl genrsa -out ca.key 40961.3 准备配置文件vim ca.conf内容如下[ req ] default_bits 4096 distinguished_name req_disti…...

逻辑仿真工具VCS的使用-Makefile

Gvim写RTL code,VCS仿真,Verdi看波形,DC做综合下约束,Primetime做STA,Spyglass做异步时序分析。 VCS全称Verilog Computer Simulation ,VCS是逻辑仿真EDA工具的编译源代码的命令。要用VCS做编译仿…...

信息系统安全技术

一、信息安全的有关概念 1. 属性2. 四个安全层次※3. 信息安全保护等级※4. 安全保护能力的等级※ 二、信息加密、解密与常用算法 1. 对称加密2. 非对称加密3. Hash函数4. 数字签名5. 认证 三、信息系统安全 1. 计算机设备安全2. 网络安全3. 操作系统安全4. 数据库安全5. 应用系…...

【数据结构】最小生成树(Prim算法,普里姆算法,普利姆)、最短路径(Dijkstra算法,迪杰斯特拉算法,单源最短路径)

文章目录前置问题问题解答一、基础概念:最小生成树的定义和性质(1)最小生成树(Minimal Spanning Tree)的定义(2)最小生成树(MST)的性质二、如何利用MST性质寻找最小生成树…...

Session与Cookie的区别(一)

从我刚开始学程序时这一题就常出现在面试考题里,一直到现在都还是能看见这个问题。 这个问题重要吗?我觉得蛮重要的。因为 Session 所代表的是「状态」,如果没有了状态,一大堆功能都会失效。 对于工程师来说必须去理解什么是 Sess…...

【Java】重载和重写的区别

重载(Overload) 在同一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同…...

AcWing 第 90 场周赛

目录A、首字母大写B、找数字C、构造字符串A、首字母大写 原题链接&#xff1a;AcWing 4806. 首字母大写 签到题。 #include <bits/stdc.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string s;cin >> s;s[0] toupper(s[0]);…...

刚刚,体验了一把Bing chat很爽

文章目录刚刚&#xff0c;体验了一把Bing chat很爽你能做啥&#xff1f;与chatgpt有什么不同&#xff1f;以下是Bingchat的 10个新功能1⃣️在网上搜索结果2⃣️摘要链接3⃣️对话助手4⃣️向您发送实际信息&#xff0c;正确的链接5⃣️在单个查询中执行多个搜索6⃣️玩冒险游戏…...

牛客网Python篇数据分析习题(二)

1.现有一个Nowcoder.csv文件&#xff0c;它记录了牛客网的部分用户数据&#xff0c;包含如下字段&#xff08;字段与字段之间以逗号间隔&#xff09;&#xff1a; Nowcoder_ID&#xff1a;用户ID Level&#xff1a;等级 Achievement_value&#xff1a;成就值 Num_of_exercise&a…...

如何用Python打包好exe文件,并替换图标

前言 Python打包&#xff1f;打包exe文件&#xff1f;怎么操作&#xff1f; ok&#xff0c;今天我来分享分享&#xff0c;教你们如何打包号文件&#xff0c;顺便还来展示一下&#xff0c;如何替换好图标 首先把你的代码准备好&#xff0c;尽量不要中文路径&#xff0c;容易报…...

NFC概述摘要

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 原理来说,NFC和Wi-Fi类似,利用无线射频技术来实现设备间通信。NFC的工作频率为13.5…...

Python-项目实战--贪吃蛇小游戏(1)

1.贪吃蛇游戏规则贪吃蛇游戏规则如下:1.1开始和结束贪吃蛇初始出现在游戏窗口的左上角位置,体长共有3节游戏过程中&#xff0c;一旦蛇头撞到了窗口的边缘或者身体的其他部位,游戏结束游戏过程中&#xff0c;点击游戏窗口的关闭按钮&#xff0c;或者按下ESC键可以直接退出游戏一…...

vscode sftp从linux服务器下载文件至本地:No such file or dictionary【已解决】

在服务器跑完程序需要下载数据的时候报错&#xff1a; [warn] ENOENT: no such file or directory, open /home/LIST_2080Ti/.ssh/config load /home/LIST_2080Ti/.ssh/config failed 完整报错内容如下&#xff1a; [02-10 08:38:47] [info] config at /home/LIST_2080Ti {&q…...

详解指针(2)(初阶版)

前言&#xff1a;内容包括&#xff1a;指针运算&#xff0c;指针和数组&#xff0c;二级指针&#xff0c;指针数组 详解指针&#xff08;1&#xff09;&#xff08;点击即跳转&#xff09; part 1&#xff1a;指针运算 1 指针-整数 以如下代码为例&#xff1a;初始化数组内容…...

超详细讲解字符串查找函数(保姆级教程!!!)

超详细讲解字符串查找函数&#xff08;保姆级教程&#xff01;&#xff01;&#xff01;&#xff09;字符串查找函数strstr函数strstr函数的使用strstr函数的模拟实现strtok函数strtok函数的使用strtok函数的模拟实现strpbrk函数strpbrk函数的使用strpbrk函数的模拟实现strcspn…...

LeetCode-1138. 字母板上的路径【哈希表,字符串】

LeetCode-1138. 字母板上的路径【哈希表&#xff0c;字符串】题目描述&#xff1a;解题思路一&#xff1a;首先考虑坐标位置&#xff0c;字符是有序的从0开始&#xff0c;当前字符c的行为(c-a)/5,列为(c-a)%5。其次是考虑特殊情况z。若当前从‘z’开始则只能往上走;若是其他字符…...

Vue 可配置化的路由缓存(Vu2 Vue3)

Vue 可配置化的路由缓存&#xff08;Vu2 & Vue3&#xff09; 1 介绍 在Vue的项目当中&#xff0c;路由缓存是一个比较常见的功能&#xff0c;譬如&#xff0c;从列表页面进入到详情页面&#xff0c;返回到列表页面时&#xff0c;如果可以保持列表的状态&#xff0c;那用户…...

Linux VPU驱动

1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. 概述 VPU 是用来进行图像、视频数据进行硬件编、解码的硬件模块。内部集成了 Encoder、Decoder 功能部件进行图像、视频数据进行硬件编、解码&a…...

spring 笔记

一、spring概述 1.1 spring介绍 spring是一个轻量级的控制反转和面向切面的容器框架&#xff0c;用来解决企业项目开发的复杂度问题---解耦 轻量级&#xff1a;体积小&#xff0c;对代码没有侵入性控制反转&#xff1a;IOC inverse of control&#xff0c; 把创建对象的工作交…...

Java日志框架学习

首先&#xff0c;Java日志框架可以分为两类&#xff1a;门面型日志框架和记录型日志框架。 门面型日志框架 JCL&#xff1a;Java日志接口&#xff0c;后更名为Commons LoggingSLF4J&#xff1a;是一套简易Java日志门面&#xff0c;本身并无日志的实现 记录型日志框架 JUL&a…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...