如何正确解密DES算法(二进制加密与解密的关系图)

2023-03-04 19:56:06 密语知识 思思

DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:

DES算法加密过程

对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:

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

该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:

f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:

IP-1 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

经过置换IP-1后生成的比特串就是密文e.。

下面再讲一下变换f(Ri-1,Ki)。

它的功能是将32比特的输入再转化为32比特的输出。其过程如图所示:

对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表如下:

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 31

膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:

P: 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

经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。

下面再讲一下S盒的变换过程。任取一S盒。见图:

二进制加密

一个简单而专业的办法是,你用DES加密,加密后,这句话就成了密文。

还有一个办法,你自己随便编一个128的乱序ASCII字符对应表,其实就是在程序中加个128字节的常量数组,然后将你的那句话逐字节的查表替换就可以生成密文了。

二进制加密解密

简单的异或加密,自己不写是损失

==========

#include cstdio

using namespace std;

void binByte(char *bin, unsigned char b){

char i=7;

while(b0){

bin[i]=(b1)+'0';

b=1;

i--;

}

while(i=0){

bin[i--]='0';

}

}

int main()

{

char *src="NCTV";

char bin[9]={0};

unsigned char *p=(unsigned char*)src;

unsigned char pwd=0x59;//1011001

unsigned char code;

while(*p!='\0'){

code=*p^pwd;

binByte(bin,*p);

printf("%c %u %s 加密成 %u ",*p,*p,bin,code);

binByte(bin,code);

printf("%s 解密成",bin);

code^=pwd;

binByte(bin,code);

printf(" %c %u %s",code,code,bin);

printf("\n");

p++;

}

return 0;

}

==============

输出:

N 78 01001110 加密成 23 00010111 解密成 N 78 01001110

C 67 01000011 加密成 26 00011010 解密成 C 67 01000011

T 84 01010100 加密成 13 00001101 解密成 T 84 01010100

V 86 01010110 加密成 15 00001111 解密成 V 86 01010110

========

画图说明序列密码的主要加密方式?

一、序列密码概述

序列密码也称为流密码(Stream Cipher),它是对称密码算法的一种。序列密码具有实现简单、便于硬件实施、加解密处理速度快、没有或只有有限的错误传播等特点,因此在实际应用中,特别是专用或机密机构中保持着优势,典型的应用领域包括无线通信、外交通信。

它的加密方式是将明文和密钥进行异或运算,如:明文a,ASCLL码为97,二进制嘛为0110 0001;密钥为B,ASCLL码为66,二进制码为0100 0010,然后再按位异或:

明文 0 1 1 0 0 0 0 1

密钥 0 1 0 0 0 0 1 0

密文 0 0 1 0 0 0 1 1

 

这样得到的密文为0010 0011,对应的ascll为35,即“#”。

当我们拿到密文“#”以及密钥“B”以后,我们同样按照转换为ASCLL码,按位异或的方式,获得明文:

密文 0 0 1 0 0 0 1 1

密钥 0 1 0 0 0 0 1 0

明文 0 1 1 0 0 0 0 1

 

这样,我们获得了“0110 0001”,转换为十进制为97,对应ASCLL表,得到了字符“a”。

二、序列密码的定义

这里我们对序列密码的加密与解密有以下定义:

明文、密文和密钥序列都是由单独的位组成,即:Xi,Yi,Si ∈{0,1}

加密:Yi = (Xi + Si) mod 2

解密:Xi = (Yi + Si) mod 2

三、序列密码的特点

序列密码如果使用统一密钥多次拦截后,可以从其中的规律中推导出密钥。1941-1946年间,苏联多次使用同一密码本以便节约成本,最后被美国破译,在美国称为Venona计划。为了让序列秘密更加安全,于是产生了一次性密钥,但是序列密码最大的问题有两点:

1.密钥长度与明文长度一致,如果需要加密20M的明文,那么就需要20M的密文

2.序列密码容易被篡改。

四、简单的序列密码解密

知道了序列密码的原理,解密过程就简单了,只需要将密文与密钥按字符依次取出,转换为ascll码,按位异或,再将其组合为字符串即可获得明文。

这里,因为存在特殊符号,我们就先去askll码表中,查到了每个符号对应的askll码,如下:

"11","9","43","43","44","6","49","41","21","2","56","39","1","47","20"

这样,我们就可以通过powershell,将密文进行解密了,代码如下:

[string[]]$a_arr ="11","9","43","43","44","6","49","41","21","2","56","39","1","47","20"

[string]$miyue="EfcDAcFFgilHeNm"

[int]$cd = $miyue.Length

[char[]]$b_arr = $miyue.ToCharArray()

[string]$e_arr =""

for($i=1;$i -le $cd; $i++ )

{

[int]$c = $b_arr[$i-1]

[int]$d = $c -bxor $a_arr[$i-1]

[char]$e = $d

[string]$e_arr =$e_arr + $e

}

echo $e_arr

登录后复制

输出的结果为:

这就完成了对序列密码的解密。