密码体制&Feistel 密码的相关知识

1、分组密码的概念

分组密码(block cipher) 的数学模型是:将明文消息编码表示后的数字(简称明文数字)序列,划分成长度为n的组(可看成长度为n的矢量),每组分别在密钥的控制下变换成等长的输出数字(简称密文数字)序列

2、密码体制

2.1、密码体制的概念

密码体制也叫密码系统,是指能完整地解决信息安全中的机密性、数据完整性、认证、身份识别、可控性及不可抵赖性等问题中的一个或几个的一个系统。对一个密码体制的正确描述,需要用数学方法清楚地描述其中的各种对象、参数、解决问题所使用的算法等

2.2、密码体制的三要素

  • 算法
  • 密钥个数
  • 加密方式( 分组加密 流式加密)

2.3、密码体制的组成

通常情况下,一个密码体制由五元组{M,C,K,E,D}五个部分

  • 明文信息空间Message:它是全体明文M的集合
  • 密文信息空间Ciphertext:它是全体密文C的集合
  • 密钥空间Key:它是全体密钥K的集合。其中每一个密钥K均由加密密钥Ke和解密密钥Kd组成,即K=(Ke,Kd)
  • 加密算法Encryption Algorithm:它是由M到C的加密变换,即 M→C; 也就是 C = ( M,Ke)
  • 解密算法Decryption Algorithm:它是由C到M的加密变换,即 C→M; 也就是 M = ( C,Kd)

2.4、密码体制的基本模式

通常的密码体制采用移位法、代替法和代数方法来进行加密和解密的变换
可以采用一种或几种方法结合的方式作为数据变换的基本模式
下面举例说明:
移位法也叫置换法。移位法把明文中的字符重新排列,字符本身不变但其位置改变了。

例如最简单的例子:把文中的字母和字符倒过来写
或将密文以固定长度来发送
5791ECNI SYLDIPAT DEVLOBES AHYTIRUC ESATAD**

3、Feistel 密码

Feistel 密码结构,在密码学研究中,Feistel 密码结构是用于分组密码中的一种对称结构

3.1、Feistel密码的核心

Feistel密码的核心是代替和置换

  • 代换:每个明文元素或元素被唯一地替换为相应的密文元素或元素组
  • 置换:明文元素的序列被替换为该序列的一个置换。也就是说,序列里没有元素被添加进去,删除或替换,但序列里的元素出现的顺序改变了

3.2、Feistel密码构造过程

令F 为轮函数;令K1,K2,……,Kn 分别为第1,2,……,n 轮的子密钥。那么基本构造过程如下:
(1)将明文信息均分为两块:(L0,R0);
(2)在每一轮中,进行如下运算(i 为当前轮数):

Li+1 = Ri;
Ri+1 = Li ⊕F (Ri,Ki)。(其中⊕为异或操作)

所得的结果即为:(Ri+1,Li+1)

3.3、Feistel密码解密过程

对于密文(Rn+1,Ln+1),我们将i 由n 向0 进行,即, i = n,n-1,……,0。然后对密文进行加密的逆向操作,如下:

1)Ri = Li+1;
(2)Li = Ri+1⊕F (Li+1,Ki)。(其中⊕为异或操作)

所得结果为(L0,R0),即原来的明文信息。

Feistel密码加解密过程
在这里插入图片描述
在这里插入图片描述

3.4、影响Feistel 结构的因素

(1)块的大小:大的块会提高加密的安全性,但是会降低加密、解密的速度。截止至2013年,比较流行的这种方案是64 bit。而128 bit 的使用也比较广泛。
(2)密钥的大小:同上。而 128 bit 正逐渐取代64 bit ,成为主流。
(3)循环次数(轮次数):每多进行一轮循环,安全性就会有所提高。现阶段比较流行的是16轮。
(4)子密钥的生成算法:生成算法越复杂,则会使得密码被破译的难度增强,即,信息会越安全。
(5)轮函数的复杂度:轮函数越复杂,则安全性越高。

3.5、Feistel结构的特点

