道隐于小成,言隐于荣华

HTTPS基础内容

本科期间阅读笔记备份。

HTTP简介

HTTP模型:B/S

HTTP消息包括两部分:HTTP语义与HTML实体

HTTP语义

请求/响应消息示例:

POST /gsorganizationvalsha2g2 HTTP/1.1
Host: ocsp2.globalsign.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/ocsp-request
Content-Length: 79
Connection: close

从中看出HTTP包括三部分:请求行/响应行、HTTP头部、HTML实体(包括请求~与响应~)

其中,请求行包括:URL、HTTP版本。

响应行包括:HTTP版本、状态码、信息提示符。

Cookie与Session:技术设计不严谨,漏洞多

TCP/IP

计网内容:应用层、传输层、网络层、链路层、物理层

DNS解析、ICMP包、TCP包、UDP包、IP包、Frame,Buffer、三次握手、四次握手等。

Socket API

密码学基础

OpenSSL

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md4               
md5               rmd160            sha1              sha224            
sha256            sha384            sha512            

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       base64            bf                
bf-cbc            bf-cfb            bf-ecb            bf-ofb            
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb  
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc          
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb         
des               des-cbc           des-cfb           des-ecb           
des-ede           des-ede-cbc       des-ede-cfb       des-ede-ofb       
des-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofb      
des-ofb           des3              desx              rc2               
rc2-40-cbc        rc2-64-cbc        rc2-cbc           rc2-cfb           
rc2-ecb           rc2-ofb           rc4               rc4-40            
seed              seed-cbc          seed-cfb          seed-ecb          
seed-ofb          

随机数

效率

随机性:不存在统计学偏差

不可预测性:无法推断

不可重现性:不重复

常见随机数生成器

外部熵生成随机数

head -c 32 /dev/urandom |openssl enc -base64

常见伪随机数生成算法:Blum Blum Shub、Mersenne Twister(马特赛特旋转演算法)、Linear congruential generator(线性同余法)

openssl生成伪随机数:

openssl rand -base64 24

密码学随机数生成:块密码算法CTR模式、摘要函数、流密码算法等。用途为密钥、初始化向量(IV)、nonce、salt。

Hash算法

MD5、SHA1、SHA2、SHA3

对称加密算法

流密码

RC4、ChaCha

块密码

推荐AES。

模式:ECB、CBC、CTR(CBC、CTR目前推荐)

MAC(Message Authentication Code)

分类:CBC-MAC与HMAC。

AD加密模式

  1. Encrypt-and-MAC(E&M)
  2. MAC-then-Encrypt(MtE)
  3. Encrypt-then-MAC(EtM)

AEAD加密模式

  1. CCM模式
  2. GCM模式
  3. ChaCha20-Poly1305

公钥密码

RSA

Openssl生成密钥对:

openssl genrsa -out key.pem 2048

3des加密密钥:

openssl genrsa -des3 -out key2.pem 2048

从密钥对中分离出公钥:

openssl rsa -in key.pem -pubout -out pubkey.pem

校验密钥对:

openssl rsa -in key.pem -check -noout

显示公钥信息:

openssl rsa -pubin -in pubkey.pem -text

openssl使用密钥对进行加密:

openssl rsatl -encrypt -inkey key.pem -in plain.txt -out cipher.enc

openssl使用公钥进行加密:

openssl rsatl -encrypt -pubin -inkey pubkey.pem -in plain.txt -out cipher.enc

openssl解密:

openssl rsatl -decrypt -inkey key.pem -in cipher.enc

note:如果需要指定机制,请在最后添加。比如PKCS#1 OAEP,就在句末添加-oaep

密钥

密钥最重要,最重要的属性为长度。

生成密钥

足够长、不可预测,因此两种方法生成密钥:基于伪随机数生成器生成密钥,基于口令的加密。

口令与PEB算法

口令:弱密钥

PBKDF2算法:PRF(伪随机数函数)、Password、Salt、c(迭代数)、dkLen(密钥长度)

密钥传输与存储

静态密钥、动态密钥

密钥协商

采用动态密钥(也叫会话密钥)。

特点:

  1. 作用:加密解密通信数据。
  2. client与server需要协商会话密钥。
  3. 不用存储

RSA协商

服务器发送RSA公钥->随机数生成->客户端使用公钥加密会话密钥并发送->服务器私钥解密->通信通道完成

