深入理解HTTPS系列-密码学篇-公开密钥(五)

946 阅读11分钟

前情提要

深入理解HTTPS系列-密码学篇-随机数(一)

深入理解HTTPS系列-密码学篇-哈希算法(二)

深入理解HTTPS系列-密码学篇-对称加密(三)

深入理解HTTPS系列-密码学篇-消息验证码(四)

概述

终于来到了系列文章的核心章节-公开密钥算法,首先我们来了解下什么是公开密钥算法,看名称有两个关键字“公开”和“密钥”

  • 先来讲密钥,密钥就是一把密码锁,用这把密码锁加密消息、解密消息,只要密钥不泄漏,通信就是安全的
  • 再来讲公开,在之前的对称加密章节,密钥是私密的,且一次会话中只有一个。公开密钥的意思就是密钥是一对,其中一个可以被所有人看见的叫做“公钥”,不能被看见的叫“私钥”

很容易理解吧,那组合起来就是叫 公开密钥算法。公开密钥算法不是单指一种算法,而是有一系列算法,下面会依次展开讲讲,分别是非对称加密算法密钥协商算法以及数字签名技术。非对称加密是听到过最多的,密钥协商和数字签名都是基于非对称加密算法原理在不同的场景下的具体应用算法,原理和非对称加密算法基本差不多。

非对称加密

先来讲非对称加密算法,和它对应的当然就是对称加密算法,那它和对称加密有什么区别呢?

  • 密钥不一样:对称加密的密钥是一串数字,非对称加密是一对公私钥,用私钥可以解开用公钥加密的消息
  • 运算速度:非对称加密比对称加密慢。

非对称加密算法的代表当然就是大名鼎鼎的RSA了,另外还有在HTTPS中非常流行使用的ECC椭圆曲线算法,相同密钥长度下,ECC比RSA具有更高的安全性。这里我们先着重介绍一下RSA

RSA的名称来源很有意思,本以为是什么复杂的缩写,其实就是三个发明者名称字母的缩写,分别是Ron Rivest、Adi Shamir和Leonard Adleman,在1977年提出的,RSA算法的安全性基于大质数分解问题,我们来简单了解一下:

公私的计算过程

  1. 选择两个很大的质数ppqq,令:
N=pq(1)N = p * q \tag{1}
r=φ(N)其中φ(N)N的欧拉公式(2)r = \varphi(N) \tag{2} \quad其中\varphi(N)是N的欧拉公式

根据欧拉公式的定理以及ppqq均为质数,得:

r=φ(N)=(p1)(q1)(3)r = \varphi(N) = (p-1)*(q-1) \tag{3}
  1. 取一个公开指数ee,满足条件
e<r    er互质(a)e<r\;且\;e和r互质 \tag{a}
  1. 求得ee关于rr的模逆元,将其命名为dd,则有:
ed1(modr)(4)e*d \equiv 1\pmod{r} \tag{4}

(N,e)(N, e)组合是公钥,(N,d)(N, d)组合是私钥,且丢弃ppqq

公钥加密过程

首先将明文转换为数字,一般是将明文转为unicode编码,然后将这些编码数字连接起来称为一个大数字,如果数字过长,可以考虑分段加密。假设有明文对应的数字x,公钥加密结果cc计算如下:

c=xemodN(5)c = x^e \bmod N \tag{5}

私钥解密过程

利用私钥和密文解密如下:

x=cdmodN(6)x = c^d \bmod N \tag{6}

证明过程

  1. (5)式(5)左右两边同时指数运算得:
cd=xedmodN(7)c^d = x^{ed} \bmod{N}\tag{7}
  1. 同时根据(4)式(4)有,ed=1+kφ(N)  k为自然数e*d=1+k*\varphi(N)\;k为自然数,则有:
xedx1+kφ(N)=xxkφ(N)=x(xφ(N))k(8)x^{ed} \equiv x^{1+k\varphi(N)} = x·x^{k\varphi(N)} = x(x^{\varphi(N)})^k \tag{8}
  1. 如果xxNN互素,则由欧拉定理得:
xedx(xφ(N))kx(1)kx(modN)(9)x^{ed} \equiv x(x^{\varphi(N)})^k \equiv x(1)^k \equiv x\pmod{N} \tag{9}
  1. 结合(7)式(7)(9)式(9)(6)式(6)得证
  2. 如果xxNN不互素,由于NN是两个素数ppqq的乘积,所以必然有:
x=kp  其中k为正整数(10)x = k * p\;其中k为正整数 \tag{10}

且根据3式34式4有:

ed1=h(q1)(11)ed - 1= h * (q - 1) \tag{11}

根据10式10得:

xed=(ph)ed0phx(modp)(12)x^{ed} = (ph)^{ed} \equiv 0 \equiv ph \equiv x \pmod{p} \tag{12}

