• HTTPS是加密传输协议,HTTP是明文传输协议
• HTTPS需要用到SSL证书,而HTTP不用
• HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO
• HTTPS标准端口443,HTTP标准端口80
• HTTPS基于传输层,HTTP基于应用层
• HTTPS在浏览器显示绿色安全锁,HTTP没有显示

1、http请求
package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w,
     "这个是http请求")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

运行:go run main.go

然后浏览器:http://localhost:8080/

2、https 请求

在测试环境,我们没有必要花钱去购买什么证书,利用openssl工具,我们可以自己生成相 关私钥和自签发的数字证书。

2.1 安装openssl

地址:http://slproweb.com/products/Win32OpenSSL.html

下载对应版本,安装步骤如下:





编辑环境变量:

2.1 生成证书

1、创建一个目录,用于存放证书,我的是c:/demo,在生成证书之前需要设置两个环境变量

set RANDFILE=c:\demo\.rnd
set OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg


2、进入openssl命令行:

C:\OpenSSL-Win64\bin\openssl.exe

3、生成 server.key和server.crt

  • 先生成证书私钥, 2048表示私钥的长度为2048bit
genrsa -out server.key 2048
  • 根据私钥生成证书
 req -new -x509 -key server.key -out server.crt -days 365 

2.2 生成一个https服务器

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "这个是http请求")
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServeTLS(":8080",
		"C:/demo/server.crt",
		"C:/demo/server.key",
		nil)
}

编译: go run main.go
运行:
第一种方法:然后浏览器端:
https://localhost:8080/


第二种方法:

为此,我们可以先跳过验证

2.3 代码访问https客户端

我们除了上面两种方法可以访问https服务端之外,还可以生成一个使用代码它

'package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main(){
	resp, err := http.Get("https://127.0.0.1:8080")
	if err != nil{
		fmt.Println("error", err)
		return
	}
	defer  resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}

运行上面程序,发现报错:error Get https://127.0.0.1:8080: x509: certificate signed by unknown authority;说明client端也会对服务端传过来的证书进行校验,但是客户端提示:这个证书是不知名CA签发 的。我们可以跳过证书验证
备注:服务端也报错: http: TLS handshake error from 127.0.0.1:62004: remote error: bad certificate;说明服务器也会对客户端进行验证

package main

import (
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main(){
	//要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport
	//Client和Transport类型都可以安全的被多个go程同时使用。出于效率考虑,应该一次建立、尽量重用
	tr := &http.Transport{
		//InsecureSkipVerify用来控制客户端是否证书和服务器主机名。如果设置为true,
		//则不会校验证书以及证书中的主机名和服务器主机名是否一致。
		TLSClientConfig: &tls.Config{InsecureSkipVerify:true},
	}
	client := &http.Client{Transport:tr}
	resp, err := client.Get("https://127.0.0.1:8080")
	if err != nil{
		fmt.Println("err:", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}

如果设置验证证书的话(TLSClientConfig: &tls.Config{InsecureSkipVerify: false}),
那么需要验证两个东西,一个是上证书用的CN的名称一致。

x509: cannot validate certificate for 127.0.0.1 because it doesn’t contain any IP SANs

另一个是证书是否是权威的签发了,否则就是上面的unknown authority了
如果设置成true,则无所谓了,不校验证书,当然不一致也无所谓了。

2.4 对服务端证书进行校验

多数时候,我们需要对服务端的证书进行校验,而不是像上面那样忽略这个校验。

首先我们来建立我们自己的CA,需要生成一个CA私钥和一个CA的数字证书:

  • 生成CA私钥
openssl genrsa -out ca.key 2048
  • 生成CA证书
openssl req -x509 -new -nodes -key ca.key -subj "/CN=tonybai.com" -days 5000 -out ca.crt

接下来,生成server端的私钥,生成数字证书请求,并用我们的ca私钥签发server的数字证书:

  • 生成服务端私钥
openssl genrsa -out server.key 2048
  • 生成证书请求文件
openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
  • 根据CA的私钥和上面的证书请求文件生成服务端证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000

使用方法主要参考:https://blog.didierstevens.com/2015/03/30/howto-make-your-own-cert-with-openssl-on-windows/
参考:https://blog.csdn.net/u010278923/article/details/76101074?utm_source=blogxgwz8
参考:https://studygolang.com/articles/17143
参考:https://www.cnblogs.com/pzblog/p/9088286.html