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
登录后复制
输出的结果为:
这就完成了对序列密码的解密。