OpenSSL 生成 gRpc SSL证书

Grpc Ssl Generate

Posted by BlueFat on Sunday, December 6, 2020

TLS 概述

传输层安全 (TLS) 对通过 Internet 发送的数据进行加密,以确保窃听者和黑客无法看到您传输的内容,这对于密码、信用卡号和个人通信等私人和敏感信息特别有用。

1、什么是 TLS?

传输层安全 (TLS) 是一种 Internet 工程任务组 ( IETF ) 标准协议,可在两个通信计算机应用程序之间提供身份验证、隐私和数据完整性。它是当今使用最广泛部署的安全协议,最适合需要通过网络安全交换数据的 Web 浏览器和其他应用程序。这包括 Web 浏览会话、文件传输、虚拟专用网络 (VPN) 连接、远程桌面会话和 IP 语音 (VoIP)。最近,TLS 被集成到包括 5G 在内的现代蜂窝传输技术中,以保护整个无线电接入网络 ( RAN ) 的核心网络功能。

2、TLS 的工作流程

TLS 使用客户端 - 服务器握手机制来建立加密和安全的连接,并确保通信的真实性。

  • 通信设备交换加密功能。
  • 使用数字证书进行身份验证过程以帮助证明服务器是它声称的实体。
  • 发生会话密钥交换。在此过程中,客户端和服务器必须就密钥达成一致,以建立安全会话确实在客户端和服务器之间的事实 —— 而不是在中间试图劫持会话的东西。

gRPC TLS机制

1、概述

gRPC 建立在 HTTP/2 协议之上,对 TLS 提供了很好的支持。当不需要证书认证时,可通过 grpc.WithInsecure () 选项跳过了对服务器证书的验证,没有启用证书的 gRPC 服务和客户端进行的是明文通信,信息面临被任何第三方监听的风险。为了保证 gRPC 通信不被第三方监听、篡改或伪造,可以对服务器启动 TLS 加密特性。

gRPC 内置了以下 encryption 机制:

  • SSL / TLS:通过证书进行数据加密;
  • ALTS:Google 开发的一种双向身份验证和传输加密系统。
    • 只有运行在 Google Cloud Platform 才可用,一般不用考虑。

2、gRPC 加密类型

  • insecure connection:不使用 TLS 加密
  • server-side TLS:仅服务端 TLS 加密
  • mutual TLS:客户端、服务端都使用 TLS 加密 我们前面的例子都是明文传输的,使用的都是 insecure connection,通过指定 WithInsecure option 来建立 insecure connection,不建议在生产环境使用。

TLS 证书解说

1)流程 服务端 TLS 具体包含以下几个步骤:

  • 制作证书,包含服务端证书和 CA 证书;
  • 服务端启动时加载证书;
  • 客户端连接时使用 CA 证书校验服务端证书有效性。

也可以不使用 CA 证书,即服务端证书自签名。

2)什么是 CA?CA 证书又是什么?

  • CA 是 Certificate Authority 的缩写,也叫 “证书授权中心”。它是负责管理和签发证书的第三方机构,作用是检查证书持有者身份的合法性,并签发证书,以防证书被伪造或篡改。

CA 实际上是一个机构,负责 “证件” 印制核发。就像负责颁发身份证的公安局、负责发放行驶证、驾驶证的车管所。

  • CA 证书就是 CA 颁发的证书。我们常听到的数字证书就是 CA 证书,CA 证书包含信息有: 证书拥有者的身份信息,CA机构的签名,公钥和私钥。

    • 身份信息:用于证明证书持有者的身份
    • CA 机构的签名:用于保证身份的真实性
    • 公钥和私钥:用于通信过程中加解密,从而保证通讯信息的安全性

3)什么是 SAN? SAN (Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析。

我们在用 go 1.15 版本以上,用 gRPC 通过 TLS 建立安全连接时,会出现证书报错问题:

panic: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate
is not valid for any names, but wanted to match localhost"

造成这个 panic 的原因是从 go 1.15 版本开始废弃 CommonName,我们没有使用官方推荐的 SAN 证书(默认是没有开启 SAN 扩展)而出现的错误,导致客户端和服务端无法建立连接。

Openssl 生成TLS证书

https://blog.csdn.net/u013360850/article/details/115278341

文件certificate.conf的内容

[req]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C = CN
ST = BJ
O = helloworlde
CN = localhost
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = ::1
IP.2 = 127.0.0.1


生成自签名的证书,因为 Netty 的 SslContextBuilder 和 SslContext 仅支持 PKCS8 格式的 key,所以需要将其他格式的 key 转换为 PKCS8 格式
openssl genrsa -out ca.key 4096 
openssl req -new -x509 -key ca.key -sha256 -subj "/C=US/ST=NJ/O=CA, Inc." -days 3650 -out ca.cert 
openssl genrsa -out private.key 4096 
openssl req -new -key private.key -out private.csr -config certificate.conf 
openssl x509 -req -in private.csr -CA ca.cert -CAkey ca.key -CAcreateserial -out server.pem -days 3650 -sha256 -extfile certificate.conf -extensions req_ext 
openssl pkcs8 -topk8 -nocrypt -in private.key -out server.key
执行命名后,会生成多个文件,其中 Server 端需要私钥 server.key 以及证书 server.pem,客户端需要证书 server.pem

生成 CA 根证书

ca.conf

cat << EOF > 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 = Guangdong
localityName                = Locality Name (eg, city)
localityName_default        = Guangzhou
organizationName            = Organization Name (eg, company)
organizationName_default    = DEV
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost
EOF

1.生成 ca 私钥,得到 ca.key

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

2.生成 ca 证书签发请求,得到 ca.csr

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

这里一直回车就好了 openssl req:生成自签名证书,-new 指生成证书请求、-sha256 指使用 sha256 加密、-key 指定私钥文件、-x509 指输出证书、-days 3650 为有效期,此后则输入证书拥有者信息

3.生成 ca 根证书,得到 ca.crt

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

生成 Server 证书

server.conf

cat << EOF > server.conf
[ req ]
default_bits       = 2048
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 = Guangdong
localityName                = Locality Name (eg, city)
localityName_default        = Guangzhou
organizationName            = Organization Name (eg, company)
organizationName_default    = DEV
commonName                  = CommonName (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
IP.1    = 127.0.0.1
IP.2    = 192.168.10.18
DNS.1   = rocketmq-grpc
DNS.2   = rocketmq.demo.example.com 
EOF
  • IP.1和DNS.x 这里很重要,会匹配授权

1.生成私钥,得到 server.key

openssl genrsa -out server.key 4096

2.生成证书签发请求,得到 server.csr

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

这里也一直回车就好。

Rocketmq TLS配置

# 移除私钥密码
openssl rsa -passin pass:3333 -in server.key -out server.key
# 私钥转换为X.509
openssl pkcs8 -topk8 -nocrypt -in server.key -out server.pem

gRPC(五)进阶:通过TLS建立安全连接