問題
golang 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"
造成的原因是因為我們用的證書,並沒有開啟SAN擴展(默認是沒有開啟SAN擴展)所生成的,
導致客戶端和服務端無法建立連接
開始解決問題
使用開啟擴展SAN的證書
什么是 SAN
SAN(Subject Alternative Name) 是 SSL 標准 x509 中定義的一個擴展。使用了 SAN 字段的 SSL 證書,可以擴展此證書支持的域名,使得一個證書可以支持多個不同域名的解析。
生成CA根證書
新建 ca.conf
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 = GuangDong localityName = Locality Name (eg, city) localityName_default = GuangZhou 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
生成ca秘鑰,得到ca.key
openssl genrsa -out ca.key 4096
生成ca證書簽發請求,得到ca.csr
openssl req \ -new \ -sha256 \ -out ca.csr \ -key ca.key \ -config ca.conf
shell交互時一路回車就行
生成ca根證書,得到ca.crt
openssl x509 \ -req \ -days 3650 \ -in ca.csr \ -signkey ca.key \ -out ca.crt
生成終端用戶證書
准備配置文件,得到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 = GuangDong localityName = Locality Name (eg, city) localityName_default = GuangZhou organizationName = Organization Name (eg, company) organizationName_default = Sheld commonName = linyouyi commonName_max = 64 commonName_default = linyouyi [ req_ext ] subjectAltName = @alt_names [alt_names] DNS.1 = www.linyouyi.com IP = 127.0.0.1
生成秘鑰,得到server.key
openssl genrsa -out server.key 2048
生成證書簽發請求,得到server.csr
openssl req \ -new \ -sha256 \ -out server.csr \ -key server.key \ -config server.conf
shell交互時一路回車就行
用CA證書生成終端用戶證書,得到server.crt
openssl x509 \ -req \ -days 3650 \ -CA ca.crt \ -CAkey ca.key \ -CAcreateserial \ -in server.csr \ -out server.pem\ -extensions req_ext \ -extfile server.conf
現在證書已經生成完畢, server.pem 和 server.key就是我們需要的證書和密鑰
服務端代碼:
creds, err := credentials.NewServerTLSFromFile("./keys/server.pem", "./keys/server.key")
客戶端代碼:
creds, err := credentials.NewClientTLSFromFile("./keys/server.pem", "linyouyi")
報以下錯
panic: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate is valid for www.linyouyi.com, not linyouyi" goroutine 1 [running]: main.main() D:/golang/grpc/examples/grpcSSL/client.go:35 +0x7d4 exit status 2
改為面的就沒問題
creds, err := credentials.NewClientTLSFromFile("./keys/server.pem", "www.linyouyi.com")
原文鏈接:https://blog.csdn.net/m0_37322399/article/details/117308604