极客时间-实用密码学-10怎么防止数据重放攻击

2024-06-20 03:08

本文主要是介绍极客时间-实用密码学-10怎么防止数据重放攻击,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为什么还要学习 CBC 模式?

不知道你是不是已经有了一个问题:既然 CBC 要退出历史舞台了,我们还学习它干什么呢?

第一个原因,CBC 的退出进程可能需要十数年才能完成。你现在工作的项目种,可能还存在 CBC 模式的大量使用。我们学习了 CBC 模式,有助于你解决现存项目的安全问题。

第二个原因,学习针对 CBC 的攻击方案, 是我们深入理解加密算法安全问题的最好的切入点。了解这些安全缺陷和攻击方案,有助于你更好地使用密码学的算法。因为,这些缺陷也可能换个面孔,出现在应用程序层面。如果你能够说清楚 CBC 模式的攻击办法,也就意味着你已经试着走入了算法的细节。

第三个原因,也是最重要的原因,就是我们要进一步地理解初始化向量和链接模式对加密算法的影响。学习 CBC 模式会为我们将来讨论更高级的协议和更安全的算法打下基础。那么,CBC 模式是什么样子的?它是怎么解决数据重放攻击的?它存在哪些安全陷阱?这是我们这一次要解决的问题。

CBC模式加密流程

CBC链接流程
如上图,每一个明文分组加机密前都会与上一个密文分组做异或运算,第一个明文数据与初始化向量做异或,再送入加密函数加密。

解密流程如下:
CBC解密流程
将密文分组送入解密函数,将输出与上一个密文分组做异或得到明文数据,第一个分组与初始化向量异或。

CBC模式关键点:

  • 加密解密都要使用初始化向量
  • 加密解密初始化向量等同的
  • 上一次的密文分组参与下一次的加密和解密运算

初始化向量需要保密吗?

如果每一次运算,初始化向量都能不重复,即使是相同的明文数据,它的加密结果也是不同的。但是,如果初始化向量重复使用,相同的明文就会有相同的密文。重复使用的初始化向量,会消解密文反馈的作用,使得 CBC 模式和 ECB 模式一样脆弱。

所以,初始化向量的唯一性在加密运算的安全性中至关重要。

那你会问了,既然初始化向量这么重要,那我们需要对它进行保密吗?初始化向量并不需要保密。如果你对这一点有疑问,不妨换个角度想一想:每一个分组加密的初始化向量都是上一次加密运算得到的密文分组,而密文分组是可以公开的信息。

异或运算会不会有问题?

我在上面的讲解中提到了异或运算,其实,它在密码算法里有广泛的应用,为什么它如此广泛

第一个原因是异或运算是按位运算,所以在相同的计算环境下,异或运算时间只和数据的位数相关,和数据的实际数值无关。

换句话说,如果运算时间和数据数值相关,而且别人还了解到这种相关性,他就可以通过统计学的方法,通过观察、测算运算时间,找到运算时间和数据数值之间的关联,来破解密码。

第二个原因同样是按位运算,在相同的计算环境下,异或运算的复杂度,也就是需要的算力,只和数据的位数相关,和数据的实际数值无关。而且,一个运算需要的算力,在计算机环境中,可以通过占用的 CPU 周期数,以及消耗的内存空间来衡量。

同理,如果占用的 CPU 或者消耗的内存和数据数值相关,别人就可以通过统计学的办法,然后观察 CPU 的占用、电力消耗或者内存的消耗,来破解密码。一般来说,这种相关性,也会影响运算时间,从而使得基于测算运算时间的攻击方式同样有效。

不光如此,如果运算的复杂度和数据数值相关,密码破解的办法可就是千奇百怪的了。记录、测算计算机的噪音、温度、辐射、反应时间等等,都有可能成为有效的攻击手段。

