密码学:解析Feistel网络结构及实现代码

article/2025/6/29 21:42:33

概述

Feistel网络是由IBM密码学家Horst Feistel在20世纪70年代提出的对称加密结构,已成为现代分组密码的核心框架。DESBlowfishRC5等经典加密算法均基于此结构。其核心思想是将输入明文分组分成左右两半,通过多轮迭代操作实现加密,每轮使用不同的子密钥和轮函数处理数据。Feistel结构具有加解密过程对称的特性,只需反转子密钥顺序即可实现解密,极大简化了实现复杂度。


关键特点

  1. 雪崩效应

    • 定义:输入微小变化(如1比特翻转)导致输出产生显著变化
    • 实现机制:轮函数扩散特性 + 左右数据交叉混合
    • 重要性:增强密码算法抵抗差分密码分析的能力

    在这里插入图片描述

  2. 结构对称性

    • 加密与解密使用相同结构
    • 仅需反转子密钥顺序即可解密
  3. 可证明安全性

    • 轮数足够多时可逼近理想密码模型
    • 安全性依赖轮函数设计质量

加解密过程

加密流程(n轮迭代)

1. 输入:明文分组M = (L0, R0)
2. 对于每轮i (1到n):Li = Ri-1Ri = Li-1 ⊕ F(Ri-1, Ki)   # Ki为第i轮子密钥
3. 输出密文:C = (Rn, Ln)   # 注意左右交换

在这里插入图片描述

解密流程

1. 输入密文:C = (Rn, Ln)
2. 对于每轮i (n到1):Ri-1 = LiLi-1 = Ri ⊕ F(Li, Ki)  # 使用与加密相同的子密钥序列
3. 输出明文:M = (L0, R0)
  • SP网络结构相比,Feistel网络结构的一个优点是,它的轮函数F不必可逆
    在这里插入图片描述