缺点:不能向前安全性

DH协商

通信双方生成p、g

->服务器发送参数给客户端

->客户端生成随机数a,计算yc=(g^a) mod p.yc为公钥

->服务器生成随机数b,随机数为私钥,计算ys=(g^b) mod p,ys为公钥

->yc发送给服务器,服务器计算Z=(yc^b) mod p

->ys发送给客户端,计算Z=(ys^a) mod p

->Z相等,完成

DH分类: 静态DH与临时DH(EDH)

DH密钥协商实践:

#生成1024bits参数
$ openssl dhparam -out dhparam.pem -2 1024
#查看参数文件
$ openssl dhparam -in dhparam.pem -noout -C
#基于参数生成密钥对
$ openssl genpkey -paramfile dhparam.pem -out dhkey.pem
#查看密钥对文件内容
$ openssl pkey -in dhkey.pem -text -noout
#通信双方任何一方生成DH参数文件,对外公开
$ openssl genpkey -genparam -algorithm DH -out dhp.pem
#查看参数文件内容
$ openssl pkeyparam -in dhp.pem -text
#发送方A基于参数文件生成一个密钥对
$ openssl genpkey -paramfile dhp.pem -out akey.pem
#发送方B基于参数文件生成一个密钥对
$ openssl genpkey -paramfile dhp.pem -out bkey.pem
#查看密钥对内容
$ openssl pkey -in bkey.pem -text -noout
#发送方A拆出公钥文件akey_pub.pem,私钥自己保存
$ openssl pkey -in akey.pem -pubout -out akey_pub.pem
#发送方B拆出公钥文件bkey_pub.pem,私钥自己保存
$ openssl pkey -in bkey.pem -pubout -out bkey_pub.pem
#发送方A收到B发送过来的公钥,将协商的密钥保存到data_a.txt
$ openssl pkeyutl -derive -inkey akey.pem -peerkey bkey_pub.pem -out data_a.txt
#发送方B收到A发送过来的公钥,将协商的密钥保存到data_b.txt
$ openssl pkeyutl -derive -inkey bkey.pem -peerkey akey_pub.pem -out data_b.txt

椭圆曲线密码学

命名曲线:系统预先设定的曲线标准

查看命名曲线:

openssl ecparam -list_curves

ECDH协商

#生成参数文件
$ openssl ecparam -name secp256k1 -out secp256k1.pem
#A、B生成各自ECDH私钥对文件
$ openssl genpkey -paramfile secp256k1.pem -out akey.pem
$ openssl genpkey -paramfile secp256k1.pem -out bkey.pem
#A、B分解出公钥,将公钥发送给对方
$ openssl pkey -in akey.pem -pubout -out akey_pub.pem
$ openssl pkey -in bkey.pem -pubout -out bkey_pub.pem
#A、B计算出同样的会话密钥
$ openssl pkeyutl -derive -inkey akey.pem -peerkey bkey_pub.pem -out data_a.txt
$ openssl pkeyutl -derive -inkey bkey.pem -peerkey akey_pub.pem -out data_b.txt

RSA数字签名

签名算法:

s=m^d (mod n)

解密签名算法公式:

m=s^e (mod n)

RSA数字签名实践

#生成RSA密钥对
$ openssl genrsa -out rsaprivatekey.pem 1024
#从密钥对分离出公钥
$ openssl rsa -in rsaprivatekey.pem -pubout -out rsapublickey.pem
#sha256数字签名
$ echo “hello”>>plain.txt
$ openssl dgst -sha256 -sign rsaprivatekey.pem -out signature.txt
#用相同摘要算法和签名算法校验文件
$ openssl dgst -sha256 -verify rsapublickey.pem -signature signature.txt plain.txt

其中默认使用RSAES-PKCS1-v1_5填充标准,可以指定RSASSA-PSS标准。

openssl dgst -sha256 -sign rsaprivatekey.pem -sigopt rsa_padding_mode:pss -out signature.txt plain.txt

openssl dgst -sha256 -verify rsapublickey.pem -sigopt rsa_padding_mode:pss -signature signature.txt plain.txt

DSA数字签名

生成参数文件和密钥对文件:

#生成参数文件
$ openssl dsaparam -out dsaparam.pem 1024
#通过参数文件生成密钥对
$ openssl gendsa -out dsakey.pem dsaparam.pem
#对秘钥文件使用dsa3算法加密
$ openssl gendsa -out dsakey.pem -des3 dsaparam.pem
#通过密钥对文件拆分公钥
$ openssl dsa -in dsakey.pem -pubout -out dsapubkey.pem

