热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用golang进行证书签发和双向认证

前言数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。证书签发涉及到了非对称加密方面的知识,这里介绍使用golang中的x509标准库进行证书自签发,

前言

数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。证书签发涉及到了非对称加密方面的知识,这里介绍使用golang中的x509标准库进行证书自签发,还有证书签发后如何使用golang进行双向认证.

自签发证书

生成根证书

根证书是CA认证中心给自己颁发的证书,是信任链的起始点.这里我们自己做CA使用openssl命令来生成根证书.

首先生成私钥

openssl genrsa -out key.pem 2048

然后根据私钥提取公钥

openssl rsa -in key.pem -pubout -out key.pub

开始生成X509格式的自签名证书,会要求输入区别名DN的各项信息(国家,城市,组织,姓名,email等.

penssl req -x509 -new -days 365 -key rsakey.pem -out cert.crt

到这里根证书就制作好了,下面开始使用golang根据根证书签发下一级证书.

使用golang自签发证书

关于自签发证书的流程,这里做个简单介绍.golang的x509标准库下有个Certificate结构,这个结构就是证书解析后对应的实体.新证书需要先生成秘钥对,然后使用根证书的私钥进行签名.证书和私钥以及公钥这里使用的是pem编码方式.

首先读取根证书的证书和私钥

//解析根证书
caFile, err := ioutil.ReadFile(rootCa)
if err != nil {
return
}
caBlock, _ := pem.Decode(caFile)
cert, err := x509.ParseCertificate(caBlock.Bytes)
if err != nil {
return
}
//解析私钥
keyFile, err := ioutil.ReadFile(rootKey)
if err != nil {
return
}
keyBlock, _ := pem.Decode(keyFile)
praKey, err := x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
if err != nil {
return
}

然后需要生成新证书的模板,里面的字段根据自己需求填写,

cer := &x509.Certificate{
SerialNumber: big.NewInt(rd.Int63()), //证书序列号
Subject: pkix.Name{
Country: []string{"CN"},
Organization: []string{"Easy"},
OrganizationalUnit: []string{"Easy"},
Province: []string{"ShenZhen"},
CommonName: equi.Code,
Locality: []string{"ShenZhen"},
},
NotBefore: time.Now(), //证书有效期开始时间
NotAfter: time.Now().AddDate(1, 0, 0), //证书有效期结束时间
BasicConstraintsValid: true, //基本的有效性约束
IsCA: false, //是否是根证书
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, //证书用途(客户端认证,数据加密)
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment,
EmailAddresses: []string{"test@test.com"},
IPAddresses: []net.IP{net.ParseIP("192.168.1.59")},
}

当获取到这种信息后就可以签发证书了,key和ca就是签发好的证书和私钥.

//生成公钥私钥对
priKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return
}
ca, err = x509.CreateCertificate(rand.Reader, equiCer, rootCa, &priKey.PublicKey, rootKey)
if err != nil {
return
}
//编码证书文件和私钥文件
caPem := &pem.Block{
Type: "CERTIFICATE",
Bytes: ca,
}
ca = pem.EncodeToMemory(caPem)
buf := x509.MarshalPKCS1PrivateKey(priKey)
keyPem := &pem.Block{
Type: "PRIVATE KEY",
Bytes: buf,
}
key = pem.EncodeToMemory(keyPem)

使用golang进行双向认证

客户端

//加载客户端证书
//这里加载的是服务端签发的
cert, err := tls.LoadX509KeyPair("client_cert.pem", "client_key.pem")
if err != nil {
log.Fatalln(err)
}
config := &tls.Config{
//这里先不验证服务端证书,是自己签发的呀
InsecureSkipVerify: true,
Certificates: []tls.Certificate{cert},
}
raddr, err := net.ResolveTCPAddr("tcp", "192.168.1.59:6001")
if err != nil {
log.Fatalln(err)
}
conn, err := net.DialTCP("tcp", nil, raddr)
if err != nil {
log.Fatalln(err)
}
tlsConn := tls.Client(conn, config)

tlsConn就和net.Conn一样了,当调用Wirte时就会进行握手,如果服务端证书不符合要求,就会返回错误.

服务端

//这里读取的是根证书
buf, err := ioutil.ReadFile(d.conf.Tls.CA)
if err != nil {
return
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(buf)
//加载服务端证书
cert, err := tls.LoadX509KeyPair(d.conf.Tls.Cert, d.conf.Tls.Key)
if err != nil {
return
}
tlsConfig := &tls.Config
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: pool,
}
//accept到conn后
tlsConn := tls.Server(conn, tlsConfig)

这个tlsConn和客户端的一样,也可以手动调用Handshake进行握手.

结语

这里只是进行了简单介绍,关于证书的知识还不止这些.比如x509标准库还可以生成签发证书请求,解析证书吊销列表等.多加练习才能对证书方面知识理解更深.


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
author-avatar
中哒瘋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有