对称加密算法(二)(分组密码,Feistel Cipher)

news2024/9/22 13:28:05

文章目录

  • Traditional Block Cipher Structure
    • Stream Ciphers and Block Ciphers
    • Feistel Cipher
  • References


Traditional Block Cipher Structure

Stream Ciphers and Block Ciphers

序列密码也称为流密码 (Stream Ciphers), 它是指每次对数字数据流的一个比特或一个字节进行加密的一种密码。我们在《对称加密算法(一)(替换算法,Caesar, Playfair, Hill Cipher,Polyalphabetic Cipher)》中介绍的 autokeyed Vigenère cipher 以及 Vernam cipher 就属于序列密码。序列密码利用密钥产生一个密钥流 Z=Z1Z2Z3…,然后利用此密钥流依次对明文 X=X0X1X2… 进行加密。

如果采用 one-time pad 的思想,密钥流是随机的,且和明文长度相同,那么攻击者除了掌握密钥流,其他任何手段都无法进行破解。然而,密钥流必须事先通过一些独立和安全的渠道提供给两个用户,但这种完全随机且长度非常长的密钥流生成是非常困难的(logistical problems)。

因此,由于实际原因,比特流生成器是作为一个算法程序来实现的,以便加密比特流可以由两个用户产生,如下图所示:

在这里插入图片描述

比特流生成器是一个由密钥控制的算法,我们要求它必须产生一个较为强大的密钥流。也就是说,攻击者很难根据密钥流的已知部分来预测后面的部分。两个用户只需要共享生成密钥,且都可以生成密钥流。


分组密码(block cipher)将明文消息编码表示后的数字序列,划分成长度为 n 的组,每组分别在密钥的控制下变换成等长的输出数字序列。通常,分组大小会取 64 比特或者 128 比特。分组密码的框图如下所示:

在这里插入图片描述

一般来说,分组密码比序列密码的应用更加广泛。绝大多数基于网络的对称加密应用都使用了分组密码。


Feistel Cipher

目前使用的几种重要的对称分组加密算法都是基于一种被称为费斯妥密码(Feistel block cipher)的对称结构。

在分组密码中,我们要把 n 比特的明文块转换为 n 比特的密文块。为了保证加密是可逆(reversible,或者叫 nonsingular)的(可以解密),我们需要生成的密文块都是唯一的。对于 n 比特的分组,我们总共会有 2 n 2^n 2n 个可能的密文块(可逆加密)。下面列出了 n=2 时一组可逆和不可逆加密的示意:

在这里插入图片描述

下图说明了 n=4 时的一个分组密码工作示意。一个 4 比特的输入会产生 16个 可能的密文块中的一个,解密时密文块会被映射回对应的输入:

在这里插入图片描述

该过程的映射规则由一个映射表定义:

在这里插入图片描述

我们将这种分组密码称为理想分组密码,因为它允许从明文块中进行最大数量的加密映射。

但对于理想分组密码来说,如果 n 比较小,例如上例中的 4,那么它几乎等价于传统的替换密码,这意味着它可以通过对统计特性的分析而被破解。如果 n 足够大,并且允许在明文和密文之间进行任意的可逆替换,那么明文的统计特征就会被掩盖,这种类型的密码分析就不可行了。但实现这样一个足够大且任意可逆的理想分组密码显然是不切实际的。

且这种方法的另一个问题在于,映射规则本身就含有密钥。例如,对于上面的映射表,我们的密钥其实就是第二列的 ciphertext,长度为 (4 bits) × (16 行) = 64 bits.

基于这些问题,Feistel 指出,我们需要的是对一个较大 n 值的理想分组密码系统的近似,且可以用易实现的器件去构造。

Feistel 提出,我们可以利用乘积密码的概念来近似理想的分组密码,即依次执行两个或更多的加密算法,使最终的乘积结果比单一的加密算法结果都更具有鲁棒性。该方法的本质是使用一个密钥长度为 k、块长度为 n 的分组密码,允许 2 k 2^k 2k 个可能的转换,而不再是理想分组密码的 2 n 2^n 2n 个转换。