如果让一个一流的黑客,拿着手机进入数据中心,录一段服务器发出的声音,说不定你的服务器就被攻陷了。之所以没有说一定会被攻破,是因为近几年的密码学进展,已经发展出了具有防范能力的算法和实现。

但是,如果你的服务器使用的是十年前的技术和软件,黑客得手的概率还是有的。我们后面会讨论这些新技术和新算法。

第三个原因和异或运算的运算特点有关,也就是相同的数据归零,不同的数据归一

  • 归零律:如果两段数据完全相同,它们的异或运算结果,就是每一位都是零的数据;
  • 恒等律:如果一段数据和一段全是零的数据进行异或运算,前一段数据中是零的位运算后还是零,是一的位运算后还是一。也就是说,和零进行异或运算,不改变原数据的数值。

正是异或运算的归零律和恒等律,CBC 模式才能成立,解密才能进行。这两个性质,还使得解密运算和加密运算具有相同的运算效率。

如果两段数据中只有一位不同,它们的异或运算结果,就是只有这一位的数据是一,其他的数据都是零。那是不是我们就可以通过构造明文分组或者密文分组,一次改变一位数据,然后把数据交给加密运算或者解密运算来处理,通过观察加密或者解密的结果展开攻击了?

比如说,一个 128 位的密钥,它的强度能承受 2^128 次的运算,是一个强度的指数级别的量级。

  • 如果我们一次改变一位数据的攻击方式得逞,最多需要 128 次的运算;
  • 如果我们一次只能观测一个字节,一次一位的改变需要 2^8 = 256 次,这样的攻击方式得逞,最多需要 255 * 16 = 4080 次的运算。

这样的运算强度,和设计的理论值 2^128 相差太远了,一次有效的破解也就是分分钟的事情。

还别说,这样的攻击方式在实践中真的是可行的。这种攻击方式,把 CBC 模式变成了一个充满陷阱的模式。用的好,它就是安全的;用的不好,它就会惹来麻烦。这实在不符合密码算法要皮实、耐用的要求。

密钥少一位会有影响吗?

不知道你有没有注意到,我们上面的讨论,提到了数据的位数。

因为分组加密是按照固定的分组进行加解密运算,所以每一次的分组运算,数据的位数都是固定的。比如,AES 算法的分组大小都是 128 位。所以,我们不用担心分组运算的数据位数的变化。

在分组运算中,初始化向量、密文分组和明文分组密钥的数据位数也都是固定的。所以,我们也不需要担心它们的位数的变化。加密算法和解密算法不涉及数据位数,所以我们也不担心算法。剩下的一个变量,就是密钥了。密钥的位数会变化吗?密钥的位数变化有影响吗?

一般来说,我们也不太关心密钥的位数变化,密钥少一位似乎也不是什么无关紧要的事情。所以,出于互操作性的考虑,很多标准和协议(包括应用最广泛的 TLS 1.2 协议)需要把密钥的高位的零清除掉,然后再参与运算。

原来 128 位的密钥,可能就被清除成了 127 位或者 126 位的密钥了。2018 年发布的的 TLS 1.3 版本,不再需要清除密钥高位的零。少一位密码,当然会带来计算性能的差异,以及由此引发的计算时间偏差。可是,似乎 2020 年之前,没有人担心这件事。

直到 2020 年 9 月 8 日,一个名字叫做“浣熊攻击”的安全研究成果发布了。浣熊攻击可以利用密钥高位清零造成的运算时间差,通过观察、测算运算时间,运用统计学的技术破解运算密钥。这实在是一个了不起的发现。

目前来看,这种攻击方式还比较复杂,不容易执行。但是,一旦发现攻击方法,如果业界没有采取及时的措施,攻击技术的改进速度是惊人的。“浣熊攻击”出现,再一次敲了敲大门,警告我们要尽量避免计算时间偏差和计算算力偏差,谨慎地处理不可避免的计算时间偏差和算力偏差

这篇关于极客时间-实用密码学-10怎么防止数据重放攻击的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076926

相关文章

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核