DES数据加密标准

目录

  • 一、算法原理
    • 每一轮的加密过程
        • 1. 初始分组
        • 2. 16轮迭代加密
        • 3. F函数(核心加密步骤)
        • 4. 16轮加密结束
    • 密钥生成过程
  • 二、代码实例

一、算法原理

DES(数据加密标准)算法对明文数据进行16轮的替换和置换操作,每一轮都会生成一个不同的子密钥,并依次对数据块进行操作。

每一轮的加密过程

DES的每一轮都将64位的明文分为两个部分:左半部分(32位)和右半部分(32位)。加密操作实际上只对右半部分进行变换,而左半部分则直接参与异或运算。具体步骤如下:

1. 初始分组
  • 将64位明文经过初始置换(Initial Permutation, IP),重新排列位的顺序,得到新的64位数据,并将其分为左右两部分:
    • 左半部分:L₀(32位)
    • 右半部分:R₀(32位)
2. 16轮迭代加密

每一轮都会使用不同的子密钥 (K_i),并将当前轮的左半部分 (L_i) 和右半部分 (R_i) 进行如下操作:

  • 步骤 1:将前一轮的右半部分 (R_{i-1}) 作为这一轮的新左半部分,即:

    L_i = R_{i-1}

  • 步骤 2:将前一轮的右半部分 (R_{i-1}) 送入 F函数,并与当前轮的子密钥 (K_i) 进行操作。F函数的详细步骤见后续。F函数的输出结果与前一轮的左半部分 (L_{i-1}) 进行异或运算,生成这一轮的新右半部分 (R_i),即:
    R_i = L_{i-1} ​⊕ F(R_{i-1}, K_i)

  • 步骤 3:继续进行下一轮。经过16轮后,左半部分和右半部分合并,形成64位的加密数据。

在每一轮操作中,左右两部分交换一次位置,从而保证密文与明文之间的复杂关系。

3. F函数(核心加密步骤)

F函数是DES算法中的关键步骤,用于生成复杂的加密结果。F函数将32位的右半部分 (R_{i-1}) 和48位的子密钥 (K_i) 结合起来,具体操作如下:

  • 扩展置换(E扩展):
    32位的右半部分 (R_{i-1}) 经过扩展置换操作,变成48位,扩展时根据一定的规则重复某些位。这一步的作用是增加密文的混淆性,并使其与48位的子密钥 (K_i) 进行异或操作。

  • 异或运算
    将扩展后的48位数据与48位的子密钥 (K_i) 进行异或运算,得到48位的新数据。

  • S盒替代
    将48位数据分成8组,每组6位(48位/6),然后使用8个不同的S盒(Substitution box,替代盒)对每组6位进行替代。S盒的作用是将6位的输入转化为4位的输出,从而将48位数据变成32位。每个S盒都有一个特定的查表,用于根据输入的6位值确定输出的4位值。

    S盒是DES中最重要的非线性变换步骤,是加密过程产生混淆的关键。

  • 置换操作(P盒置换)
    对S盒替代后的32位输出进行置换操作,将数据位重新排列,增加混淆性。经过这一置换操作后,得到最终的32位输出结果。

F函数的输出与当前轮的左半部分进行异或运算,完成这一轮的加密。

4. 16轮加密结束

在完成16轮加密后,得到两个部分:左半部分 (L_{16}) 和右半部分 (R_{16})。此时将这两个部分组合在一起,并进行逆初始置换(Inverse Initial Permutation, IP⁻¹),得到最终的64位密文。

密钥生成过程