显示参数、密钥对信息:

#显示私钥三个公共参数
$ openssl dsa -in dsakey.pem -text
#显示公钥参数信息
$ openssl dsa -pubin -in dsapubkey.pem -text

生成和验证签名

$ echo 'hello' >plain.txt
#进行签名,查看signature.txt发现原始信息
$ openssl dgst -sha256 -sign dsakey.pem -out signature.txt plain.txt
#验证签名
$ openssl dgst -sha256 -verify dsapubkey.pem -signature signature.txt plain.txt

ECDSA数字签名

直接生成:

#直接生成ECDSA密钥
$ openssl ecparam -name secp256k1 -genkey -out ecdsakey.pem
#显示密钥信息
$ openssl ec -in ecdsakey.pem -text -noout
#拆分密钥对获取公钥
$ openssl ec -in ecdsakey.pem -pubout -out ecdsapub.pem
#显示公钥信息
$ openssl ec -in ecdsapub.pem -pubin -text -noout

生成签名:

$ echo 'hello'>plain.txt
#hash sha256
$ openssl dgst -sha256 -sign ecdsakey.pem  -out signature.txt plain.txt 

校验签名:

$ openssl dgst -sha256 -verify ecdsapub.pem -signature signature.txt plain.txt

算法性能与安全性

openssl speed -evp参数子命令

openssl speed aes-128-cbc

openssl speed -evp aes-128-cbc

openssl -decrypt:测试解密时间

openssl -elapsed:测试结果使用实际时间代替CPU用户时间

TLS宏观理解

HTTPS:HTTTP+TLS/SSL

TLS/SSL位于TCP与应用层之间。

TLS/SSL可以构建在TCP上,也能UDP上,称为DTLS协议。

TLS/SSL背后的协议

TLS/SSL协议包含以下几个关键步骤:

  • 对称加密算法和HMAC算法保证数据机密性与完整性
  • 加密块由主密钥生成(会话秘钥),主密钥由密码衍生算法分成多个密码块。
  • 主密钥来自于预备主密钥。预备主密钥采用相同密码衍生算法转换为主密钥,采用DH(ECDH)或RSA算法协商。

核心步骤:认证、密钥协商、数据加密

加密算法和MAC算法

密码套件:决定了本次连接采用哪种加密算法、协商算法、HMAC算法。

密钥协商算法

RSA:客户端生成预备主密钥,用服务器公钥加密传递给服务器。

DH:静态DH与临时DH。

向前安全性

两个都缺乏向前安全性,即如果泄露服务器私钥,之前历史信息如果被拦截后将能解开其加密密钥块,从而所有历史信息都将被破解。

密钥衍生算法

两次运算:

  • 预备主密钥转换出固定长度的朱密钥
  • 朱密钥转换出任意数量、长度的密钥块

TLS/SSL中密钥衍生算法特点:

  • 秘钥块个数、数量依赖于堆成加密算法和HMAC算法
  • 需要输入参数包含输入值和salt

中间人攻击

这个其实就是拦截公钥请求,伪装向服务器请求,并中间换包,拦截信息。

PKI

CA认证的过程

网站PKI过程:

服务器实体希望网站HTTPS

->服务器生成公开密钥算法的密钥对

->生成一个CSR(证书签名请求)

->CA收到CSR

->审核通过,CA用自己构建的密钥对的私钥签名,签名值附在CSR中给服务器实体

->服务器部署证书

->客户端请求服务器,服务器接受请求,发送证书与RSA公钥

->浏览器接收判断CA证书,进行签名验证

->验证成功,校验证书申请者身份

->身份校验成功,进行秘钥协商

握手

  1. 认证
  2. 密码套件协商
  3. 密钥协商
  4. 握手消息完整性校验

全站HTTPS策略

  1. 301、302重定向技术
  2. HSTS技术
  3. 其他HTTP头部,比如Content-Security-Policy

混合内容

HTTPS页面引入非HTTPS元素。浏览器一般显示警示图标。

被动混合内容

包含的HTML标签为:audio、img、video、object。

主动混合内容

script、link(引用的CSS文件)、XMLHttpRequest请求对象、iframe、object对象。

构建HTTPS网站

