前言

在进行项目总结的时候,领导提出有关数据安全的问题。总结会议过后,自己查阅了一下资料,发现基于CA的TLS证书认证方案是一个很好的选择,虽然项目本身也有关于数据安全的处理,但是从远不及TLS的处理方式。

本文只介绍tls的开发,采用go语言,不会涉及到太多专业的词语。


制作自签名证书

初始目录如下:

grpc-tls/
├── configs
│ ├── cert # 存放证书相关的目录
├── cmd

CA

为了保证证书的可靠性和有效性,在这里可引入 CA 颁发的根证书的概念。CA就是专门用自己的私钥给别人进行签名的单位或者机构,其遵守 X.509 标准,即无论是客户端还是服务端都是使用CA来签发证书。

根证书

根证书(root certificate)是属于根证书颁发机构(CA)的公钥证书。我们可以通过验证 CA 的签名从而信任 CA ,任何人都可以得到 CA 的证书(含公钥),用以验证它所签发的证书(客户端、服务端)。

它包含了公钥和密钥。

CA公钥

进入cert目录

openssl genrsa -out ca.key 2048
  • openssl genrsa:生成RSA私钥,命令的最后一个参数,将指定生成密钥的位数,如果没有指定,默认512

CA秘钥(证书)

openssl req -new -x509 -days 365 -key ca.key -out ca.pem
  • -x509:证书文件格式为x509,目前TLS默认只支持这种格式的证书
  • -days 365:证书有效期1年
  • -out ca.pem:生成的私钥保存到ca.pem

要填写的信息:

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ca.com
Email Address []:
  • 生成的过程中会要求填一些信息,除了Common Name要取一个容易区分的名字之外,其它都可以随便填写,我们在这里将它填为ca.com.

目录

grpc-tls/
├── configs
│ ├── cert # 存放证书相关的目录
│ ├── ca.key
│ └── ca.pem
├── cmd

服务器证书相关

服务器key

# openssl genrsa -out server.key 2048
或者
openssl ecparam -genkey -name secp384r1 -out server.key
  • openssl genrsa:生成RSA私钥,命令的最后一个参数,将指定生成密钥的位数,如果没有指定,默认512
  • openssl ecparam:生成ECC私钥,命令为椭圆曲线密钥参数生成及操作,本文中ECC曲线选择的是secp384r1

生成 CSR(证书申请文件)

CSR 是**Cerificate Signing Request **的英文缩写,为证书申请文件,在服务器私钥的基础上加上一些申请人的属性信息,比如我是谁,来自哪里,名字叫什么,证书适用于什么场景等的信息,然后带上进行的签名,发给CA(私下安全的方式发送),带上自己签名的目的是为了防止别人篡改文件。

openssl req -new -key server.key -out server.csr

要填写的信息:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:domain.com
Email Address []: Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
  • 生成的过程中会要求填一些信息,除了Common Name要取一个容易区分的名字之外,其它都可以随便填写,我们在这里将它填为domain.com;
  • 密码也是建议填写;
  • 注意和ca证书的不同。

基于 CA 签发

使用CA的公钥对申请文件进行签名

openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in server.csr -out server.pem
  • -sha256:生成的证书里面使用sha256作为摘要算法
  • 由于需要往生成的证书里写入签名者的信息,所以这里需要ca.pem,因为只有这里有CA的描述信息,ca.key里面只有公钥的信息。

目录

grpc-tls/
├── configs
│ ├── cert # 存放证书相关的目录
│ ├── ca.key
│ └── ca.pem
│ ├── server.csr
│ └── server.key
│ └── server.pem
├── cmd

客户端证书相关

此生成的证书可用于浏览器、java、tomcat、golang等。

客户端key

openssl ecparam -genkey -name secp384r1 -out client.key

生成CSR(证书申请书)

openssl req -new -key client.key -out client.csr

要填写的信息:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:domain.com
Email Address []: Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
  • Common Name要取一个容易区分的名字之外,填为domain.com,和服务器的CSR保持一致;
  • 密码也是建议填写;
  • 注意和ca证书的不同。

基于CA签发

openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in client.csr -out client.pem

生成客户端p12格式根证书

该证书用于导入浏览器使用。

openssl pkcs12 -export -clcerts -in client.pem -inkey client.key -out client.p12

目录