根据11式11得:

xed=xed1x=xh(q1)x=x(xq1)hx(1)hx(modq)(13)x^{ed} = x^{ed-1}x = x^{h(q-1)}x = x(x^{q-1})^h \equiv x(1)^h \equiv x \pmod{q} \tag{13}

根据12式1213式13以及N=pqN = pq6式6得证

  1. 结合步骤3和步骤5 解密6式6得证

现在我们考察下算法的安全性,看看能不能从公钥破解出私钥,已知NNee以及ed1(modr)e*d \equiv 1\pmod{r}r=φ(N)=(p1)(q1)r = \varphi(N) = (p-1)*(q-1),要想求得dd,必须知道rr,也就是从NN破解出ppqq,大数的质因数分解是个非常难的问题,没有公式捷径可走,只能暴力破解。目前常用的RSA的NN的长度是1024,即210242^{1024},现代普通计算机的破解时长大概需要几百到几千年不等,如果是2048位则破解时长已经超过宇宙时间了。

密钥协商

公开密钥算法的的另外一种算法就是密钥协商算法,密钥协商算法协商的就是通信双方的会话密钥,如何在不安全的通信网络环境下(消息可能被窃听)使得通信双方获得会话密钥,这是密钥协商算法重点解决的问题。该会话密钥需要具备以下几个特点:

  1. 会话密钥的作用就是为了加密解密通信数据,也就是对称加密算法可以使用会话密钥进行加密解密。
  2. 在加密解密通信数据之前,客户端和服务器端需要协商出会话密钥,而会话密钥只有服务器端和特定的客户端才能知晓,不能泄露,这可以采用密钥协商算法解决
  3. 会话密钥的意思就是该密钥不用存储,一旦客户端和服务器端的连接关闭,该密钥就会消失,也就是说密钥存储在客户端和服务器端的内存中,由于密钥不用存储,安全性就得到了很大的保障

密钥协商算法主要有RSA算法、DH算法、ECDH算法等,本文重点介绍RSA和DH算法

RSA算法

RSA协商算法主要就是利用的RSA中公钥加密、私钥解密的特性,具体协商过程如下:

  1. 客户端初始化连接服务器端,服务器发送RSA密钥对的公钥给客户端
  2. 客户端生成一个随机值,这个值必须是随机的,不能被攻击者猜出,这个值就是会话密钥
  3. 客户端使用服务器RSA密钥对的公钥加密会话密钥,并发送给服务器端,由于攻击者没有服务器的私钥,所以无法解密会话密钥
  4. 服务器端用它的私钥解密出会话密钥
  5. 至此双方完成连接,接下来服务器端和客户端可以使用对称加密算法和会话密钥加密解密数据

RSA的优势在于原理非常简单,计算快,但同时也有一些重大的安全缺陷:

  • 会话密钥的生成全部依赖客户端生成,如果客户端生成密钥方式不可靠,则会话还是有泄露风险

  • 缺乏前向安全性,如果服务端私钥泄漏,则所有历史通信都可以被破解(前向安全性指的是长期使用的主密钥泄漏不会导致过去的会话密钥泄漏)

DH算法

DH(Diffie-Hellman)密钥协商算法是由美国密码学家惠特菲尔德·迪菲(Whitfield Diffie)和马丁·赫尔曼(Martin Hellman)于1976年发明的。当时,迪菲和赫尔曼在斯坦福大学从事密码学研究,他们提出了一种新的密钥交换算法,该算法可以在通信双方没有事先共享密钥的情况下,安全地协商出一个共享密钥,从而实现加密通信。DH算法协商过程如下:

  1. 客户端发起连接,请求协商参数
  2. 服务端生成密钥协商参数,并发送给客户端
    • pp:很大的一个质数
    • gggg是模pp的原根,一般就是2或者5
  3. 服务端随机生成私钥aa,并根据密钥协商参数生成公钥AA,并发送给客户端
A=gamodp(1)A=g^a \bmod{p} \tag{1}
  1. 同理,客户端随机生成私钥bb,并根据密钥协商参数生成公钥BB,并发送给服务端
B=gbmodp(2)B=g^b \bmod{p} \tag{2}
  1. 服务端和客户端分别通过以下式生成会话密钥
C1=Bamodp=gabmodp(3)C_1=B^a\bmod{p}=g^{ab}\bmod{p} \tag{3}
C2=Abmodp=gbamodp(4)C_2=A^b\bmod{p}=g^{ba}\bmod{p} \tag{4}

显然有C1=C2C_1=C_2,这就是会话密钥

这里我们来考察下安全性,假设有攻击者截获了密钥协商参数ppgg以及双方的公钥AABB,是否能破解得到密钥CC呢?答案是否定的,要想得到CC,必须得从1式12式2计算出aabb。这是一个经典的离散对数问题,目前计算的破解能力非常有限

