只有xx.key和xx.pem时,https客户端如何避免中间人攻击,确保证书没问题?

jan-bar · · 1713 次点击 · 开始浏览    置顶

我通过阿里云申请的证书里面只有`xx.pem`和`xx.key`这两个文件,我查找了很多证书相关的资料,客户端确认服务器证书貌似需要`ca.crt`这种CA证书,我没有这个。然后我查了下中间人攻击就是有人替换了证书让客户端以为证书没问题,但实际用的是中间人给的证书。 所以我尝试如下代码,不知道可不可以防止中间人攻击,我的客户端直接读取`xx.pem`文件和go库连接https服务器获取的证书内容进行比较,如果不一样则说明被篡改,终止当前连接。我不知道我这样做对不对,有没有大佬确认一下,或者有更好方案啊? 原始需求就是当只有`xx.pem`和`xx.key`服务器证书文件时,如何保证客户端连接是没有问题的? ```go package main import ( "bytes" "crypto/tls" "crypto/x509" "encoding/pem" "errors" "fmt" "io" "net/http" "os" ) func main() { err := getPem() if err != nil { panic(err) } err = httpGet() if err != nil { panic(err) } } var ( pemRawCerts [][]byte // xx.pem读取的原始数据 errCheckPem = errors.New("check xx.pem error") ) func getPem() error { certPEMBlock, err := os.ReadFile(`xxx.pem`) if err != nil { return err } var certDERBlock *pem.Block for { certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) if certDERBlock == nil { break } if certDERBlock.Type == "CERTIFICATE" { tmp := make([]byte, len(certDERBlock.Bytes)) copy(tmp, certDERBlock.Bytes) pemRawCerts = append(pemRawCerts, tmp) } } return nil } func httpGet() error { c := http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ VerifyPeerCertificate: func(data [][]byte, verifiedChains [][]*x509.Certificate) error { if len(data) == len(pemRawCerts) { for i := len(data) - 1; i >= 0; i-- { if !bytes.Equal(data[i], pemRawCerts[i]) { return errCheckPem } } // 只有当证书的每一项都正确才确定当前连接没问题 return nil } return errCheckPem }, }, }, } resp, err := c.Get("https://xxx.com") if err != nil { return err } defer resp.Body.Close() n, err := io.Copy(io.Discard, resp.Body) fmt.Println(n) return err } ```

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1713 次点击  
加入收藏 微博
6 回复  |  直到 2022-10-12 09:44:08
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传