Information Security

Assignment 1 - DES 算法实现

算法原理概述

DES 是一种典型的块加密方法:它以 64 位为分组长度,64 位一组的明文作为算法的输入,通过一系列复杂的操作,输出同样 64 位长度的密文。

总体结构

本程序的总体实现结构和 DES 算法过程完全一致:

#mermaid-svg-hl8IWSlAOHEy1R45 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .error-icon{fill:#552222;}#mermaid-svg-hl8IWSlAOHEy1R45 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hl8IWSlAOHEy1R45 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-hl8IWSlAOHEy1R45 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hl8IWSlAOHEy1R45 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hl8IWSlAOHEy1R45 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hl8IWSlAOHEy1R45 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hl8IWSlAOHEy1R45 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hl8IWSlAOHEy1R45 .marker.cross{stroke:#333333;}#mermaid-svg-hl8IWSlAOHEy1R45 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hl8IWSlAOHEy1R45 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .cluster-label text{fill:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .cluster-label span{color:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .label text,#mermaid-svg-hl8IWSlAOHEy1R45 span{fill:#333;color:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .node rect,#mermaid-svg-hl8IWSlAOHEy1R45 .node circle,#mermaid-svg-hl8IWSlAOHEy1R45 .node ellipse,#mermaid-svg-hl8IWSlAOHEy1R45 .node polygon,#mermaid-svg-hl8IWSlAOHEy1R45 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hl8IWSlAOHEy1R45 .node .label{text-align:center;}#mermaid-svg-hl8IWSlAOHEy1R45 .node.clickable{cursor:pointer;}#mermaid-svg-hl8IWSlAOHEy1R45 .arrowheadPath{fill:#333333;}#mermaid-svg-hl8IWSlAOHEy1R45 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hl8IWSlAOHEy1R45 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hl8IWSlAOHEy1R45 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-hl8IWSlAOHEy1R45 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-hl8IWSlAOHEy1R45 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hl8IWSlAOHEy1R45 .cluster text{fill:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 .cluster span{color:#333;}#mermaid-svg-hl8IWSlAOHEy1R45 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hl8IWSlAOHEy1R45 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

des_chunk
do_permutation:PERM_IP
calc_subkey
t_iteration
do_permutation:PERM_SWITCH
do_permutation:PERM_IPINV

模块分解

本程序分为以下三个模块:

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算法相关推荐

  1. CITA v0.18 新增「基于 Rust 语言的国密算法库」新特性

    近日,秘猿科技宣布开源第一个基于 Rust 语言的国密算法代码库,以及对该算法支持友好的 CITA v0.18 版本.随着社会信息化程度的不断提升,各国对于本国的密码算法及标准均上升到国家战略的高度. ...

  2. 基于R语言的梯度推进算法介绍

    简介 通常来说,我们可以从两个方面来提高一个预测模型的准确性:完善特征工程(feature engineering)或是直接使用Boosting算法.通过大量数据科学竞赛的试炼,我们可以发现人们更钟爱 ...

  3. 基于c语言图像灰度拉伸算法实现,c语言实现图像灰度均衡化

    通过对灰度直方图进行修正的理论.建模.算法和程序的论述说明如何实现图象的灰度直方图均衡化,达到图象增强的目的. 廛围抖蕉 c语 言实现图像灰度均衡化 郭韶斌 (北京交通大学,北京市 100044) ' ...

  4. 基于R语言的随机森林算法运用

    有关数据挖掘中的分类算法有很多,如贝叶斯判别法.Fisher判别法.决策树.支持向量机和随机森林等,本文将对随机森林做一个介绍,并使用R语言实现该算法的应用. 随机森林算法的实质是基于决策树的分类器集 ...

  5. 基于Java语言的面向对象基础算法的练习

    话不多说,直接上题目: 一.编写 Car 类,属性有品牌(brand)和颜色(color),show 方法打印 所有属性. 代码如下: public static void main(String[] ...

  6. c语言排序算法 应用与实现,基于C语言排序算法改进与应用.doc

    基于C语言排序算法改进与应用 基于C语言排序算法改进与应用 摘 要:介绍了程序语言中排序的原理及应用,阐述了基于C语言的三种主要排序方法,提出了每种排序方法的改进,计算出改进后算法的时间复杂度,编写了 ...

  7. c语言des算法实验报告,C语言实现DES算法实验报告解析.doc

    C语言实现DES算法实验报告解析 xx工程大学 实验报告 (2015-2016学年第一学期) 报告题目: DES加密算法 课程名称: 密码学B 任课教员: 专 业: 学 号: 姓 名: 二O一六年一月 ...

  8. c语言凸包算法,基于C语言的凸包算法实现

    基于C语言的凸包算法实现 非计算机专业,代码有些的不好的地方,大佬轻喷^ _ ^ 根据要求,需要使用C语言实现凸包算法--Graham扫描法,本文将从算法理解.实现思路.遇到的问题及其解决方案三个方面 ...

  9. TypeScript算法专题 - blog1.基于TypeScript语言的单链表实现

    TypeScript算法专题 - 基于TypeScript语言的单链表实现 李俊才 CSDN:jcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.n ...

最新文章

  1. 华为自动驾驶实车实路测试视频曝光!
  2. python程序运行不出来_python实战演练2:python可执行文件运行不成功怎么办
  3. Java属性loadFromXML()方法与示例
  4. linux安全模式改文件,嵌入式Linux的安全模式设计 - 嵌入式操作系统 - 电子发烧友网...
  5. mysql datetime类型按天查询_mysql 时间相关sql , 按天、月、季度、年等条件进行查询...
  6. 最近总是淡淡的····
  7. 【kafka】kafka 消费的时候 退出
  8. ts 变量后面加问号或者叹号_关于记录型信号量与TS指令的理解
  9. 负载均衡mysql的使用_使用负载均衡集群集化 MySQL - Azure Virtual Machines | Microsoft Docs...
  10. DeepMind深度学习高级课程,视频已全部放出
  11. 初步学习pg_control文件之十四
  12. python nltk.download报错_python 文本转语音机器学习之nltk download安装测试包
  13. Java基本数据类型自动转换规则
  14. (社会工程学攻击)安全书籍中的重要笔记摘要
  15. android平板电脑手写笔应用,三星旗舰Android平板电脑将配备手写笔 小米5C使用自家松果处理器...
  16. 374C. Inna and Dima
  17. python域名转化为ip的简单方法
  18. DPDK内存管理二:初始化
  19. GNU和GPL是什么
  20. TX2--wifi模块开启AP路由功能

热门文章

  1. 基于标签的实时短视频推荐系统 | 深度
  2. Linux 删除目录的方法
  3. C++11创建线程/多线程
  4. 推荐丨鲲鹏OGCA训练营开营啦!拿证返200元京东卡,快冲!
  5. 由BN、CB领投的跨链网络—Axelar,即将在Coinlist 平台IDO
  6. 一键就能去除视频水印,简单实用,重点是免费的哦!
  7. 对图片数据集进行数据增强操作
  8. app登录时用QQ或者微信授权登录,及找回密码功能
  9. RFID基础---RFID的技术特点
  10. 【JavaSE】equals方法基本使用