grpc-tls/
├── configs
│ ├── cert # 存放证书相关的目录
│ ├── ca.key
│ └── ca.pem # 导入浏览器使用
│ ├── server.csr
│ └── server.key
│ └── server.pem
│ ├── client.csr
│ └── client.key
│ └── client.pem
│ └── client.p12 # 导入浏览器使用
├── cmd

证书如何验证

下面以浏览器为例,说明证书的验证过程:

  • 在TLS握手的过程中,浏览器得到了网站的证书(.p12)

  • 打开证书,查看是哪个CA签名的这个证书(.p12)

  • 在自己信任的CA库中,找相应CA的证书(ca.pem),

  • 用CA证书里面的公钥解密网站证书上的签名,取出网站证书的校验码(指纹),然后用CA证书中摘要算法(比如sha256)算出出网站证书的校验码,如果校验码和签名中的校验码对的上,说明这个证书是合法的,且没被人篡改过

  • 读出里面的CN,对于网站的证书,里面一般包含的是域名

  • 检查里面的域名和自己访问网站的域名对不对的上,对的上的话,就说明这个证书确实是颁发给这个网站的

  • 到此为止检查通过

如果浏览器发现证书有问题,一般是证书里面的签名者不是浏览器认为值得信任的CA,浏览器就会给出警告页面,这时候需要谨慎,有可能证书被掉包了。如访问12306网站,由于12306的证书是自己签的名,并且浏览器不认为12306是受信的CA,所以就会给警告,但是一旦你把12306的根证书安装到了你的浏览器中,那么下次就不会警告了,因为你配置了浏览器让它相信12306是一个受信的CA。


在浏览器中导入证书

导入证书

  • 详细步骤百度即可....

  • 个人导入client.p12证书

  • 受信任的根证书颁发机构导入ca.pem证书

修改域名

ca.pem这个证书是发给domain.com的,而不是127.0.0.1,所以在C:\Windows\System32\drivers\etc\hosts添加一记录:

127.0.0.1   domain.com

测试完成之后记得手动将127.0.0.1 domain.comC:\Windows\System32\drivers\etc\hosts里面删掉。


golang服务端

目录

grpc-tls/
├── configs
│ ├── cert # 存放证书相关的目录
│ ├── ca.key
│ └── ca.pem # 导入浏览器使用
│ ├── server.csr
│ └── server.key
│ └── server.pem
│ ├── client.csr
│ └── client.key
│ └── client.pem
│ └── client.p12 # 导入浏览器使用
├── cmd
│ ├── main.go

main.go

package main