实际上,Feistel 的设计基于香农的一个提议,即设计一个交替使用混淆(confusion)和扩散(diffusion)的乘积密码。

在密码学中,混淆(confusion)和扩散(diffusion)是设计密码学算法的两种主要方法。这样的定义最早出现在克劳德·香农 1945 年的论文《密码学的数学理论》当中。

在克劳德·香农的定义之中,混淆是一种使密钥与密文之间的关系尽可能模糊的加密操作;而扩散则主要是用来使明文和密文的关系变得尽可能的复杂,明文中任何一点小更动都会使得密文有很大的差异。

实现混淆常用的一个方法就是替换(substitution)。而扩散是一种为了隐藏明文的统计特性而将一个明文符号的影响扩散到多个密文符号的加密操作。最简单的扩散就是位置换(permutation)。

维基百科

一个扩散的例子为
y n = ( ∑ i = 1 k m n + k )   m o d   26 y_n=\left(\sum_{i=1}^k m_{n+k}\right)\ {\rm mod}\ 26 yn=(i=1kmn+k) mod 26

即使用接下来的连续 k k k 个字符来得到一个密文字符。


下面我们给出费斯妥密码的结构:

在这里插入图片描述

该图左边为加密过程,而右边为解密过程。加密算法的输入为长度 2 w 2w 2w 比特的明文块以及密钥 K K K。明文块被等分为两部分, L E 0 LE_0 LE0 R E 0 RE_0 RE0,在每一轮 i = 1 , 2 , … , n i=1, 2,\dots,n i=1,2,,n,我们都计算
L E i = R E i − 1 LE_i=RE_{i-1} LEi=REi1

R E i = L E i − 1 ⊕ F ( R E i − 1 , K i ) RE_i=LE_{i-1}\oplus {\rm F}(RE_{i-1}, K_i) REi=LEi1F(REi1,Ki)

而在解密时,我们的方法是完全一样的,除了密钥的顺序是相反的
L D i = R D i − 1 LD_i=RD_{i-1} LDi=RDi1

R D i = L D i − 1 ⊕ F ( R D i − 1 , K n − i + 1 ) RD_i=LD_{i-1}\oplus {\rm F}(RD_{i-1}, K_{n-i+1}) RDi=LDi1F(RDi1,Kni+1)

从图中我们还可以注意到,第 i i i 轮加密过后我们会得到 L E i ∣ ∣ R E i LE_i||RE_i LEiREi,而对应的 16 − i 16-i 16i 轮次后的解密则有 L D 16 − i ∣ ∣ R D 16 − i = R E i ∣ ∣ L E i LD_{16-i}||RD_{16-i}=RE_i||LE_i LD16iRD16i=REiLEi. 下面我们来具体计算一下看以上结果是否正确。

最后一轮加密过后我们有
L E 16 = R E 15 LE_{16}=RE_{15} LE16=RE15

R E 16 = L E 15 ⊕ F ( R E 15 , K 16 ) RE_{16}=LE_{15}\oplus {\rm F}(RE_{15}, K_{16}) RE16=LE15F(RE15,K16)
两部分互换位置之后得到了最终的密文 R E 16 ∣ ∣ L E 16 RE_{16}||LE_{16} RE16LE16,所以解密过程的输入即为 R E 16 ∣ ∣ L E 16 RE_{16}||LE_{16} RE16LE16

在解密的第一轮:
L D 1 = R D 0 = L E 16 = R E 15 LD_1=RD_0=LE_{16}=RE_{15} LD1=RD0=LE16=RE15

R D 1 = L D 0 ⊕ F ( R D 0 , K 16 ) = R E 16 ⊕ F ( R E 15 , K 16 ) = [ L E 15 ⊕ F ( R E 15 , K 16 ) ] ⊕ F ( R E 15 , K 16 ) = L E 15 \begin{aligned} RD_1=&LD_0\oplus {\rm F}(RD_0, K_{16}) \\ =& RE_{16} \oplus {\rm F}(RE_{15}, K_{16}) \\ =& [LE_{15}\oplus {\rm F}(RE_{15}, K_{16})] \oplus {\rm F}(RE_{15}, K_{16}) \\ =& LE_{15} \end{aligned} RD1====LD0F(RD0,K16)RE16F(RE15,K16)[LE15F(RE15,K16)]F(RE15,K16)LE15