相较于RSA算法,DH算法的协商过程是需要双方共同完成的,密钥随机性有了保障。另外在前向安全性方面,如果DH的密钥协商参数每次都不一样,则即使某次私钥泄漏了,也只会影响到使用了该私钥的某次会话,其他的历史会话还是不能被破解,这就大大提升了通信安全性。

这里我们将每次密钥协商参数都不同的DH算法称为动态DH算法,优势很明显,具有了前向安全性,但由于每次会话都需要计算私钥,也会额外消耗服务器的性能。

刚提到ECDH算法和DH算法类似,只不过在DH算法的基础上融入了ECC椭圆曲线算法,相同密钥长度下安全性有了提升,这里就不在赘述

数字签名

现在介绍公开密钥算法的的最后一种,数字签名。数字签名主要解决的就是防抵赖问题,什么是防抵赖,即A发送一条消息,所有人都知道这是A发送的,A不可抵赖说这不是它发的。

现实生活中有类似的例子,比如按了手印的合同,每个人的指纹都是独一无二的,在合同上按了指纹,相当于本人承认了合同的有效性。

那在计算机通信中有类似于指纹的东西吗?结合上述的知识,很容易想到私钥就是独一无二的,且能唯一标志服务身份,服务方A可以用自己的私钥给消息加上签名,然后和消息一起发送出去,接收到消息的人,如果能用服务方A的公钥验证签名通过,说明这条消息的确就是A发的,且A不可抵赖,因为只有A才有A的私钥。这就是数字签名技术的主要原理了。

数字签名过程

image.png

  1. 发送者对消息计算摘要值
  2. 发送者用私钥对摘要值进行签名得到签名值
  3. 发送者将原始消息和签名值一同发给接收者

数字签名验证过程

image.png

  1. 接收者接收到消息后,拆分出消息和消息签名值A
  2. 接收者使用公钥对消息进行运算得到摘要值B
  3. 接收者对摘要值B和签名值A进行比较,如果相同表示签名验证成功,否则就是验证失败

目前主要的数字签名算法包括RSA、DSA(Digital Signature Algorithm)算法以及ECDSA(基于ECC椭圆曲线的DSA数字签名算法),本文依次介绍下RSA和DSA:

RSA

设消息为MM,消息的摘要值为mm,则签名结果ss计算如下:

s=mdmodN(1)s=m^d\bmod{N} \tag{1}

消息验证如下,计算mm后和MM的实际摘要值对比:

m=semodN(2)m=s^e\bmod{N}\tag{2}

DSA

DSA是一种用于数字签名的算法,是美国国家标准技术研究所(NIST)于1991年制定的,基于离散对数问题和有限域上的数论,可以用于数字签名和密钥交换等安全通信场景,计算签名过程如下:

  1. DSA主要通过参数文件计算密钥对,参数包含:
    • pp:很大的质数,建议1024比特,pp的长度关乎算法的安全性
    • qq:160比特,且p1p-1qq的倍数
    • gg:数值来自于ppqq数学表达式的计算
  2. 生成DSA密钥对:
    • 选择一个随机数xx作为私钥,满足0<x<q0<x<q
    • 基于私钥xx生成公钥yy,满足y=gxmodpy=g^x\bmod{p}
  3. 计算签名
    • 生成随机数kk,满足1<k<q1<k<q
    • 计算r=(gkmodp)modqr=(g^k\bmod{p})\bmod{q}
    • 计算s=(m+xrk)modq      其中m是消息M的摘要值s=(\frac{m+xr}{k})\bmod{q}\;\;\;其中m是消息M的摘要值
    • 签名值即(r,s)(r,s),跟随原消息MM一起发送
  4. 签名验证
    • 计算w=1smodqw=\frac{1}{s}\bmod{q}
    • 计算u1=mwmodqu_1=m·w\bmod{q}
    • 计算u2=rwmodqu_2=r·w\bmod{q}
    • 计算v=(gu1yu2modp)modqv=(g^{u_1}*y^{u_2}\bmod{p})\bmod{q}
    • 如果v==rv==r,则表示验证通过,反之失败

证明过程有兴趣的可以自行取了解一下

总结

好了,以上就是公开密钥算法的全部内容了,我们从定义入手,然后依次介绍了具体的非对称密钥、密钥协商以及数字签名算法,涉及到的数学公式以及推导证明较多,大家理解原理即可,不必完全掌握数学证明过程

在这些算法中,RSA算法在各个具体的场景下都有实际的应用,不愧是公开密钥算法中最经典的一个,大家可以从RSA算法入手,纵向了解下上述三个应用场景

在下一章节,我们将要给大家介绍下数字签名技术的继续推广,数字证书技术,它是HTTPS体系中非常重要的环节,也是大家经常接触到的部分,希望本章节给大家打下一个好的基础,下章再见!