import (
"crypto/tls"
"crypto/x509"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"net/http"
"time"
) func main() {
router := gin.Default()
router.GET("/test", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "test",
})
}) // 启动https方式访问
cert, err := tls.LoadX509KeyPair("./configs/cert/server.pem", "./configs/cert/server.key")
if err != nil {
log.Fatalf("tls.LoadX509KeyPair err: %v", err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("./configs/cert/ca.pem")
if err != nil {
log.Fatalf("ioutil.ReadFile err: %v", err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
log.Fatalf("certPool.AppendCertsFromPEM err")
}
ReadTimeout := time.Duration(60) * time.Second
WriteTimeout := time.Duration(60) * time.Second s := &http.Server{
Addr: ":8090",
Handler: router,
ReadTimeout: ReadTimeout,
WriteTimeout: WriteTimeout,
MaxHeaderBytes: 1 << 20,
TLSConfig:&tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12,
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
},
} s.ListenAndServeTLS("./configs/cert/server.pem","./configs/cert/server.key")
}

测试

在浏览器输入https://domain.com:8090/test


参考

SSL/TLS及证书概述

带入gRPC:TLS 证书认证

TLS示例开发-golang版本的更多相关文章

  1. 崔用志-微信开发-java版本

    崔用志-微信开发-java版本 今天看到一些关于微信开发的知识蛮好的博客,分享给大家,希望对大家有帮助. 微信开发准备(一)--Maven仓库管理新建WEB项目 微信开发准备(二)--springmv ...

  2. PHP Extension开发(Zephir版本)

    上篇介绍了C语言开发PHP扩展的方法, 现在介绍使用Zephir开发扩展的方法. 关于Zephir需要简单介绍一下: Zephir 是为PHP开发人员提供的能够编写可编译/静态类型的高级语言.是优秀的 ...

  3. ios开发数据库版本迁移手动更新迭代和自动更新迭代艺术(二)

    由于大家都热衷于对ios开发数据库版本迁移手动更新迭代和自动更新迭代艺术(一)的浏览下面我分享下我的源文件git仓库: 用法(这边我是对缓存的一些操作不需要可以省去):https://github.c ...

  4. iOS 开发之版本上线更新流程

    iOS 开发之版本上线更新流程   把自己app上线的流程记录下来,希望能够让自己加深印象,也能帮助到一些人便是极好的! 证书和描述文件的配置就不写了,直接配置工程吧. 大致把我自己上线的流程写一下: ...

  5. Sublime for mac 开发Golang : 一步步环境配置

    安装Golang 在官网上直接下载安装包就可以了.下载pkg格式的最新安装包 ,直接双击运行,一路按照提示操作就可以完成安装. 或者使用brew进行安装 brew install go 完成安装之后, ...

  6. IntelliJ IDEA开发golang环境配置

    IntelliJ IDEA开发golang环境配置 首先把GO安装好...(自行安装,附上一篇我之前写的MAC安装GO) 安装IntelliJ IDEA,下载地址: https://www.jetbr ...

  7. vue前端+java后端 vue + vuex + koa2开发环境搭建及示例开发

    vue + vuex + koa2开发环境搭建及示例开发 https://segmentfault.com/a/1190000012918518 vue前端+java后端 https://blog.c ...

  8. 上传golang 版本SDK

    在上传的时候,文件都上传成功了,但是返回的信息里面errcode 404 token 是"".是不是因为我的callbackUrl(随便写的) 写错导致的. 上传golang 版本 ...

  9. Golang版本的rocksdb-对gorocksdb的封装

    rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...

随机推荐

  1. websocket协议学习

    一 实验代码 client.html websocket_server.go package main import ( "crypto/sha1" "encoding/ ...

  2. SQL Server 命名实例更改端口进行发布订阅

    原文:SQL Server 命名实例更改端口进行发布订阅 两台数据库服务器,都没有加入域,都安装多实例,端口也不一样了.现在使用命名实例进行复制,折腾了好久,才发现解决方法. 服务器A:myserve ...

  3. SQLServer 复制中移除和添加发布而不初始化所有项目

    原文:SQLServer 复制中移除和添加发布而不初始化所有项目 -- 若提前"禁止架构更改",新增的列不会自动添加大发布,此时应使用 sp_articlecolumn 添加列 E ...

  4. Dropbox是同步盘,Box.net是网盘(所以要学习Box)

    自从能无缝用Dropbox后,确实得瑟了很久,但只有可怜巴巴的2G空间,搞不出什么妖蛾子,dropbox的好用,世所共知.百度云盘2T的空间,我却不敢把重要的东西放在里面. 在还没有优盘的时候,我常常 ...

  5. D7下FastMM的使用

    原文出处:http://hi.baidu.com/showwindows/blog/item/5b7ac601c487c605728da573.html FastMM 快速MM:-),在D2006和2 ...

  6. IT++数学、信号、通讯类库,Blitz++数学,Armadillo 线性代数,Dlib网络,线程,图形,数学,图像,数据挖掘/机器学习,XML等等

    https://en.wikipedia.org/wiki/Blitz%2B%2B https://en.wikipedia.org/wiki/IT%2B%2B https://en.wikipedi ...

  7. shell多线程(2)之基于管道实现并发

    在shell脚本里批量执行程序是比较常见的方式,如果程序很多,每个执行时间比较长,则顺序执行需要花费大量的时间. 此时并发就成为我们考虑的方向. 上篇<shell多线程>中我们已经简单实现 ...

  8. Linux下python多版本多环境介绍

     一.python多版本配置说明 安装python相关依赖 [root@centos6 ~]# yum install -y gcc make patch gdbm-devel openssl-dev ...

  9. Python 爬虫从入门到进阶之路(七)

    在之前的文章中我们一直用到的库是 urllib.request,该库已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Hum ...

  10. spring boot 2.x 系列 —— spring boot 整合 redis

    文章目录 一.说明 1.1 项目结构 1.2 项目主要依赖 二.整合 Redis 2.1 在application.yml 中配置redis数据源 2.2 封装redis基本操作 2.3 redisT ...