简单介绍:RC4加密算法是一种对称加密算法,加密和解密使用同一个函数
初始化分为以下几个步骤
// 步骤一、初始化赋值
for (i=0;i<256;i++){
S[i] = i;
T[I] = K[i mod keylen];
}
// 步骤二、用T产生S的初始置换
j = 0;
for (i=0; i<256; i++)
{
j = (j + S[i] + T[i]) mod 256;
swap(S[i],S[j]);
}
// 步骤三、得到密钥流K(每次计算出一个K)
i=j=0;
for(h=0; h<datalen; h++)
{
i=(i+1) mod 256;
j=(j+S[i]) mod 256;
swap(S[i],s[j]);
t=(S[i]+S[j]) mod 256;
K=S[t];
// D[h]^=K; 亦或得到密文
}
```
求解私钥的步骤:
欧拉函数:表示表示与n互质的数的个数
eg:
[WUSTCTF2020]babyrsa
c = 28767758880940662779934612526152562406674613203406706867456395986985664083182
n = 73069886771625642807435783661014062604264768481735145873508846925735521695159
e = 65537
若要求解私钥,必须要分解n,得到两个质数p,q:http://www.factordb.com/index.php
p = 189239861511125143212536989589123569301
q = 386123125371923651191219869811293586459
求解私钥d,以及明文m
from Crypto.Util.number import long_to_bytes
from Crypto.Util.number import *
q = 189239861511125143212536989589123569301
p = 386123125371923651191219869811293586459
e = 65537
c = 28767758880940662779934612526152562406674613203406706867456395986985664083182
# n = 73069886771625642807435783661014062604264768481735145873508846925735521695159
n = q * p
# print(n)
d = gmpy2.invert(e, (p - 1) * (q - 1))
print("d=", d)
m = pow(c, d, n)
此处有疑问了,明文是如何转为这么一大长串数字呢?
import Crypto
from Crypto.Util.number import bytes_to_long
import os
t = os.urandom(4) # os.urandom(len)方式产生长度为len的随机字节串
print(t)
for i in t:
print(i)
print(bytes_to_long(t)) # 调用函数计算long整型值:
计算原理:29*pow(2,24) + 30*pow(2,16) + 150*pow(2,8) + 148*pow(2,0)
大数在此处的类是mpz
,引用了GMP
库:参考传送阵
判断字符串中所有字符是否都是可打印字符。
Unicode字符集中“Other” “Separator”类别的字符为不可打印的字符(但不包括ASCII码中的空格(0x20))。可用于判断转义字符。
ASCII码中第0~32号及第127号是控制字符;第33~126号是可打印字符,其中第48~57号为0~9十个阿拉伯数字;65~90号为26个大写英文字母,97~
122号为26个小写英文字母。
ascii码在0~255字符中只有189个字符能被打印。
lst = []
for idx,val in enumerate(range(256)):
if chr(val).isprintable():
lst.append(idx)
print(len(lst))
print(set(range(256)) - set(lst))
Data Encryption Standard
就不主动写了,这篇文章讲的非常详细:
https://www.hankcs.com/security/des-algorithm-illustrated.html
K1~K16
的生成:PC-1
置换,得到56位的密钥;off = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
????即C1
为C0
向左循环移位1,D1
为D0
向左循环移位1;C2
为C1
向左循环移位1,D2
为D1
向左循环移位1;C3
为C2
向左循环移位2,D3
为D2
向左循环移位2;最后将其 Ci 与 Di 合并为 CiDi 。PC-2
置换,得到K1~K16
。和密钥的生成一样,先进行一个初始置换(换了个名字,叫IP置换)只不过密钥是将校验位去掉了,而明文的加密不需要验证。
初始置换后将其均分为左边32位
L0,右边32位
R0。
密文的加密规则如下图
需要经过f函数的加密16轮
,得到的 L16 R16, 接着再次进行一个IP逆置换,形成最终的密文。
重要的就是这16轮
的加密。
加密函数
????Ln = Rn-1
????Rn= Ln-1 十 f (Rn-1,Kn)
f函数
步骤如下(eg):
32位
,K1为48位
,所以要进行32-48
位的E盒扩展
;4
为单位,分为8组
,每组首位前添加前相邻位,末位后添加相邻位,如下图所示:48位
后,与对应的子密钥进行亦或,即 R0 十 K1,得到另一组最终48位
的数据。32位
的,所以还要对其进行S盒压缩
,最终将8组6bit
的数据被转换为8组4bit
(一共32位
)的数据。48位
数据化为8组6bit
:B1B2B3B4B5B6B7B8 ,每组含有6bit
,经过以下运算8组6bit
的数据S盒
计算eg:101010
到S1中。S1会将这六位的第一位1
和第六位0
拿出来,组成10
作为S1的行,中间四位0101
拿出来作为S1的列。我们转换成十进制,此时映射到这个S盒的位置就是(2,5)
,对应S盒的第3行
第6列
(索引都从0开始数)。32位
数据在经过P盒
置换,得到数据即为f函数
结束将最终经过f函数
的数据与 L0 亦或,得到 R1,即 L0 十 上一步结果
重复上面步骤至16轮
,在第16轮
后,将R16 与 L16 拼接为 R16L16。
R16L16 经过IP-1盒
逆置换,得到最终16进制数,即为密文。
注意:
DES
加密算法中,
PC-1盒
,64位
去掉校验位为56位
,简单表替换;PC-2盒
,取56位
密钥中的48位
,简单表替换IP盒
,将原明文数据打乱,简单表替换,数据位数不变;E盒
,将分开的32位
扩展为48位
;S盒
,将已经经过f函数变换后的48位
数据(8组6bit)变回原来的32位
(8组4bit),用于下次f函数的计算 ;P盒
,将S盒
的到的数据进行置换,简单表替换,数据位数依旧为32位
。经P盒
置换后的数据和 L0 做 十 ,得到下一步的 Ri+1 .IP-1盒
,合并后 R16L16 简单表替换,数据位数不变64bit
。