最后一步计算用到了异或(XOR)的以下性质:
[ A ⊕ B ] ⊕ C = A ⊕ [ B ⊕ C ] [A \oplus B] \oplus C=A\oplus[B \oplus C] [AB]C=A[BC]

D ⊕ D = 0 D\oplus D=0 DD=0

E ⊕ 0 = E E \oplus 0=E E0=E

在上面的推导中我们应该也注意到了,函数 F F F 并没有参与到实际的运算当中,这意味着它不要求是一个可逆函数,即使它总是输出一个常数,我们也可以成功解密。

费斯妥结构的实现涉及到以下几个参数的选择:

  • Block size:更大的块长度意味着更高的安全性(更强的扩散),但同时也会导致加密和解密的速度降低。
  • Key size:和块大小类似,更大的密钥长度意味着更高的安全性(更强的混淆),但同时也会导致加密和解密的速度降低。
  • Number of rounds:轮次越多,越能保证安全,通常会选择 16.
  • Subkey generation algorithm:子密钥生成算法越复杂,密码分析就越困难。
  • Round function F:当然也是越复杂安全性越好。

尽管看起来我们把设计搞得越复杂越好,但越复杂的东西也意味着越高的成本,我们还需考虑下面两个因素:

  • Fast software encryption/decryption:在许多情况下,加密被嵌入到应用程序或实用功能中,因此,算法的执行速度需要被考虑。
  • Ease of analysis:尽管我们希望使我们的算法尽可能难以进行密码分析,但使算法易于分析也有很大的好处。也就是说,如果算法能够被简明扼要地解释,那么就更容易分析该算法的漏洞,从而对其做出改进。

References

Cryptography and Network Security: Principles and Practice, 7th Edition, ISBN 978-0-13-444428-4, by William Stallings, published by Pearson Education.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS -- CSS复合选择器总结

文章目录CSS的复合选择器1 什么是复合选择器2 后代选择器3 子选择器4 并集选择器5 伪类选择器6 链接伪类选择器7 :focus 伪类选择器8 复合选择器总结CSS的复合选择器 1 什么是复合选择器 在 CSS 中,可以根据选择器的类型把选择器分为基础选择器和复合选择器&#…

【博客554】k8s 中的 Client-Side Apply 和 Server-Side Apply

k8s 中的 Client-Side Apply 和 Server-Side Apply 背景 如果你经常与 kubectl 打交道,那相信你一定见过 kubectl.kubernetes.io/last-applied-configuration annotation,以及那神烦的 managedFields,像这样: kubectl get pods…

单元测试理论储备及JUnit5实战

概述 测试驱动开发,TDD,Test Driven Development,优点: 使得开发人员对即将编写的软件任务具有更清晰的认识,使得他们在思考如何编写代码之前先仔细思考如何设计软件对测试开发人员所实现的代码提供快速和自动化的支…

银保监机构保险许可证数据(2007-2022年)

保险是金融系统的重要组成部分,保险的经济补偿和资金融通功能对维持金融系统的稳定,维护整个社会的安定起着不可或缺的作用,因此,从现实意义上来讲,对于我国保险业系统性风险的研究是很有必要性的。 通过对保险业系统性风险的类型、传播机制的研究,可以有效防范并降低我国保险…

MATLB|基于粒子群优化算法的智能微电网调度(含风、光、微型燃气轮机、电网输入微网、储能)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑…

linux基本使用及服务器环境搭建

文章目录0.linux基本命令1.配置jdk环境变量2.安装tomcat3. mysql安装4.部署jar项目基本命令5. 前端项目继承到后端项目中0.linux基本命令 1.pwd 我在那里 2.who am i 我是谁 3.clear 清屏 4.ctrlc 强制停止 5.ip addr 查看地址 6.ping 是否联通网站 7.systemctl start|s…

分布式系统的解决方案,学好这个就够了

分布式、负载、消息队列等一些解决方案,在互联网公司应用已经非常普遍了,也是每一个程序员要成为技术专家、架构师必学的知识。 所以,今天给大家推荐一个开源项目,有关互联网项目常见的解决方案,通通都打包一起了。 …

