基于C语言实现的DES算法
Information Security
Assignment 1 - DES 算法实现
算法原理概述
DES 是一种典型的块加密方法:它以 64 位为分组长度,64 位一组的明文作为算法的输入,通过一系列复杂的操作,输出同样 64 位长度的密文。
总体结构
本程序的总体实现结构和 DES 算法过程完全一致:
模块分解
本程序分为以下三个模块:
binary.c
该模块中包含二进制数的操作工具函数。本程序实现 DES 加密算法的方式是将计算都囊括在 uint64_t
类型下,因为 DES 操作的数字都不超过 64 位,使用位运算执行移位、拼接要比字节数组要方便得多,速度也更快。
permutation.c
该模块中包含 DES 的置换、变换以及 S-盒变换的工具函数以及变换矩阵。
变换函数
/*** @brief 根据变换表 table,将 chunk 进行变换* @param perm 变换表,表中每个元素 e 表示对应位置 i 变换为 chunk[e]* @param chunk 将被变换的数组* @return 变换后的数组*/
uint64_t do_permutation(const permutation_t *perm, uint64_t chunk)
{uint64_t result = 0;for (int i = 0; i < perm->to_bits; ++i){result = (result << 1) | get_bit(chunk, perm->from_bits - perm->table[i] - 1);}return result;
}
S-Box 变换
/*** @brief 做 DES 的 S-Box 选择* @note S-Box 选择函数是 6 位转 4 位的变换。* 假设 Si=(abcdef)2,那么 n=(af)2 确定行号,m=(bcde)2 确定列号* @param chunk 二进制位数为 6 的 Feistel 轮函数分组* @return 二进制位数为 4 的选择后的分组*/
uint64_t do_sbox(const int box[4][16], uint64_t chunk)
{assert(0 <= chunk && chunk < (1 << 6));return box[((chunk >> 4) & 0x2) | (chunk & 0x1)][(chunk >> 1) & 0xF];
}
des.c
该模块中包含 DES 主算法,包括 Feistel
函数、T
迭代、子密钥计算、密钥生成、以及将输入流进行 DES 加解密的算法。
feistel
/*** @brief Feistel 轮函数* @param r 长度为 32 位的串 R[i - 1]* @param k 长度为 48 位的子密钥 k[i]* @return 32 位输出*/
static des_value_t feistel(des_value_t r, des_value_t k)
{// step1: 将长度为32位的串Ri-1 作E-扩展,成为48位的串E(Ri-1)des_value_t er = do_permutation(&PERM_E_EXTENSION, r);// step2: 将E(Ri-1) 和长度为48位的子密钥Ki 作48位二进制串按位异或运算,Ki 由密钥K生成des_value_t g = er ^ k;// step3: 将(2) 得到的结果平均分成8个分组,每个分组长度6位。各个// 分组分别经过8个不同的S-盒进行6-4 转换,得到8个长度分别为4位的分组// step4: 将(3) 得到的分组结果顺序连接得到长度为32位的串;des_value_t s =(do_sbox(S1_BOX, (g >> 42) & 0x3F) << 28) |(do_sbox(S2_BOX, (g >> 36) & 0x3F) << 24) |(do_sbox(S3_BOX, (g >> 30) & 0x3F) << 20) |(do_sbox(S4_BOX, (g >> 24) & 0x3F) << 16) |(do_sbox(S5_BOX, (g >> 18) & 0x3F) << 12) |(do_sbox(S6_BOX, (g >> 12) & 0x3F) << 8) |(do_sbox(S7_BOX, (g >> 6) & 0x3F) << 4) |(do_sbox(S8_BOX, (g >> 0) & 0x3F) << 0);// step5: 将(4)的结果经过P-置换,得到的结果作为轮函数f(Ri-1, Ki) 的最终32位输出return do_permutation(&PERM_P, s);
}
生成子密钥
/*** @brief 生成子密钥* @param key 64 位密钥 K* @param subkeys 生成的 16 个 48 位子密钥*/
static void calc_subkey(des_value_t key, des_value_t subkeys[16])
{static int SHIFT_BITS[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};key = do_permutation(&PERM_REMOVE_PARITY, key);key = do_permutation(&PERM_PC1, key);des_value_t c = (key >> 28) & 0xFFFFFFF, d = key & 0xFFFFFFF;for (int i = 0; i < 16; ++i){c = loop_shl(c, 28, SHIFT_BITS[i]);d = loop_shl(d, 28, SHIFT_BITS[i]);des_value_t cd = (c << 28) | d;subkeys[i] = do_permutation(&PERM_PC2, cd);}
}
T 迭代
/*** @param m 上一次 T 迭代的结果 M[i-1]=L[i-1]R[i-1]* @param k 长度为 48 位的子密钥 k[i]* @return L[i]R[i]*/
static des_value_t t_iteration(des_value_t m, des_value_t k)
{des_value_t l = (m >> 32) & 0xFFFFFFFF, r = m & 0xFFFFFFFF;return (r << 32) | (l ^ feistel(r, k));
}
DES 块加密
static des_value_t des_chunk(des_value_t m, des_value_t key, int mode)
{// C = E_k(M) = IP^(-1)·W·T_16·...·T_1·IP(M)des_value_t subkeys[16];m = do_permutation(&PERM_IP, m);calc_subkey(key, subkeys);for (int i = 0; i < 16; ++i)if (mode == DES_ENCRYPT)m = t_iteration(m, subkeys[i]);elsem = t_iteration(m, subkeys[15 - i]);m = do_permutation(&PERM_SWITCH, m);m = do_permutation(&PERM_IPINV, m);return m;
}
数据结构
由于程序的计算全部使用 uint64_t
类型参与计算,因此 DES 算法实现中并没有用到任何的数据结构。不过值得一提的是我实现的 permutation_t
,该结构体包含变换矩阵本身、变换矩阵的行数和列数。我们只需要调用 do_permutation
函数并传入变换矩阵就可以将输入的 uint64_t
整数进行变换。
C 语言源代码
本程序源代码为该压缩包的根目录,您可以在 Linux 环境下通过 make
命令编译该程序。运行生成的 bin/des
程序以查看使用方法。
编译运行结果
生成密钥
运行结果如下图所示,可以看到生成的密钥为 0x67C7687351FE4AEC
,是 64 位的。
经过计算,可以确认该密钥中的校验位都是合法的。
输入:12345678
接着运行加密任务,将 input8.txt
加密后的数据存储在了 temp.txt
中。可以看到因为 input8.txt
中的数据恰好为 64 位,因此需要额外补一个块,块内每个字节都是 0x08
。因此 temp.txt
中的数据为 2 块。
最后运行解密任务,解密后可以看到输出文件恰好为 12345678
。
输入:123456
运行加密任务后可以看到由于明文不足 64 位,补齐后加密得到的密文是 64 位的。最后解密完成后恰好为 123456
,并将补齐的两个 0x02
字节删去了。
基于C语言实现的DES算法相关推荐
- CITA v0.18 新增「基于 Rust 语言的国密算法库」新特性
近日,秘猿科技宣布开源第一个基于 Rust 语言的国密算法代码库,以及对该算法支持友好的 CITA v0.18 版本.随着社会信息化程度的不断提升,各国对于本国的密码算法及标准均上升到国家战略的高度. ...
- 基于R语言的梯度推进算法介绍
简介 通常来说,我们可以从两个方面来提高一个预测模型的准确性:完善特征工程(feature engineering)或是直接使用Boosting算法.通过大量数据科学竞赛的试炼,我们可以发现人们更钟爱 ...
- 基于c语言图像灰度拉伸算法实现,c语言实现图像灰度均衡化
通过对灰度直方图进行修正的理论.建模.算法和程序的论述说明如何实现图象的灰度直方图均衡化,达到图象增强的目的. 廛围抖蕉 c语 言实现图像灰度均衡化 郭韶斌 (北京交通大学,北京市 100044) ' ...
- 基于R语言的随机森林算法运用
有关数据挖掘中的分类算法有很多,如贝叶斯判别法.Fisher判别法.决策树.支持向量机和随机森林等,本文将对随机森林做一个介绍,并使用R语言实现该算法的应用. 随机森林算法的实质是基于决策树的分类器集 ...
- 基于Java语言的面向对象基础算法的练习
话不多说,直接上题目: 一.编写 Car 类,属性有品牌(brand)和颜色(color),show 方法打印 所有属性. 代码如下: public static void main(String[] ...
- c语言排序算法 应用与实现,基于C语言排序算法改进与应用.doc
基于C语言排序算法改进与应用 基于C语言排序算法改进与应用 摘 要:介绍了程序语言中排序的原理及应用,阐述了基于C语言的三种主要排序方法,提出了每种排序方法的改进,计算出改进后算法的时间复杂度,编写了 ...
- c语言des算法实验报告,C语言实现DES算法实验报告解析.doc
C语言实现DES算法实验报告解析 xx工程大学 实验报告 (2015-2016学年第一学期) 报告题目: DES加密算法 课程名称: 密码学B 任课教员: 专 业: 学 号: 姓 名: 二O一六年一月 ...
- c语言凸包算法,基于C语言的凸包算法实现
基于C语言的凸包算法实现 非计算机专业,代码有些的不好的地方,大佬轻喷^ _ ^ 根据要求,需要使用C语言实现凸包算法--Graham扫描法,本文将从算法理解.实现思路.遇到的问题及其解决方案三个方面 ...
- TypeScript算法专题 - blog1.基于TypeScript语言的单链表实现
TypeScript算法专题 - 基于TypeScript语言的单链表实现 李俊才 CSDN:jcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.n ...
最新文章
- 华为自动驾驶实车实路测试视频曝光!
- python程序运行不出来_python实战演练2:python可执行文件运行不成功怎么办
- Java属性loadFromXML()方法与示例
- linux安全模式改文件,嵌入式Linux的安全模式设计 - 嵌入式操作系统 - 电子发烧友网...
- mysql datetime类型按天查询_mysql 时间相关sql , 按天、月、季度、年等条件进行查询...
- 最近总是淡淡的····
- 【kafka】kafka 消费的时候 退出
- ts 变量后面加问号或者叹号_关于记录型信号量与TS指令的理解
- 负载均衡mysql的使用_使用负载均衡集群集化 MySQL - Azure Virtual Machines | Microsoft Docs...
- DeepMind深度学习高级课程,视频已全部放出
- 初步学习pg_control文件之十四
- python nltk.download报错_python 文本转语音机器学习之nltk download安装测试包
- Java基本数据类型自动转换规则
- (社会工程学攻击)安全书籍中的重要笔记摘要
- android平板电脑手写笔应用,三星旗舰Android平板电脑将配备手写笔 小米5C使用自家松果处理器...
- 374C. Inna and Dima
- python域名转化为ip的简单方法
- DPDK内存管理二:初始化
- GNU和GPL是什么
- TX2--wifi模块开启AP路由功能