DES使用的是一个56位的主密钥(尽管输入是64位的,但其中每8位用于校验,只留下56位用于实际加密),然后通过一系列的位移和置换操作,从这个主密钥中生成16个子密钥,每个子密钥长度为48位。

  1. 去掉奇偶校验位
    虽然输入的密钥是64位,但每8位中的第8位是奇偶校验位。因此,首先需要将64位的密钥中的校验位去除,剩下56位用于密钥生成。

  2. 密钥置换选择 1(PC-1)
    对去除校验位后的56位密钥进行第一次置换,称为置换选择1(Permutation Choice 1,PC-1)。PC-1会根据固定规则重新排列这56位密钥,将其分为两部分:左半部分 (C_0) 和右半部分 (D_0),每部分28位。

    初始56位密钥 -> PC-1 -> 28位的 C_0 和 28位的 D_0
    
  3. 左移操作
    在每一轮加密开始时,都会对(C_0) 和 (D_0) 进行左移操作。左移的位数不是固定的,而是根据当前轮次决定的。具体来说,每一轮的左移位数如下:

    • 第1、2、9、16轮:左移1位
    • 其他轮:左移2位

    每一轮左移后的值会生成新的 (C_i) 和 (D_i)。

    注意是循环左移

    C_0, D_0 -> 左移 -> C_1, D_1 -> 左移 -> C_2, D_2 -> …… -> C_16, D_16
    
  4. 密钥置换选择 2(PC-2)
    左移之后,将 (C_i) 和 (D_i) 组合成56位的密钥,然后使用置换选择2(Permutation Choice 2,PC-2)将这56位压缩为48位。这是通过从56位中选择48位进行排列完成的。PC-2的目的是通过重新选择位的位置并减少位数来生成本轮的子密钥 (K_i)(48位)。

    56位的 C_i + D_i -> PC-2 -> 48位的子密钥 K_i
    
  5. 生成16个子密钥
    通过左移和置换选择2的操作,DES一共会生成16个不同的48位子密钥 (K_1, K_2, …, K_{16}),分别用于每一轮的加密运算。

二、代码实例

# 将十六进制字符串转为二进制字符串
def hex_to_bin(hex_str):bin_str = bin(int(hex_str, 16))[2:].zfill(len(hex_str) * 4)return bin_str# 将二进制字符串转为十六进制字符串
def bin_to_hex(bin_str):hex_str = hex(int(bin_str, 2))[2:].upper().zfill(len(bin_str) // 4)return hex_str# DES初始置换表
IP = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7]# 逆初始置换表
IP_INV = [40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25]# 扩展置换表
E = [32, 1, 2, 3, 4, 5, 4, 5,6, 7, 8, 9, 8, 9, 10, 11,12, 13, 12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21, 20, 21,22, 23, 24, 25, 24, 25, 26, 27,28, 29, 28, 29, 30, 31, 32, 1]# S盒表
S_BOX = [# S1[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],# S2[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],# S3[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],# S4[[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],# S5[[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],# S6[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],[4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],# S7[[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],# S8[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]],
]# P盒置换表
P_BOX = [16, 7, 20, 21, 29, 12, 28, 17,1, 15, 23, 26, 5, 18, 31, 10,2, 8, 24, 14, 32, 27, 3, 9,19, 13, 30, 6, 22, 11, 4, 25]# 置换选择1(PC-1)表
PC_1 = [57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4]# 置换选择2(PC-2)表
PC_2 = [14, 17, 11, 24, 1, 5, 3, 28,15, 6, 21, 10, 23, 19, 12, 4,26, 8, 16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55, 30, 40,51, 45, 33, 48, 44, 49, 39, 56,34, 53, 46, 42, 50, 36, 29, 32]# 子密钥生成左移位数
SHIFT_SCHEDULE = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]# 将输入密钥转为64位,并去除校验位得到56位密钥
def key_permutation(key):# key = hex_to_bin(key)print('密钥的key:', key)key = ''.join(key[i - 1] for i in PC_1)return key[:28], key[28:]# 左移操作
def left_shift(key, shifts):return key[shifts:] + key[:shifts]# 根据C和D生成子密钥
def generate_subkeys(C, D):subkeys = []for shift in SHIFT_SCHEDULE:C = left_shift(C, shift)D = left_shift(D, shift)subkey = C + D# 这里也就是在PC_2的列表为下标,看subkey[i]是什么,全部赋值完后,加入到新的subkey中subkey = ''.join(subkey[i - 1] for i in PC_2)subkeys.append(subkey)return subkeys# 执行初始置换和逆置换
def permute(data, table):return ''.join(data[i - 1] for i in table)# 加密的核心f函数,包括扩展置换E、S盒和P盒
def f_function(R, K):# 1. 扩展置换R = ''.join(R[i - 1] for i in E)# 2. 与子密钥K进行异或   字符格式转换 int(K, 2)R = bin(int(R, 2) ^ int(K, 2))[2:].zfill(48)# 3. 经过S盒压缩result = ''for i in range(8):block = R[i * 6:(i + 1) * 6]row = int(block[0] + block[5], 2)col = int(block[1:5], 2)result += bin(S_BOX[i][row][col])[2:].zfill(4)# 4. 经过P盒置换result = ''.join(result[i - 1] for i in P_BOX)return result# DES加密函数
def des_encrypt(plaintext, key):# 1. 初始置换plaintext = permute(plaintext, IP)# 初始置换后的输出print('初始置换后的输出:', plaintext)# 2. 分成左右两部分L, R = plaintext[:32], plaintext[32:]print("R的值为:", R)# 生成16轮子密钥C, D = key_permutation(key)   # 去掉奇偶校验位subkeys = generate_subkeys(C, D)   # 使用列表将每一层密钥存储起来# 利用enumerate()函数,遍历密钥列表for i, subkey in enumerate(subkeys, 1):print(f"第{i}轮子密钥: {bin_to_hex(subkey)}")# 3. 进行16轮加密for i in range(16):L_new = R# 查看下变换前L的值if i == 0:print("第1轮的L变换前的值为:", L)R_new = bin(int(L, 2) ^ int(f_function(R, subkeys[i]), 2))[2:].zfill(32)L, R = L_new, R_newif i == 0:print("第1轮的R_new的值为:", R_new)print(f"第1轮输出: L = {bin_to_hex(L)}, R = {bin_to_hex(R)}")# 4. 合并L和R,逆初始置换combined = R + Lciphertext = permute(combined, IP_INV)return bin_to_hex(ciphertext)# 主函数
if __name__ == "__main__":plaintext = "0123456789ABCDEF"key = "133457799BBCDFF1"# 转为二进制plaintext_bin = hex_to_bin(plaintext)key_bin = hex_to_bin(key)print("明文的二进制:",plaintext_bin)print("密钥的二进制:", key_bin)# 加密ciphertext = des_encrypt(plaintext_bin, key_bin)print(f"最终密文: {ciphertext}")