下面是HTTPS网站部署的基本步骤

HTTPS网站构建分析

  • 证书、域名、密钥对
  • 迁移还是全新构建
  • web应用类型
  • 混合内容处理
  • 系统架构

获取证书和密钥对

证书获取途径:自签名证书、Let's Encrypt证书、收费CA证书

# 自签名证书

浏览器不一定收集,存在伪造可能性。一般用于企业内部系统。

流程:

生成私钥对和CSR

$ openssl req \
    -newkey res:1024 -nodes -keyout key.pem \
    -out csr.pem

生成自签名证书

openssl x509 \
    -signkey key.pem \
    -in csr.pem \
    -req -days 365 -out cert.pem

向CA机构申请证书

申请途径:专门CA机构申请或者代理机构申请。

具体方式:发送CSR文件或者同意生成证书与密钥对

CA核实申请者方式:申请者增加域名TXT记录,CA校验TXT记录;或者服务器放置HTTP校验文件,CA访问校验

使用Let's Encrypt证书

Let's Encrypt是免费的,我的博客也是用这个。

官方推荐使用CertBot客户端管理证书,管理基于ACME协议。

详细文档看这个网站:

https://certbot.eff.org/

以Ngnix的Ubuntu 18.04LTS服务器为例。

安装Certbot客户端:

$ sudo apt-get update #更新清单
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot #添加源
$ sudo apt-get update
$ sudo apt-get install certbot python-certbot-nginx #安装Certbot客户端 

使用Certbot客户端:

如果想自动完成证书安装与Certbot编辑Nginx设置,则输入:

$ sudo certbot --nginx

如果自己去调节Nginx设置,则输入:

$ sudo certbot --nginx certonly

如果想使用新的Let's encrypt ACMEv2服务,则也需要使用Cerbot的DNS模块。

$ sudo certbot -a dns-plugin -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory

以上为CertBot官方提供的安装证书方法。

书中提供的是用git获取CertBot,之后执行:

#生成证书
./certbot-auto certonly --webroot -w /usr/nginx/web -d www.example.com
#example.com为你的域名

部署证书和密钥对

以Nginx为例子(因为我服务器也是Nginx反向代理的)

Nginx配置

安装Nginx,一般免费的够个人使用的了。如果是公司那还是付费比较好。

$ apt-get install nginx #安装nginx
$ nginx -v #检查版本

配置HTTPS:

$ vim /etc/nginx/sites-nginx/example.com-ssl.conf

修改内容如下

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com; #example.com换为你的域名
    root /var/www/ghost/system/nginx-root;#web网站的nginx-root

    #证书路径
    ssl_certificate /etc/letsencrypt/example.com/fullchain.cer;
    #密钥路径
    ssl_certificate_key /etc/letsencrypt/example.com/example.com.key;
    #SSL相关参数设置
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;

    }#反向代理

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

配置完重新启动Nginx

service nginx restart

测试HTTPS

使用Curl命令行:

$ curl "https://www.example.com" --verbose

也可以用开发人员工具。

301重定向

用vim修改nginx的网站config:

$ vim /etc/nginx/sites-nginx/example.com.conf

server{
    listen 80;
    server_name www.example.com;
    rewrite ^ https://$server_name;
    #如果是迁移的网站则为: rewrite ^ https://$server_name?request_uri? permanent
}

HSTS

避免默认HTTP连接、引擎HTTP链接、不信任证书继续HTTPS连接不安全等问题。

以Nginx为例,在Nginx的Server配置文件中添加:

add_header Strict-Transport-Security 'max-age=1000;includesSubDomains;Preload;'

CSP

解决混淆内容。

为了防止XSS攻击,由Mozilla制定。

以Nginx为例,添加服务配置文件内容:

add_header Content-Security-Policy "default-src 'self';:;

Let's encrypt证书更新

更新需要先停下Nginx服务:

$ service nginx stop

首先用git下载let's encrypt:

$ git clone https://github.com/letsencrypt/letsencrypt

如果之前git过了,直接进目录。下载之后也要进入目录:

$ cd letsencrypt

最后执行如下格式命令:

$ ./letsencrypt-auto certonly --standalone --email xxxxxxxxx@gmail.com -d www.example.com

更新结束后,启动Nginx服务:

$ service nginx start

posted @ 2022-05-06 10:24  FrancisQiu  阅读(23)  评论(0)    收藏  举报