10个 解放双手的 IDEA 插件,少些冤枉代码

正经干活用的 分享一点自己工作中得心应手的IDEA插件,可不是在插件商店随随便便搜的,都经过实战检验,用过的都说好。可能有一些大家用过的就快速划过就行了。 1、GenerateAllSetter 实际的开发中,可能会经常为某个对象中多个属性…

半监督下的点云

搬了这么个东东来~~ 不过他的名字有点容易叫大家混淆,所以没写标题上... 在训练阶段,只需少量的二维方框标注作为指导,本文的网络就可以从激光雷达方框中产生精确的具有三维属性的图像级长方体标注。 论文:https://arxiv.org/pdf/2211.0930…

【Dubbo3高级特性】「实战开发」自定义扩展实现Dubbo服务对外暴露的主机地址实战开发指南

内容主旨 本篇文章主要介绍了如何进行自定义Dubbo服务对外暴露的主机地址的实战技术方案,其中我们需要针对于服务提供者侧的host主机暴漏的目的以及如何进行定制化处理 特性说明 在Dubbo中,Provider启动时主要做两个事情 启动服务提供者的server端实…

基于C++实现(控制台+界面)通讯录管理系统【100010012】

个人通讯录管理系统 问题描述: 主要内容: 个人通讯录是记录了同学(包含一起上学的学校名称)、同事(包含共事的单位名称)、朋友(包含认识的地点)、亲戚(包含称呼&#…

Python小炼(2):文件操作

"一封信,写下太多如果" 如果有一定语言基础的,一定对文件操作十分得"熟悉"!当然,这种熟悉是 引起人恼怒的 也不为过。 python 也有自己的文件操作,那它跟C\C又有何不同呢? 一、文件的基本操作 (…

中国宗教活动场所数据库(数据+python代码)

通常研究,宗教活动场所与公司避税行为,社会整体信任水平以及民营企业创始资金来源等元素相关联。例如,企业注册地的宗教传统负向影响公司避税,企业注册地的宗教传统通过提高管理者的道德意识和强化管理者的风险规避倾向两条机制抑…

Swagger总结

目录 简介: openAPI Springfox: 简介 Springfox的使用 SwaggerUI的使用 Swagger配置 设置扫描的包 设置范围 Swagger常用注解: 控制类、方法生成接口信息 ApiParam ApiModel ApiModelProperty ApiIgnore ApiImplicitParam 部分图片来自百…

SpringBoot日志详解

⭐️前言⭐️ 🍉博客主页: 🍁【如风暖阳】🍁 🍉精品Java专栏【JavaEE进阶】、【JavaEE初阶】、【MySQL】、【数据结构】 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 …

rocketMq相关机制

rocketMq相关机制 topic读写队列 perm字段表示Topic的权限。有三个可选项。 2:禁写禁订阅,4:可订 阅,不能写,6:可写可订阅 这其中,写队列会真实的创建对应的存储文件,负责消息写入。…

小蓝本 第一本《因式分解技巧》第四章 拆项与添项 笔记(第四天)

小蓝本 第一本《因式分解技巧》第四章 拆项与添项 笔记(第四天)前言拆项与添项目的方法分组分解走平均分配分组分解走瞄准公式旧事重提第二章公式(9)好题习题4题目题解错题题号改错经验前言 芜湖,坚持做小蓝本的第四天,今天的知识…

基于LSTM、BP神经网络实现电力系统负荷预测(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

房屋装修设计技巧有哪些?有哪些注意事项

拥有自己的家是每个人的愿望,拥有一座新的房子是一种幸福。但是,作为一个装修小白,装修新房是一件很麻烦的事情。那么,房屋装修设计技巧是什么?房屋的装修设计应该注意些什么?下面我将详细解释一下。 房屋装…

pandas数据分析

目录 题目001: 把list变成一个Series 题目002: 把dict变成一个Series 题目003: 把Series转换成list 题目004: 把series变成一个DataFrame 题目005:用numpy创建Series 题目006:转换series的数据类型 …