算法名称
- AES、DES 对称加密算法(密文可通过秘钥还原成原始数据)
- RSA、DSA、ECC 非对称加密
- CRC32、MD5、SHA1 摘要算法(加签)
CRC32
Cyclic Redundancy Check,又称循环冗余校验,类似还有CRC64(出现碰撞的概率小),常用于校验网络上传输的文件MD5
Message-Digest Algorithm 5,又叫摘要算法和哈希算法SHA1
Secure Hash Algorithm,又叫安全散列算法- 区别
- CRC的计算效率很高;MD5和SHA1比较慢
- CRC一般用作通信数据的校验(毕竟效率高适用于通信数据校验)或数据库索引;MD5和SHA1用于安全(Security)领域,比如文件校验、数字签名等
加密相关的概念
对称加密
- 这是加密文件常用的方式,加密的时候输入一个密码,解密的时候也用这个密码,加密和解密都用同一个密码,所以叫对称加密。常见的算法有AES、
3DES
- 这是加密文件常用的方式,加密的时候输入一个密码,解密的时候也用这个密码,加密和解密都用同一个密码,所以叫对称加密。常见的算法有AES、
非对称加密
- 非对称加密有两个不一样的密码,一个叫私钥,另一个叫公钥,用其中一个加密的数据只能用另一个密码解开,用自己的都解不了,也就是说用公钥加密的数据只能由私钥解开,反之亦然
- 私钥一般自己保存,而公钥是公开的,同等加密强度下,非对称加密算法的速度比不上对称加密算法的速度,所以非对称加密一般用于数字签名和密码(对称加密算法的密码)的交换。常见的算法有
RSA
、DSA
、ECC
摘要算法
- 摘要算法不是用来加密的,其输出长度固定,相当于计算数据的
指纹
,主要用来做数据校验,验证数据的完整性和正确性。常见的算法有MD5
、SHA1
、SHA256
、CRC
- 摘要算法不是用来加密的,其输出长度固定,相当于计算数据的
数字签名
- 数字签名就是 “非对称加密+摘要算法”,其目的不是为了加密,而是用来防止他人篡改数据
- 其核心思想是
- 比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名,B收到数据和A的签名后,也用同样的摘要算法计算指纹,然后用A公开的公钥解密签名,比较两个指纹,如果相同,说明数据没有被篡改,确实是A发过来的数据
- 假设C想改A发给B的数据来欺骗B,因为篡改数据后指纹会变,要想跟A的签名里面的指纹一致,就得改签名,但由于没有A的私钥,所以改不了,如果C用自己的私钥生成一个新的签名,B收到数据后用A的公钥根本就解不开
SSL/TLS
介绍
SSL
(Secure Sockets Layer)和TLS
(Transport Layer Security)的关系就像windows XP和windows 7的关系,升级后改了个名字而已- TLSv1是建立在SSLv3.0之上的,可以理解成SSLv3.1,中间还有TLSv1.1,目前一般推荐使用TLSv1.2,但是最新版本已近到了TLSv1.3
- 具体使用得TLS协议版本有客户端优先选择,但是服务器可设置支持的协议版本。像XP系统下的谷歌(v49)就不支持TLSv1.2,但是XP系统下的火狐浏览器是支持的
- 最初的SSL只支持TCP,现在已经可以支持UDP
HTTPS=HTTP+TLS
、FTPS=FTP+TLS
。SSH和SSL/TLS是两个不同的协议,SSH并不依赖于SSL/TLS- 测试https访问
https://www.ssllabs.com/ssltest/analyze.html?d=test.aezo.cn
证书概念
私钥
:私钥就是一个算法名称加上密码串,自己保存,从不给任何人看公钥
:公钥也是一个算法名称加上密码串,一般不会单独给别人,而是嵌在证书里面一起给别人CA
:专门用自己的私钥给别人进行签名的单位或者机构申请签名文件
:在公钥的基础上加上一些申请人的属性信息,比如我是谁,来自哪里,名字叫什么,证书适用于什么场景等的信息。然后带上进行的签名,发给CA(私下安全的方式发送),带上自己签名的目的是为了防止别人篡改文件证书文件
:证书由公钥加上描述信息,然后经过私钥签名之后得到。一般都是一个人(一般是CA)的私钥给另一个人的公钥签名;如果是自己的私钥给自己的公钥签名,就叫自签名
- 签名过程
- CA收到申请文件后,会走核实流程,确保申请人确实是证书中描述的申请人,防止别人冒充申请者申请证书,核实通过后,会用CA的私钥对申请文件进行签名
- 签名后的证书包含:申请者的基本信息,CA的基本信息,证书的使用年限,申请人的公钥,签名用到的摘要算法,CA的签名
- 签完名之后,证书就可以用了
- 证书找谁签名合适
- 别人认不认你的证书要看上面签的是谁的名,所以签名一定要找权威的人来签,否则别人不认,哪谁是权威的人呢?那就是CA,哪些CA是受人相信的呢?那就要看软件的配置,配置相信谁就相信谁,比如浏览器、操作系统等,安装好了之后里面就内置了很多信任的CA的证书,只要是那些CA签名的证书,操作系统/浏览器都会相信。而自己写的程序,可以由你自己指定信任的CA(即使用自签名证书);浏览器使用自签名证书时必须将CA证书添加为信任的证书,否则会有警告
- 那么CA的证书又是谁签的名呢?一般CA都是分级的,CA的证书都是由上一级的CA来签名,而最上一级CA的证书是自签名证书
- 以浏览器为例,说明证书的验证过程
- 在TLS握手的过程中,浏览器得到了网站的证书
- 打开证书,查看是哪个CA签名的这个证书
- 在自己信任的CA库中,找相应CA的证书
- 用CA证书里面的公钥解密网站证书上的签名,取出网站证书的校验码(指纹),然后用同样的算法(比如sha256)算出出网站证书的校验码,如果校验码和签名中的校验码对的上,说明这个证书是合法的,且没被人篡改过
- 读出里面的CN,对于网站的证书,里面一般包含的是域名
- 检查里面的域名和自己访问网站的域名对不对的上,对的上的话,就说明这个证书确实是颁发给这个网站的
- 到此为止检查通过
- 如果浏览器发现证书有问题,一般是证书里面的签名者不是浏览器认为值得信任的CA,浏览器就会给出警告页面,这时候需要谨慎,有可能证书被掉包了。如访问12306网站,由于12306的证书是自己签的名,并且浏览器不认为12306是受信的CA,所以就会给警告,但是一旦把12306的根证书安装到了你的浏览器中,那么下次就不会警告了,因为配置了浏览器让它相信12306是一个受信的CA
TLS握手过程
1 | +--------+ +--------+ |
证书生成示例
1 | mkdir cert && cd cert |
- openssl参数说明
-newkey rsa:2048
:生成一个长度为2048的采用RSA算法的私钥-nodes
:这个私钥在本地存储的时候不加密(可以通过其它参数来加密私钥,这样存储比较安全)-sha256
:生成的证书里面使用sha256作为摘要算法-keyout ca.key
:输出私钥到ca.key
(或者取名key.pem
)-x509
:证书文件格式为x509
,目前TLS默认只支持这种格式的证书-days 365
:证书有效期1年-out ca.crt
:生成的证书文件保存到ca.crt
(或者取名cert.pem
)
- 证书文件
- 证书的CRT内容:”—–BEGIN CERTIFICATE—–”开头,”—–END CERTIFICATE—–”结尾
- 证书的私钥内容:”—–BEGIN PRIVATE KEY—–”开头,”—–END PRIVATE KEY—–”结尾
- 证书生成填写
1 | Country Name (2 letter code) [XX]:CN |
HTTPS
- 证书检测在线工具 可以查看包括二级证书
- 使用 HTTPS 时,所有的 HTTP 请求和响应数据在发送到网络之前,都要进行加密。网络分层如下
- 不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,会有以下风险
- 窃听风险(eavesdropping):第三方可以获知通信内容
- 篡改风险(tampering):第三方可以修改通信内容
- 冒充风险(pretending):第三方可以冒充他人身份参与通信
- SSL 是个二进制协议,与 HTTP 完全不同,其流量是承载在另一个端口上的(SSL 通常是由端口 443 承载的)
- 如果URL的方案为http,客户端会打开服务器80端口的连接
- 如果URL的方案为https,客户端就会打开一条到服务器端口443(默认情况下) 的连接,然后与服务器“握手”,以二进制格式与服务器交换一些 SSL 安全参数, 附上加密的 HTTP 命令
- 服务器公钥放在服务器的数字证书之中
- 清除谷歌证书缓存:访问
chrome://net-internals/#hsts
,在Delete domain security policies
中输入域名删除证书,然后重新打开浏览器
Let’s Encrypt免费证书使用
- 在线申请证书:https://www.sslforfree.com/
- 基于certbot自动获取证书:可实现通配符证书
- 基于acme.sh:证书申请脚本和续签脚本 https://github.com/acmesh-official/acme.sh
Linux服务器证书申请(基于certbot)
1 | ## 安装 |
- 结合自动验证DNS脚本进行配置通配符证书(阿里云需要AccessKey账号)(2403)
1 | ## 参考:https://www.cnblogs.com/trblog/p/14690908.html |
- 手动配置nginx证书
1 | server { |
- 测试https访问
https://www.ssllabs.com/ssltest/analyze.html?d=test.aezo.cn
- 常见错误
Invalid response from https://dnspod.qcloud.com/static/webblock.html?d=xxx
尽管已经备案也被拦截了(特别是换成腾讯DNS专业版之后出现)- 可以换成DNS验证解决,参考: https://zhiqiang.org/it/letsencrypt-and-nginx-set-https.html
Linux服务器证书申请(基于acme.sh)
1 | # 参考:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E |
Windows证书申请(基于win-acme)
- 基于win-acme,下载win-acme.v2.1.7.807.x64.trimmed.zip
- 生成证书操作流程
- 执行wacs.exe文件
- Create new cerificate (full options)
- Manual input
- 输入host name
- 选择默认认证方式
serve verification files from memory
通过内存验证服务器(需要在实际服务器上运行上述exe。会先访问Lets自动提交工单,然后Lets会访问配置的域名,会在内存生成一个随机码进行验证)[dns-01] Create verification records manually (auto-renew not possible)
基于DNS进行验证(可在工作机上运行上述exe。选择后继续往下操作,最后会生成一个DNS解析值;如生成test.aezo.cn的证书,则他需要解析出一个 _acme-challenge.test,类型为TXT,值为随机生成的一串字符;解析好后,稍等片刻等域名解析生效后再继续执行后续步骤进行验证)
- rsa key
- pem encoded files(Apache, nginx, etc.)
- 输入文件存放路径
- No store steps
- 将生成的文件设置到ngixn(参考上文手动配置nginx证书)
- 查看托管的证书
- 再次执行wacs.exe文件
- A: Manage renewals (1 total) 可查看托管的自动更新证书
证书过期导致RestTemplate(SpringBoot)访问接口失败
- 报错:unable to find valid certification path to requested target
- 自定义RestTemplate同时支持访问http与https
1 |
|
AES/DES
简介
- 密码学中的高级加密标准 (Advanced Encryption Standard,
AES
),又称高级加密标准Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES
,已经被多方分析且广为全世界所使用。高级加密标准已然成为对称密钥加密中最流行的算法之一。该算法为比利时密码学家Joan Daemen和VincentRijmen所设计,结合两位作者的名字,以Rijndael
命名之 [1] - 加密方式如
AES/CBC/NOPadding
AES/CBC/PKCS5Padding
128位(16字节),jdk默认支持,建议使用AES/CBC/PKCS7Padding
256位(32字节),jdk默认不支持
- 说明
- 类似有
DES/CBC/PKCS5Padding
- 上述命名意义分别为:AES为算法名称,CBC为加密模式,PKCS5Padding为填充方式(PKCS5Padding是PKCS7Padding在填充块大小为8个字节时的特殊情况,本质上是一样的)
- 使用CBC模式,需要一个向量iv,可增加加密算法的强度
- 一般在对内容加密时,需要先将内容进行编码,如Base64。因为,不是所有的字节数组都可以new String(),然后在通过String.getBytes()还原
- 类似有
JAVA 实现
java默认不支持PKCS7,如果非要指定PKCS7需要借助
BouncyCastle
类和安装扩展包BouncyCastle
类1
2
3
4
5
6
7<!-- AES/CBC/PKCS7Padding 加解密 -->
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.55</version>
</dependency>安装扩展包
- oracle官方下载(JDK1.8)
- 下载之后得到
local_policy.jar
,US_export_policy.jar
两个jar包,把这两个jar包放到jre/lib/security
目录下替换原来的两个jar包即可 - 如果是128位(16字节)则无需安装扩展包
- 示例(基于jdk1.8测试)
1 | import org.apache.tomcat.util.codec.binary.Base64; |
JS 实现
- 基于插件
CryptoJS
- 参考
SHA1
1 | public static String sha1(String str) |
参考文章