Java实现

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.spec.KeySpec;
import java.util.Arrays;public class FeistelCipher {// 使用DES的分组大小(64位/8字节)private static final int BLOCK_SIZE = 8; // DES分组大小private static final int HALF_BLOCK = BLOCK_SIZE / 2; // 4字节// 默认轮数private static final int DEFAULT_ROUNDS = 16;/*** PKCS#7填充 - 加密时使用* @param data 需要填充的数据* @return 填充后的数据*/public static byte[] padPKCS7(byte[] data) {int paddingLength = BLOCK_SIZE - (data.length % BLOCK_SIZE);byte[] padded = new byte[data.length + paddingLength];System.arraycopy(data, 0, padded, 0, data.length);// 填充字节的值等于填充长度Arrays.fill(padded, data.length, padded.length, (byte) paddingLength);return padded;}/*** PKCS#7去除填充 - 解密时使用* @param data 带填充的数据* @return 去除填充后的原始数据* @throws IllegalArgumentException 如果填充无效*/public static byte[] unpadPKCS7(byte[] data) {// 检查填充长度是否有效int paddingLength = data[data.length - 1] & 0xFF;if (paddingLength < 1 || paddingLength > BLOCK_SIZE) {throw new IllegalArgumentException("无效的PKCS#7填充");}// 验证所有填充字节是否正确for (int i = data.length - paddingLength; i < data.length; i++) {if (data[i] != paddingLength) {throw new IllegalArgumentException("无效的PKCS#7填充");}}return Arrays.copyOfRange(data, 0, data.length - paddingLength);}/*** DES轮函数实现* @param data 输入数据(半块大小,4字节)* @param key 轮密钥(8字节)* @return 轮函数处理结果(4字节)*/private static byte[] desFFunction(byte[] data, byte[] key) throws Exception {// 确保输入大小正确if (data.length != HALF_BLOCK) {throw new IllegalArgumentException("轮函数输入大小必须为" + HALF_BLOCK + "字节");}// 将4字节数据扩展为8字节(DES输入大小)byte[] expanded = new byte[BLOCK_SIZE];System.arraycopy(data, 0, expanded, 0, HALF_BLOCK);System.arraycopy(data, 0, expanded, HALF_BLOCK, HALF_BLOCK);// 使用DES ECB模式Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");// 创建DES密钥(仅使用前56位有效位)KeySpec keySpec = new DESKeySpec(key);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(keySpec);cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encrypted = cipher.doFinal(expanded);// 取结果的前4字节作为输出return Arrays.copyOf(encrypted, HALF_BLOCK);}/*** 从主密钥派生轮密钥* @param masterKey 主密钥* @param rounds 轮数* @return 轮密钥数组(每个8字节)*/public static byte[][] deriveRoundKeys(byte[] masterKey, int rounds) throws Exception {byte[][] roundKeys = new byte[rounds][8];MessageDigest sha256 = MessageDigest.getInstance("SHA-256");for (int i = 0; i < rounds; i++) {// 使用不同的盐派生每轮密钥sha256.update(masterKey);sha256.update((byte) i);byte[] hash = sha256.digest();// 取前8字节作为轮密钥System.arraycopy(hash, 0, roundKeys[i], 0, 8);}return roundKeys;}/*** Feistel网络加密* @param plaintext 明文* @param roundKeys 轮密钥* @return 密文*/public static byte[] encrypt(byte[] plaintext, byte[][] roundKeys) throws Exception {// 应用PKCS#7填充byte[] padded = padPKCS7(plaintext);byte[] ciphertext = new byte[padded.length];// 分块处理for (int block = 0; block < padded.length; block += BLOCK_SIZE) {// 分割左右块byte[] left = new byte[HALF_BLOCK];byte[] right = new byte[HALF_BLOCK];System.arraycopy(padded, block, left, 0, HALF_BLOCK);System.arraycopy(padded, block + HALF_BLOCK, right, 0, HALF_BLOCK);// 多轮迭代for (int round = 0; round < roundKeys.length; round++) {byte[] temp = right.clone();byte[] fResult = desFFunction(right, roundKeys[round]);// 左块与轮函数结果异或for (int i = 0; i < HALF_BLOCK; i++) {right[i] = (byte) (left[i] ^ fResult[i]);}left = temp;}// 合并结果(最后一轮不交换)System.arraycopy(left, 0, ciphertext, block, HALF_BLOCK);System.arraycopy(right, 0, ciphertext, block + HALF_BLOCK, HALF_BLOCK);}return ciphertext;}/*** Feistel网络解密* @param ciphertext 密文* @param roundKeys 轮密钥* @return 解密后的数据*/public static byte[] decrypt(byte[] ciphertext, byte[][] roundKeys) throws Exception {if (ciphertext.length % BLOCK_SIZE != 0) {throw new IllegalArgumentException("密文长度必须是块大小的倍数");}byte[] plaintext = new byte[ciphertext.length];for (int block = 0; block < ciphertext.length; block += BLOCK_SIZE) {byte[] left = new byte[HALF_BLOCK];byte[] right = new byte[HALF_BLOCK];System.arraycopy(ciphertext, block, left, 0, HALF_BLOCK);System.arraycopy(ciphertext, block + HALF_BLOCK, right, 0, HALF_BLOCK);// 反向使用子密钥for (int round = roundKeys.length - 1; round >= 0; round--) {byte[] temp = left.clone();byte[] fResult = desFFunction(left, roundKeys[round]);// 右轮与轮函数结果异或for (int i = 0; i < HALF_BLOCK; i++) {left[i] = (byte) (right[i] ^ fResult[i]);}right = temp;}System.arraycopy(left, 0, plaintext, block, HALF_BLOCK);System.arraycopy(right, 0, plaintext, block + HALF_BLOCK, HALF_BLOCK);}// 去除填充的数据plaintext = unpadPKCS7(plaintext);// 返回解密数据return plaintext;}public static void main(String[] args) throws Exception {// 示例主密钥byte[] masterKey = "MySecretKey".getBytes(StandardCharsets.UTF_8);// 派生轮密钥int rounds = DEFAULT_ROUNDS;byte[][] roundKeys = deriveRoundKeys(masterKey, rounds);// 测试短文本(长度不足块大小)String shortText = "Short";System.out.println("测试短文本加密(长度不足块大小):");testEncryptionDecryption(shortText, roundKeys);// 测试长文本String longText = "This is a longer text that will require multiple blocks for encryption.";System.out.println("\n测试长文本加密:");testEncryptionDecryption(longText, roundKeys);}private static void testEncryptionDecryption(String text, byte[][] roundKeys) throws Exception {byte[] plaintext = text.getBytes(StandardCharsets.UTF_8);System.out.println("原始文本: " + text);System.out.println("原始长度: " + plaintext.length + " 字节");// 加密byte[] ciphertext = encrypt(plaintext, roundKeys);System.out.println("加密后长度: " + ciphertext.length + " 字节");// 解密byte[] decrypted = decrypt(ciphertext, roundKeys);System.out.println("解密后文本: " + new String(decrypted, StandardCharsets.UTF_8));System.out.println("解密后长度: " + decrypted.length + " 字节");// 验证if (Arrays.equals(plaintext, decrypted)) {System.out.println("验证成功: 原始文本与解密文本匹配");} else {System.out.println("验证失败: 原始文本与解密文本不匹配");}}}
  • 关键设计要素
  1. 轮函数(F函数)

    • 决定密码安全强度的核心组件
    • 需满足非线性、混淆和扩散特性
  2. 密钥调度

    • 主密钥扩展为多轮子密钥的过程
    • 设计目标:消除密钥相关性,抵抗相关密钥攻击
  3. 轮数选择

    • 权衡安全性与性能的关键参数
    • 典型值:DES使用16轮,AES-128使用10轮

总结

Feistel网络通过其优雅的对称结构和可证明安全性,奠定了现代密码学的工程基础。其核心设计哲学——通过简单操作的迭代实现复杂安全目标,至今仍在新型密码设计中焕发生机。随着量子计算的发展,基于Feistel结构的后量子密码研究也展现出新的可能性。


http://www.hkcw.cn/article/UWKJbUmRtJ.shtml

相关文章

JavaSE知识总结(集合篇) ~个人笔记以及不断思考~持续更新

目录 集合 List List的各种接口API List的五种遍历方式 List的删除是内部是怎么做的&#xff1f; ArrayList和LinkedList的区别 Vetor和Stack是什么&#xff1f; Set Set的特点 HashSet TreeSet LinkedHashSet Map HashMap LinkedHashMap TreeMap 集合 在Java…

Linux中的mysql备份与恢复

一、安装mysql社区服务 二、数据库的介绍 三、备份类型和备份工具 一、安装mysql社区服务 这是小编自己写的&#xff0c;没有安装的去看看 Linux换源以及yum安装nginx和mysql-CSDN博客 二、数据库的介绍 2.1 数据库的组成 数据库是一堆物理文件的集合&#xff0c;主要包括…

也说字母L:柔软的长舌

英语单词 tongue&#xff0c;意为“舌头” tongue n.舌&#xff0c;舌头&#xff1b;语言 很显然&#xff0c;“语言”是引申义&#xff0c;因为语言是抽象的&#xff0c;但舌头是具象的&#xff0c;根据由简入繁的原则&#xff0c;tongue显然首先是象形起义&#xff0c;表达…

【机器学习】决策树

目录 一、引言 二、决策树的构造 三、决策树的ID3算法 四、决策树的C4.5算法 五、决策树的CART算法 六、动手实现决策树C4.5的算法详解步骤以及Python完整代码实现 一、引言 在机器学习中,有一种与神经网络并行的非参数化模型——决策树模型及其变种。顾名思义,决…

美提高钢铝关税至50% 欧盟深表遗憾 谈判进程加速

6月2日,欧盟委员会新闻发言人对美国宣布将钢铁和铝关税从25%提高至50%表示遗憾,认为这一决定加剧了大西洋两岸的经济不确定性。发言人提到谈判仍在继续,双方已同意加快谈判进程,并计划本周举行会谈。欧盟贸易专员塞夫科维奇将于6月4日在法国巴黎会见美国贸易代表格里尔。美…

基于ubuntu和树莓派环境对游戏进行移植

目录 一、在Ubuntu中对波斯王子游戏进行移植 1.1修改Ubuntu系统的仓库镜像网站为国内网站 1.2安装mininim 软件所依赖的库 1.3 编译mininim 软件 二、在树莓派中对波斯王子游戏移植 2.1安装相关环境 2.3编译mininim 软件 三、使用树莓派实现流水灯 一、在Ubuntu中对波…

设计模式——备忘录设计模式(行为型)

摘要 备忘录设计模式是一种行为型设计模式&#xff0c;用于在不破坏封装性的前提下&#xff0c;捕获对象的内部状态并在需要时恢复。它包含三个关键角色&#xff1a;原发器&#xff08;Originator&#xff09;、备忘录&#xff08;Memento&#xff09;和负责人&#xff08;Car…

Linux磁盘管理

磁盘基础 分类 运行方式与原理 详细信息 机械硬盘(HDD)-家用 电机带动磁盘高速旋转&#xff0c;读取数据&#xff1b;速度可以达到5400&#xff0c;7200 rpm&#xff08;round per minute-转/分钟&#xff09; 固态硬盘&#xff08;SSD) 集成电路与芯片&#xff0c;存储芯…

C# XAML 基础:构建现代 Windows 应用程序的 UI 语言

在现代 Windows 应用程序开发中&#xff0c;XAML (eXtensible Application Markup Language) 扮演着至关重要的角色。作为一种基于 XML 的声明性语言&#xff0c;XAML 为 WPF (Windows Presentation Foundation)、UWP (Universal Windows Platform) 和 Xamarin.Forms 应用程序提…

鸿蒙进阶——Mindspore Lite AI框架源码解读之模型加载详解(一)

文章大纲 引言一、模型加载概述二、核心数据结构三、模型加载核心流程 引言 Mindspore 是一款华为开发开源的AI推理框架&#xff0c;而Mindspore Lite则是华为为了适配在移动终端设备上运行专门定制的版本&#xff0c;使得我们可以在OpenHarmony快速实现模型加载和推理等功能&…

趋势因子均值策略思路

本策略旨在通过多种退出条件来管理交易头寸&#xff0c;以实现稳健的交易决策。策略的核心在于利用交易趋势因子&#xff08;ttf&#xff09;及其平均值&#xff08;ttfavg&#xff09;来判断市场趋势&#xff0c;并结合其他技术指标来制定买入、卖出和止损的决策。 交易逻辑思…

FDR的定位原理

一、FDR定位原理概述 频域反射法(FDR)通过分析被测设备在频域上的反射特征&#xff0c;来推断时域(距离域)上的故障位置和性质。当电磁波信号沿着传输线进行传播时&#xff0c;如果遇到阻抗不连续点&#xff0c;一部分能量会继续向前传播&#xff0c;另一部分能量则会反射回来。…

【保姆级教程】PDF批量转图文笔记

如果你有一个PDF文档&#xff0c;然后你想把它发成图文笔记emmm&#xff0c;最好再加个水印&#xff0c;你会怎么做&#xff1f; 其实也不麻烦&#xff0c;打开PDF文档&#xff0c;挨个截图&#xff0c;然后打开PS一张一张图片拖进去&#xff0c;再把水印图片拖进去&#xff0…

【机器学习|评价指标3】平均绝对误差(MAE)、平均绝对百分比误差(MAPE)、均方误差(MSE)、均方根误差(RMSE)详解,附代码。

【机器学习|评价指标3】平均绝对误差&#xff08;MAE&#xff09;、平均绝对百分比误差&#xff08;MAPE&#xff09;、均方误差&#xff08;MSE&#xff09;、均方根误差&#xff08;RMSE&#xff09;详解&#xff0c;附代码。 【机器学习|评价指标3】平均绝对误差&#xff0…

SpringBoot高校宿舍信息管理系统小程序

概述 基于SpringBoot的高校宿舍信息管理系统小程序项目&#xff0c;这是一款非常适合高校使用的信息化管理工具。该系统包含了完整的宿舍管理功能模块&#xff0c;采用主流技术栈开发&#xff0c;代码结构清晰&#xff0c;非常适合学习和二次开发。 主要内容 这个宿舍管理系…

【笔记】在 MSYS2 MINGW64 环境中安装构建工具链(CMake、GCC、Make)

&#x1f4dd; 在 MSYS2 MINGW64 环境中安装构建工具链&#xff08;CMake、GCC、Make&#xff09; ✅ 目标说明 记录在 MSYS2 的 MINGW64 工具链环境中&#xff0c;成功安装用于 C/C 构建的常用开发工具。 包括&#xff1a; GCC 编译器Make 构建系统CMake 跨平台构建工具基础开…

2_MCU开发环境搭建-配置MDK兼容Keil4和C51

MCU开发环境搭建-配置MDK兼容Keil4和C51 一、概述 本文以MDK-ARM V5.36版本基础介绍DMK-ARM工程兼容Keil4和C51的配置。 注:在阅读本文前,请先安装和配置完成MDK-ARM(Keil5)。 二、工具包下载 链接: https://pan.baidu.com/s/1Tu2tDD6zRra4xb_PuA1Wsw 提取码: 81pp 三、…

Redis部署架构详解:原理、场景与最佳实践

Redis部署架构详解&#xff1a;原理、场景与最佳实践 Redis作为一种高性能的内存数据库&#xff0c;在现代应用架构中扮演着至关重要的角色。随着业务规模的扩大和系统复杂度的提升&#xff0c;选择合适的Redis部署架构变得尤为重要。本文将详细介绍Redis的各种部署架构模式&a…

从0开始学习R语言--Day14--贝叶斯统计与结构方程模型

贝叶斯统计 在很多时候&#xff0c;我们经常会看到在统计分析中出现很多反直觉的结论&#xff0c;比如假如有一种病&#xff0c;人群中的患病率为1%&#xff0c;患者真患病时&#xff0c;检测结果为阳性的概率是99%&#xff0c;如果没有&#xff0c;则检测结果为阳性的概率是5…

免费的硬盘工具

—————【下 载 地 址】——————— 【​本章下载一】&#xff1a;https://pan.xunlei.com/s/VORkn5VgcUDScW2C5kyqIyX5A1?pwdw5db# 【​本章下载二】&#xff1a;https://pan.quark.cn/s/dc84a71de32a 【百款黑科技】&#xff1a;https://ucnygalh6wle.feishu.cn/wiki/…