下面这个链接是结合例子讲解的,讲的不错
链接: DES加密算法介绍(含例子)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java生成Excel_低内存占用_更快

EasyExcel:高效Java Excel工具,解决大文件读写难题 EasyExcel是一个基于Java的、快速简洁且能有效解决大文件内存溢出问题的Excel处理工具。它使得用户可以在无需过多关注性能和内存消耗的情况下,轻松实现Excel文件的读写功能。相较于传统的…

无头浏览器测试:如何使用 Puppeteer 和 Browserless?

什么是无头浏览器测试? 无头浏览器测试通常指没有头的物体或东西,在浏览器的语境中,它指的是没有 UI 的浏览器模拟。无头浏览器自动化使用 Web 浏览器进行端到端测试,而无需加载浏览器的 UI。 无头模式是一个功能,它…

Canvas:AI协作的新维度

在人工智能的浪潮中,OpenAI的最新力作Canvas,不仅是一款新工具,它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面,让用户能够与ChatGPT进行更紧密、更直观的协作。 ​​​​​​​ Canvas的…

Android targetSdkVersion 升级为34 问题处理

原因是发布到GooglePlay遭到拒绝,需要最低API level为34。之前为31,感觉还挺高的,但是GooglePlay需要的更高。 记录下处理问题: 1.升级gradle版本为8.0.2 之前是: classpath com.android.tools.build:gradle:7.1.0-…

sql注入第8关

手工注入麻烦 目录 判断闭合方式 判断注入类型 手工注入 1、获取数据库名 2、爆破数据库的名字(security) 3、爆破表的数量 4、判断表名的长度 5、判断表的列名数量 6、判断表的列名的名字 7、获取表的数据 8、判断数据的长度 9、判断数据的…

Golang | Leetcode Golang题解之第464题我能赢吗

题目&#xff1a; 题解&#xff1a; func canIWin(maxChoosableInteger, desiredTotal int) bool {if (1maxChoosableInteger)*maxChoosableInteger/2 < desiredTotal {return false}dp : make([]int8, 1<<maxChoosableInteger)for i : range dp {dp[i] -1}var dfs …

点云深度学习模型PointNet

随着3D传感器&#xff08;如激光雷达、深度相机&#xff09;的广泛应用&#xff0c;点云数据已成为计算机视觉和机器人领域的重要数据形式。点云是一组在三维空间中具有 (x, y, z) 坐标的离散点的集合&#xff0c;用于表示物体的形状或场景。然而&#xff0c;由于点云的无序性、…

pycharm生成的exe执行后报错

元素 application 显示为元素 urn:schemas-microsoft-com:asm.v1^dependentAssembly (此版本的 Windows 不支持)的子元素。 日志名称: Application 来源: SideBySide 日期: 2024/10/8 14:14:12 事件 ID: 72 任务类别: 无 级别…

docker升级mysql

