[计算机网络]网络加密
为什么需要加密?#
因为http的内容是明文传输的,明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击。所以我们才需要对信息进行加密。最容易理解的就是对称加密 。
什么是对称加密?#
简单说就是有一个密钥,它可以加密一段信息,也可以对加密后的信息进行解密,和我们日常生活中用的钥匙作用差不多。
用对称加密可行吗?
如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。然而最大的问题就是这个密钥怎么让传输的双方知晓,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,那在这个传输过程中密钥被别人劫持到手了怎么办?之后他就能用密钥解开双方传输的任何内容了,所以这么做当然不行。
换种思路?试想一下,如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器只要预存好世界上所有HTTPS网站的密钥就行了!这么做显然不现实。
怎么办?所以我们就需要非对称加密 。
什么是非对称加密?#
简单说就是有两把密钥,通常一把叫做公钥、一把叫私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。他们之间互为钥匙互为锁
。
用非对称加密可行吗?
鉴于非对称加密的机制,我们可能会有这种思路:服务器先把公钥以明文方式传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,这条数据的安全似乎可以保障了!因为只有服务器有相应的私钥能解开公钥加密的数据。然而反过来由服务器到浏览器的这条路怎么保障安全?如果服务器用它的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,若这个公钥被中间人劫持到了,那他也能用该公钥解密服务器传来的信息了。所以目前似乎只能保证由浏览器向服务器传输数据的安全性(其实仍有漏洞,下文会说),那利用这点你能想到什么解决方案吗?
改良的非对称加密方案#
我们已经理解通过一组公钥私钥,可以保证单个方向传输的安全性,那用两组公钥私钥,是否就能保证双向传输都安全了?
请看下面的过程:
- 某网站服务器拥有公钥A与对应的私钥A’;浏览器拥有公钥B与对应的私钥B’。
- 浏览器把公钥B明文传输给服务器。
- 服务器把公钥A明文给传输浏览器。
- 之后浏览器向服务器传输的内容都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有私钥A’,所以能保证这条数据的安全。
- 同理,服务器向浏览器传输的内容都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全。
的确可以!抛开这里面仍有的漏洞不谈(下文会讲),HTTPS的加密却没使用这种方案,为什么?很重要的原因是非对称加密算法非常耗时,而对称加密快很多。那我们能不能运用非对称加密的特性解决前面提到的对称加密的漏洞?
非对称加密+对称加密#
既然非对称加密耗时,那非对称加密+对称加密结合可以吗?而且得尽量减少非对称加密的次数。当然是可以的,且非对称加密、解密各只需用一次即可。
请看一下这个过程:
- 某网站拥有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
- 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都通过密钥X加密解密即可。
完美!HTTPS基本就是采用了这种方案。完美?还是有漏洞的。
中间人攻击#
如果在数据传输过程中,中间人劫持到了数据,此时他的确无法得到浏览器生成的密钥X,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开它,然而中间人却完全不需要拿到私钥A’就能干坏事了。请看:
- 某网站有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)。
- 浏览器生成一个用于对称加密的密钥X,用公钥B(浏览器无法得知公钥被替换了)加密后传给服务器。
- 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
这样在双方都不会发现异常的情况下,中间人通过一套“狸猫换太子”的操作,掉包了服务器传来的公钥,进而得到了密钥X。根本原因是浏览器无法确认收到的公钥是不是网站自己的
,因为公钥本身是明文传输的,难道还得对公钥的传输进行加密?这似乎变成鸡生蛋、蛋生鸡的问题了。解法是什么?
如何证明浏览器收到的公钥一定是该网站的公钥?
其实所有证明的源头都是一条或多条不证自明的“公理”(可以回想一下数学上公理),由它推导出一切。比如现实生活中,若想证明某身份证号一定是小明的,可以看他身份证,而身份证是由政府作证的,这里的“公理”就是“政府机构可信”,这也是社会正常运作的前提。那能不能类似地有个机构充当互联网世界的“公理”呢?让它作为一切证明的源头,给网站颁发一个“身份证”?
它就是CA机构,它是如今互联网世界正常运作的前提,而CA机构颁发的“身份证”就是数字证书。
数字证书#
网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明“该公钥对应该网站”。而这里又有一个显而易见的问题,“证书本身的传输过程中,如何防止被篡改”?即如何证明证书本身的真实性?身份证运用了一些防伪技术,而数字证书怎么防伪呢?解决这个问题我们就接近胜利了!
如何放防止数字证书被篡改?
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名:
数字签名#
数字签名的制作过程:
- CA机构拥有非对称加密的私钥和公钥。
- CA机构对证书明文数据T进行hash。
- 对hash后的值用私钥加密,得到数字签名S。
- 明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。
那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)
- 拿到证书,得到明文T,签名S。
- 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
- 用证书里指明的hash算法对明文T进行hash得到T’。
- 显然通过以上步骤,T’应当等于S‘,除非明文或签名被篡改。所以此时比较S’是否等于T’,等于则表明证书可信。
为何么这样可以保证证书可信呢?我们来仔细想一下。
中间人有可能篡改该证书吗?#
假设中间人篡改了证书的原文,由于他没有CA机构的私钥,所以无法得到此时加密后签名,无法相应地篡改签名。浏览器收到该证书后会发现原文和签名解密后的值不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
既然不可能篡改,那整个证书被掉包呢?
中间人有可能把证书掉包吗?#
假设有另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?
其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。
为什么制作数字签名时需要hash一次?
我初识HTTPS的时候就有这个疑问,因为似乎那里的hash有点多余,把hash过程去掉也能保证证书没有被篡改。
最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加解密就快很多。
怎么证明CA机构的公钥是可信的?#
你们可能会发现上文中说到CA机构的公钥,我几乎一笔带过,“浏览器保有它的公钥”,这是个什么保有法?怎么证明这个公钥是否可信?
让我们回想一下数字证书到底是干啥的?没错,为了证明某公钥是可信的,即“该公钥是否对应该网站”,那CA机构的公钥是否也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中会有CA机构的根证书,这样就可以拿到它对应的可信公钥了。
实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链或数字证书链。也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。
另外,不知你们是否遇到过网站访问不了,提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书(风险自己承担XD)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。
总结#
- 浏览器本身持有一些根证书,根证书中有CA机构的公钥,
- 浏览器向CA机构请求某某网站的证书,也就是想要得到这个网站的公钥,
- CA机构用自己的私钥签名这个网站的证书传给浏览器,
- 浏览器用CA机构的公钥验证这个证书的可信性,
- 证明可信后即可得到某某网站的正确公钥,
- 用这个公钥保证浏览器向网站发送信息的秘密性,在这个安全的通道里传输一个密码
- 网站得到密码,
- 此后网站和浏览器用只有他们两个才有的密码互相通信。
补充:为什么非对称加密很慢#
对称加密 通常比 非对称加密 更快的原因在于它们的加密方式、密钥操作的复杂度、算法的计算量和设计目标的不同。
1. 加密方式的不同#
-
对称加密:在对称加密中,加密和解密使用 相同的密钥,加密算法的主要操作是基于简单的数学运算(如位操作、置换、代换等),因此计算速度非常快。对称加密算法如 AES、DES 都是基于这样的设计,用来处理大数据量时效率较高。
-
非对称加密:非对称加密则使用 一对密钥(公钥和私钥)。加密过程使用公钥,加密后的数据只能用私钥解密,反之亦然。非对称加密算法,如 RSA、ECC,依赖于复杂的数学运算(如大数的幂模运算、椭圆曲线运算等),这些运算非常耗时,特别是对大数据块的加解密时性能表现较差。
2. 密钥操作的复杂度#
-
对称加密算法的密钥操作简单:对称加密算法的设计目标是处理大量数据,通常只涉及简单的置换和代换操作,并且可以对大块数据进行快速操作。因此,密钥操作在加密和解密过程中都很高效。
-
非对称加密算法的密钥操作复杂:非对称加密中的加解密过程依赖复杂的数学操作,如大素数分解、椭圆曲线离散对数等,这些操作设计的初衷是为了确保安全性,因此计算量非常大,尤其是随着密钥长度增加,计算复杂度呈指数级增长。特别是 RSA,它的加解密过程涉及大数幂模运算,这种操作的计算开销非常高。
3. 算法设计的目标#
-
对称加密的设计目标是高效处理大量数据:对称加密主要用于大量数据的加密和解密,例如文件加密、通信加密等场景。其算法如 AES,是为快速处理大块数据而设计的,可以通过并行化操作和硬件加速(如 AES-NI 指令集)进一步提高性能。
-
非对称加密的设计目标是密钥分发和数字签名:非对称加密主要用于密钥分发、身份验证和数字签名等场景,而不是用于大规模数据的加密。由于非对称加密的运算成本较高,它通常只用于加密小块数据,如对称加密的密钥,而不会直接用于大数据量的加密和解密操作。
4. 密钥长度的影响#
-
对称加密的密钥长度较短:在对称加密中,常见的密钥长度为 128 位、192 位、256 位(如 AES 算法)。虽然密钥相对较短,但由于对称加密算法的安全性依赖于密钥的随机性和算法的复杂性,这样的密钥长度已经能够提供非常高的安全性。
-
非对称加密的密钥长度较长:非对称加密需要较长的密钥来保证安全性。比如,RSA 需要 2048 位甚至更长的密钥才能保证足够的安全性。密钥越长,计算的复杂度就越高,从而导致加解密速度变慢。
5. 应用场景的不同#
-
对称加密用于大量数据加密:由于对称加密的速度非常快,通常用于大规模数据的加密,如文件传输、硬盘加密、SSL/TLS 会话数据加密等。其加密和解密效率非常高,适合处理大量的数据。
-
非对称加密用于密钥交换和身份验证:由于非对称加密的速度较慢,主要用于加密较小的数据量,通常用在加密对称密钥或进行数字签名。在 SSL/TLS 中,非对称加密主要用于安全地交换对称密钥,一旦密钥交换完成,后续的数据传输则使用对称加密。
性能对比的示例#
对称加密的效率(如 AES-256):#
- AES 加密在软件层面上非常快,并且有专门的硬件支持(如 AES-NI 指令集)。
- 处理一段 1MB 数据的加密,AES 可能只需要几毫秒。
非对称加密的效率(如 RSA-2048):#
- RSA 的加密速度较慢,因为它涉及复杂的数学运算。
- 加密 1MB 数据可能需要几十秒到几分钟,因此通常用于加密小数据块(如对称密钥)。
总结#
- 对称加密更快,因为它使用相对简单的数学操作(如位操作、置换、代换),适合大数据量的快速加解密。
- 非对称加密较慢,因为它依赖于复杂的数学运算(如大数幂模运算、椭圆曲线运算),主要用于小数据量的加密,如密钥交换和数字签名。
- 因此,常见的方案是 使用非对称加密来交换对称加密的密钥,然后使用对称加密进行大量数据的加密传输,从而在安全性和性能之间达到平衡。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~