标签 https 下的文章

随着https的不断普及,目前几乎所有的网站都开启了https,但是有时候网站内的部分资源还是http的,此时因为浏览器的安全策略,浏览器默认会拦截这些资源。导致网站无法正常显示,出现报错:

Mixed Content: The page at 'https://www.xxx.com/' was loaded over HTTPS, but requested an insecure stylesheet 'http://www.xxx.com/xxx.css'. This request has been blocked; the content must be served over HTTPS.

解决方案

http协议中提供了一个头部:

Content-Security-Policy: upgrade-insecure-requests

当它被设置的时候,浏览器会自动将https网站内部的http资源请求升级为https,避免出现mixed content问题。

nginx配置方式:

add_header Content-Security-Policy upgrade-insecure-requests;

参考:Mixed Content

一、创建CA

CA全称是CertificateAuthority,意思是证书颁发机构。只有当CA被认为是受信任的颁发机构时,经过该CA颁发出来的证书才属于受信任的证书。否则,认为证书是不受信任的。

为了生成一个自签名的CA,需要先生成CA私钥:

openssl genrsa -des3 -out rootCA.key 4096

执行命令后,需要输入一个密码作为私钥的密码,后续通过该私钥来生成或者签发证书都要用到这个私钥。

生成私钥后,执行以下命令生成证书:

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

执行后会进入交互式界面,需要输入CN相关信息。等待根证书生成后,一个CA也就创建完成了,此时要做的是生成用户证书,并使用CA证书对它签名,然后就可以用了。

二、生成用户证书

生成用户证书的私钥:

openssl genrsa -out www.maqian.work.key 2048

生成csr,csr是一个证书签名的请求,后面生成证书需要使用这个csr文件:

openssl req -new -key www.maqian.work.key -out www.maqian.work.csr

这一步也需要输入地区、CN等相关的信息,输入完成后,使用CA证书签发用户证书:

openssl x509 -req -in www.maqian.work.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out www.maqian.work.crt -days 500 -sha256

此时,得到的www.maqian.work.keywww.maqian.key.pem就是用户端的私钥和证书。

三、chrome错误

错误码:NET::ERR_CERT_COMMON_NAME_INVALID

错误信息:此服务器无法证实它就是 www.maqian.cn - 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。

解决方案

新建一个文件ext.ini,写入以下内容:

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.dyxmq.cn
DNS.2 = *.maqian.xin
DNS.3 = *.maqian.io
DNS.4 = *.maqian.co
DNS.5 = *.maqian.cn

[alt_names]下面填写上所有的域名即可,然后签发证书的时候带上参数:

openssl x509 ... -extfile ext.ini

一、问题现象

使用自签名的证书后,chrome报错此服务器无法证实它就是 www.maqian.cn - 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接,错误码是NET::ERR_CERT_COMMON_NAME_INVALID

二、问题原因

生成证书的时候没有加上备用名称字段,目前的浏览器校验证书都需要这个字段。

三、解决方案

生成证书的时候需要添加上备用名称(subjectAltName)扩展字段。

使用openssl添加subjectAltName扩展

创建一个文件ext.ini,填入以下内容:

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.dyxmq.cn

在DNS.1的地方填写上自己的域名,如果有多个域名,可以按照规律DNS.1/DNS.2/DNS.3/...来添加。

同时还支持IP地址的形式,填入IP.1 = x.x.x.x就可以了。

一、证书和CA

HTTPS证书的颁发和验证一共包含以下几个角色:

  1. 顶级CA:最顶级的证书颁发机构,可以签发中间CA/。
  2. 中间CA:也是受信任的证书颁发机构,它由根CA签发,中间证书可以有很多级,中间CA也能再签发中间CA。
  3. 终端证书:由CA签发出来的证书。

三者的关系为:

顶级CA机构一般不直接参数证书颁发,因为顶级CA就一个公私钥,泄密后影响太大。因此一般都是通过中间CA来颁发证书,中间CA可以有多层,中间CA也可以自己再签发中间CA,他们都是等效的。实际上的正式的使用场景也是这样,中间CA会根据加密算法或其他因素再衍生出多个中间CA。以百度的证书,它的证书就是由一个中间CA颁发:

生成证书时,用户只要把自己的公私钥和身份信息(如域名信息等)提交给CA机构就行,CA机构对用户信息加密生成证书给到用户,用户把证书和私钥部署到服务端就能开启HTTPS了。

证书的表现形式

证书有多种表现形式,常用的为pemder格式,两者的区别在于前者是以ascii码表示的证书,后者是二进制形式。pem格式的证书是以下形式:

-----BEGIN CERTIFICATE-----
MIIEozCCBAygAwIBAgIJAIkKM/OEESv3MA0GCSqGSIb3DQEBBQUAMIHnMQswCQYD
...
otgUgl+vsfMW5hy8607ppPM7YWTMUV36N6mVAOGPtntf8HdlbH7MLr+PiAjBspkw
HGWHw5+FYqoBWPALLEi3d7LGHnF/qJchkjttwqakSS0u+sWQIqYD
-----END CERTIFICATE-----

两种证书在各操作系统下都是能被直接打开的(windows需要修改后缀为crt),效果也都一样,可以使用windows的证书管理或者openssl命令转换两种证书格式。

二、客户端校验CA

证书部署到服务器后,客户端请求到证书,会根据证书信息找到对应的根证书签发机构(CA),如果CA受信任,则认为证书可靠,证书中的公钥也可靠,可以建立加密连接。而如果CA不受信任,浏览器就会拦截请求,提示连接不安全,需要用户确认后才建立连接。如chrome浏览器就会弹出以下弹框信息等用户确认后才建立连接:

默认情况下,操作系统都会保存一份受信任根证书列表,这样在访问网站的时候很方便就能确认当前证书的颁发者是不是受信任CA了。windows系统可以在运行中输入certmgr.msc来查看:

ubuntu在:

 /etc/ssl/certs/ca-certificates.crt

centos在:

/etc/pki/tls/certs/ca-bundle.crt

OCSP校验

当本地信任库无法校验证书时,例如证书链不完整时,需要使用OCSP方式来校验证书的有效性,它实际上是一种在线校验证书机制,通过OCSP协议去请求服务端证书来检验CA。

三、部署HTTPS证书

nginx中配置HTTPS证书的方法:

server {
    ssl on; # 开启ssl
    ssl_certificate cert.pem; # 证书路径
    ssl_certificate_key key.pem; # 私钥路径
}

高版本的nginx配置中,取消了ssl on指令,改为了以下形式:

server {
    listen 443 ssl;
    ssl_certificate cert.pem;
    ssl_certificate_key key.pem;
}

证书中如果包含了CA,证书的格式应该为:

用户证书
中间证书
根证书

一、HTTP1.0和HTTP1.1

HTTP1.0和1.1的主要区别为:

  1. 长连接:HTTP1.0默认是短连接,HTTP1.1默认使用长连接。
  2. 断点续传:HTTP1.1支持断点续传,可以通过 Range头部指定需的资源数据部分。
  3. 添加Host头部:HTTP1.1中为了解决虚拟主机的使用场景,通过Host字段来指定访问某个特定web服务。
  4. 状态码:HTTP1.1添加了更多的状态码,如100等。

二、HTTP1.1和HTTP2.0

HTTP2.0相对于1.1来说跨了一个大版本,相应的改动也是非常大的。它的主要目标是提高HTTP协议的传输效率,不过主要都是基于数据传输上的改动,HTTP协议本身并没有修改太多。关于HTTP2.0的相关信息可以参考HTTP/2简介

HTTP2.0和HTTP1.1的主要区别为:

  1. HTTP1.1通过ascii码传输数据,而HTTP2.0通过二进制帧来传输。
  2. HTTP2.0默认使用长连接,并且每个来源只有一个连接。
  3. HTTP2.0压缩了HTTP头部,优化头部传输机制,大幅减少http传输空间。
  4. HTTP2.0原生支持服务端推送。