1、加解密算法相同;
2、16轮加密(16轮解密);
3、子密钥产生越复杂,密码分析就越困难;
4、轮函数越复杂,抗攻击能力就越强;
5、密钥长度越长,安全性增强;
6、分组越长,安全性越高。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Feistel结构是一种对称加密算法的设计思想,主要思想是将明文分成左右两部分,然后交替进行加密和解密,直到达到预定的轮数。最常见的Feistel结构加密算法是DES算法。 下面是一个简单的C语言实现Feistel结构加密的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define BLOCK_SIZE 8 // 块大小(字节数) #define ROUNDS 16 // 加密轮数 #define KEY_SIZE 8 // 密钥大小(字节数) // S盒 const unsigned char S_BOX[4][16] = { {0x0E, 0x04, 0x0D, 0x01, 0x02, 0x0F, 0x0B, 0x08, 0x03, 0x0A, 0x06, 0x0C, 0x05, 0x09, 0x00, 0x07}, {0x00, 0x01, 0x07, 0x0D, 0x0F, 0x06, 0x0C, 0x0B, 0x05, 0x08, 0x04, 0x02, 0x09, 0x0E, 0x03, 0x0A}, {0x0B, 0x03, 0x05, 0x08, 0x02, 0x0F, 0x0A, 0x0D, 0x0E, 0x01, 0x07, 0x04, 0x0C, 0x09, 0x00, 0x06}, {0x07, 0x0E, 0x0C, 0x0B, 0x0D, 0x01, 0x03, 0x09, 0x00, 0x02, 0x04, 0x0A, 0x0F, 0x05, 0x08, 0x06} }; // P盒 const unsigned char P_BOX[BLOCK_SIZE] = {2, 6, 3, 1, 4, 8, 5, 7}; // 左右分块 void split(unsigned char* block, unsigned char* left, unsigned char* right) { memcpy(left, block, BLOCK_SIZE / 2); memcpy(right, block + BLOCK_SIZE / 2, BLOCK_SIZE / 2); } // 合并左右块 void merge(unsigned char* block, unsigned char* left, unsigned char* right) { memcpy(block, left, BLOCK_SIZE / 2); memcpy(block + BLOCK_SIZE / 2, right, BLOCK_SIZE / 2); } // F函数 void F(unsigned char* right, unsigned char* subkey) { unsigned char temp[BLOCK_SIZE / 2]; memcpy(temp, right, BLOCK_SIZE / 2); memset(right, 0, BLOCK_SIZE / 2); // 扩展置换 unsigned char expand[BLOCK_SIZE] = {4, 1, 2, 3, 2, 3, 4, 1}; unsigned char expanded[BLOCK_SIZE]; for (int i = 0; i < BLOCK_SIZE; i++) { expanded[i] = temp[expand[i] - 1]; } // 异或子密钥 for (int i = 0; i < BLOCK_SIZE / 2; i++) { expanded[i] ^= subkey[i]; } // S盒替换 unsigned char row = (expanded[0] << 1) + expanded[3]; unsigned char col = (expanded[1] << 3) + (expanded[2] << 2) + (expanded[4] << 1) + expanded[5]; unsigned char sbox_out = S_BOX[row][col]; for (int i = 0; i < 4; i++) { right[i] = (sbox_out >> (3 - i)) & 1; } // 置换 unsigned char permuted[BLOCK_SIZE / 2]; for (int i = 0; i < BLOCK_SIZE / 2; i++) { permuted[i] = right[P_BOX[i] - 1]; } memcpy(right, permuted, BLOCK_SIZE / 2); } // Feistel加密 void feistel_encrypt(unsigned char* block, unsigned char* key) { unsigned char left[BLOCK_SIZE / 2], right[BLOCK_SIZE / 2]; split(block, left, right); for (int i = 0; i < ROUNDS; i++) { F(right, key + i * (BLOCK_SIZE / 2)); // 异或左右块 for (int j = 0; j < BLOCK_SIZE / 2; j++) { left[j] ^= right[j]; } // 交换左右块 if (i != ROUNDS - 1) { unsigned char temp[BLOCK_SIZE / 2]; memcpy(temp, left, BLOCK_SIZE / 2); memcpy(left, right, BLOCK_SIZE / 2); memcpy(right, temp, BLOCK_SIZE / 2); } } merge(block, right, left); } int main() { unsigned char block[BLOCK_SIZE] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; unsigned char key[KEY_SIZE] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; feistel_encrypt(block, key); printf("Encrypted block: "); for (int i = 0; i < BLOCK_SIZE; i++) { printf("%02X", block[i]); } printf("\n"); return 0; } ``` 上述示例代码实现了一个简单的Feistel结构加密算法,其中使用了S盒、P盒和异或操作等基本操作。需要注意的是,该实现仅供学习参考使用,实际应用中需要考虑更多的安全性问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值