一、首选备份原数据库所有数据 二、在Docker中查看正在运行的MySQL容器名称&#xff0c;可以使用以下命令&#xff1a; docker ps --filter "namemysql" 三、查看当前docker中正在运行mysql的版本 docker exec -it qgz-mysql mysql -V 可以看到当前运行的版本是8.…

[C++]使用纯opencv部署yolov8-cls图像分类onnx模型

【算法介绍】 使用纯OpenCV部署YOLOv8-cls图像分类ONNX模型涉及几个关键步骤。 首先&#xff0c;你需要将YOLOv8-cls模型从PyTorch格式转换为ONNX格式&#xff0c;这是为了确保模型在不同深度学习框架之间的互操作性。这个转换过程通常是通过ultralytics框架中的model.export…

大数据-158 Apache Kylin 安装配置详解 集群模式启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

C++刷怪笼(7)string类

目录 1.前言 2.正文 2.1标准库中的string类 2.1.1string类 2.1.2auto和范围for 2.1.3string类的常用接口说明 2.2string类的模拟实现 2.2.1经典的string类问题 2.2.2浅拷贝 2.2.3深拷贝 ​编辑 2.2.4写时拷贝 3.小结 1.前言 前面我们对C的封装这一大特性进行了详细…

【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货

前言 hi&#xff0c;正式接触web前端已经经过了两年的时间&#xff0c;从大学的java后端转型到web前端&#xff0c;再到后续转战Flutter&#xff0c;逐渐对前端有了一些心得体会&#xff0c;其实在当下前端的呈现形式一直在变化&#xff0c;无论你是用原生、还是web还是混编的…

吸毛效果好的宠物空气净化器分享,希喂、霍尼韦尔、米家实测

说起宠物空气净化器&#xff0c;几年前我可能会一脸鄙夷&#xff1a;为啥要花这种智商税冤枉钱&#xff1f; 直到之前养了一只猫&#xff0c;被家中乱飞的浮毛和滂臭的异味搞到头晕&#xff0c;于是作为i一个养宠的家电测评博主&#xff0c;索性对宠物空气净化器这玩意做了超级…

如何在银河麒麟服务器中获取关键日志信息

如何在银河麒麟服务器中获取关键日志信息 1、获取messages日志2、获取dmesg输出 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟服务器中&#xff0c;获取messages和dmesg日志是排查问题的重要步骤。 1、dmesg命令用于显示或控制…

PostgreSQL学习笔记二:PostgreSQL的系统架构

PostgreSQL 是一种功能强大的开源关系型数据库管理系统&#xff0c;其架构具有以下特点&#xff1a; 一、客户端/服务器架构 客户端 客户端可以是各种应用程序&#xff0c;如 Web 应用、桌面应用等&#xff0c;它们通过网络连接与 PostgreSQL 服务器进行通信。客户端使用标准的…

学习 PostgreSQL + Spring Boot 3 +mybatisplus整合过程中的报错记录

今天计划学习 PostgreSQL&#xff0c;并顺便尝试使用 Spring Boot 3.x 框架&#xff0c;打算整合 Spring Boot 3、PostgreSQL 和 MyBatis-Plus。整合后一直出现以下报错&#xff1a; 去AI上面搜了讲的是sqlSessionFactory 或 sqlSessionTemplate 没有正确配置 初始分析&#…

03 django管理系统 - 部门管理 - 部门列表

部门管理 首先我们需要在models里定义Dept类 # 创建部门表 class Dept(models.Model):name models.CharField(max_length100)head models.CharField(max_length100)phone models.CharField(max_length15)email models.EmailField()address models.CharField(max_length2…

【2024年10月测试通过】conda下使用虚拟环境安装最新版pytorch2.4+cuda12.4

开头先说重点&#xff1a; 1.采用conda的虚拟环境&#xff0c;会在沙盒环境下安装好所有所需包&#xff0c;而且该虚拟环境拷贝给其他人员可以直接用&#xff0c;很方便。 2.pytorch官网访问不了&#xff0c;有一个国内镜像推荐&#xff0c;地址为PyTorch - PyTorch 中文 3.…

怎么ping网络ip地址通不通

怎么Ping网络IP地址通不通&#xff1f;要检查网络中的IP地址是否连通&#xff0c;可以使用‌Ping命令。Ping命令通过发送ICMP&#xff08;Internet Control Message Protocol&#xff0c;因特网控制消息协议&#xff09;Echo请求报文并等待回应&#xff0c;来判断目标主机是否可…