证书与https

证书与https

为什么要使用证书

非对称加密存在公钥分发困难的问题
  1. 直接传递公钥,容易被截取
  2. 放到固定的位置,容易被替换
解决办法

引入第三方认证机构,CA(Certificate Authority)

CA机构是一系列具有社会公信力的机构的总称,它们负责为厂商提供数字证书(有公钥),从而解决公钥分发困难的问题

证书使用流程

证书与https_第1张图片

https

http:应用层协议,标准协议

https:不是标准协议,http +ssl(security socket layer)

以访问百度为例

  1. 百度首先在本地生成秘钥对(也可以由CA帮忙生成)
  2. 将公钥发送给CA机构(CA也有自己的公钥私钥)
  3. CA对百度的公钥进行处理,生成输入百度数字证书(CA根证书签发的,CA的私钥)。 服务器得到证书
  4. 客户浏览器访问百度,百度会把自己的证书发送会浏览器
  5. 浏览器会认证这个证书是否有效(操作系统内置了各大主流CA机构的根证书)
  6. 如果证书有效:
  • 访问ip与证书一直
  • 证书在有效期内
    ….
    百度得到证明。
  1. 如果认证无效,Not Secure,当然了用户也可以选择继续浏览

如果证书有效,客户的浏览器可以得到服务器的(公钥:在证书内),接下来交互就开始使用对称加密。

  1. 浏览器生成对称秘钥,使用服务器的公钥加密,发送给服务器。
  2. 服务器使用私钥解开秘钥。使用秘钥加密数据做应答。
  3. 接下来所有的数据交互都使用对称加密进行

Linux下生成自签名证书

  1. 生成私钥

    openssl genrsa -out server.key 1024 //不加密
    

    openssl genrsa -des3 -out server.key 1024  //使用des3加密
    
  2. 使用私钥生成csr(证书签名请求)

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

    查看csr详情:

    openssl req -in server.csr -text
    
  3. 生成自签名证书(用自己的key给自己的csr签名)

    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
    

    查看自签名证书:

    openssl x509 -in server.crt -text
    

go语言简单实现https服务器和客户端

服务器
func main() {

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello world"))
	})

	fmt.Println("服务器启动...")
	// func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error 
	err := http.ListenAndServeTLS(":8082", "server.crt", "server.key", nil)
	if err != nil {
		fmt.Println("err :", err)
	}
}
客户端

注意:

  1. client.Get()里的URL必须是生成csr时Common Name (e.g. server FQDN or YOUR name) []:后面你输入的内容,这里我输入了www.it.com,还需要注意的是,要把此项添加到/etc/hosts中,打开后添加127.0.0.1 www.it.com
  2. 我们需要自己校验证书是否有效,这就需要我们把服务器证书的根证书添加到根证书列表中(我们是自签名证书,”server.crt“就是当前服务器的根证书),否则会报错(err: Get https://www.it.com:8082: x509: certificate signed by unknown authority)。
func main() {
//需要告诉client,我们认可ca
// 	1. 读取证书
	caCert, err := ioutil.ReadFile("server.crt")
	if err != nil {
		fmt.Println("read server.crt failed : ", err)
		return
	}

// 2. 创建ca池,ca pool
	//返回一个新的,空的ca池
	capool := x509.NewCertPool()

// 3. 将我们认可的根证书,添加至ca pool
	ok := capool.AppendCertsFromPEM(caCert)
	if !ok {
		fmt.Println("添加ca 池失败!")
		return
	}

// 4. 创建tls结构,填入pool(TLS相当于是SSL的后续版本)
	config := tls.Config{
		//将拼凑好的ca池配置到tls配置结构中
		RootCAs: capool,
	}

// 5. 创建client 通道
	//创建http客户端
	client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &config,
		},
	}

	//发起get请求
	response, err := client.Get("https://www.it.com:8082")
	if err != nil {
		fmt.Println("err :", err)
		return
	}

	//获取body数据
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println("err :", err)
		return
	}

	defer response.Body.Close()
	fmt.Printf("body: %s\n", body)
}

你可能感兴趣的:(密码学)