xor(a,b)
1 |
|
exchange(a, b)
1 |
|
1 |
|
abs(a)
1 |
|
rot13(str)
1 |
|
快速幂
1 |
|
按位连续保存数值(sample:cm1-swpuctf-2018)
1 |
|
单向散列算法
MD5算法
输入:任意长度,产生一个128bit的消息摘要。
1.用到4个变量(A,B,C,D)
1 |
|
2.每次以512bit=64byte为单位处理,用到的加法常数表T[i]=4294967296*abs(sin(i))的整数部分,其中i用弧度表示,通过正弦函数和幂函数进一步消除变换中的线性。T[1]=0xd76aa478,T[2]=0xe8c7b756,…
1 |
|
3.最后一个单位不足56byte要补足56byte,等于或超过56byte,要补足120byte,以保证最后加上8byte的长度时刚好等于64byte。
1 |
|
因此,可以通过识别是否具有64个常量元素表T来确定是否MD5算法,常见的变形方法:
- 改变初始化的4个常数
- 改变填充方式
- 改变Hash变换过程MD5Transform
MD4算法
框架与MD5算法相同,MD5比MD4改进之处:
- 加入了第四轮
- 每一步都有唯一的加法常数T[i]
- 第二轮中的G函数从((X ∧ Y) ∨ (X ∧ Z) ∨ (Y ∧ Z)) 变为 ((X ∧ Z) ∨ (Y ∧ ~Z))以减小其对称性
- 每一步都加入了前一步的结果,以加快”雪崩效应”
- 改变了第2轮和第3轮中访问输入子分组的顺序,减小了形式的相似程度
- 近似优化了每轮的循环左移位移量,以期加快”雪崩效应”,各轮的循环左移都不同
MD2算法
框架与MD5算法相同,区别:
- 初始化为16byte的0字节,对应MD5的4个常数ABCD
- 使用256byte的PI_SUBST用于异或计算,前8个字节为:292E43C9A2D87C01
- 每次以16byte为单位处理,每单位运算18round
- 填充方式,以8进制字节
SHA1算法
输入:任意长度,产生一个160bit=20byte的消息摘要。其变种对应更长的消息摘要,以它们的摘要长度(以位计算)加在原名后面来命名:SHA-224、SHA-256、SHA-384,和SHA-512,并称为SHA-2。
1.初始化散列值,5个32位常量
1 |
|
2.每次以64byte为单位处理,每单元SHA1ProcessMessageBlock使用常量0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6
1 |
|
3.类似MD5,最后一个单位不足56byte要补足56byte,等于或超过56byte,要补足120byte,以保证最后加上8byte的长度时刚好等于64byte。
1 |
|
SM3国密算法
输入:任意长度,产生一个256bit=32byte的消息摘要(类似SHA-256)。
- 初始常量:{0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E},每次以64byte为单位处理
- 加密过程中用到常量Tj={ 0x79CC4519 0≤j≤15;0x7A879D8A 16≤j≤63}
- 填充方式类似MD5,最后一个单位不足56byte要补足56byte,等于或超过56byte,要补足120byte,以保证最后加上8byte的长度时刚好等于64byte
CRC32(Cyclic Redundancy Checksum,循环冗余校验码)算法
利用CRC32多项式值:0x04C11DB7或者颠倒后的0xEDB88320,生成CRC32表,再与明文异或查表即可。同理,CRC16采用多项式值:0X8005和0XA001。
1 |
|
1 |
|
Adler-32校验算法
Adler-32通过求解两个16位的数值A、B实现,并将结果连结成一个32位整数。A就是字符串中每个字节的和,而B是A在相加时每一步的阶段值之和。在Adler-32开始运行时,A初始化为1,B初始化为0,最后的校验和要模上65521=0xFFF1(2**16范围内最大的素数)
1 |
|
对称加密算法
流加密算法
RC4流加密算法
密钥长度不限,一般不超过256byte。借助由密钥初始化的长度为256byte的Sbox数组创建伪随机流,与明文逐字节异或,解密时使用相同算法。密钥和明文均以字节数组char inbuf[1024]方式读入。
1 |
|
1 |
|
Salsa20算法
将32Byte的key和8Byte的随机数nonce扩展为2^70 Byte的随机字节流。一次生成一个64字节的block,每一个block是通过将key、nonce和block number以及部分常量组成64字节的input,通过核函数,输出64字节的output。最终多个block组成长度为2^70的随机字节流,在生成过程中,每个block相互独立。识别方法:常量0x61707865,0x3320646e,0x79622d32,0x6b206574。
块加密算法
将明文按一定长度分块进行加密运算,得到密文块。主要有ECB(Electronic codebook,电码本模式)和CBC(Cipher Block Chaining,密文分组链接模式)模式,此外还有CFB(Cipher Feedback,密文反馈模式)和OFB(Output Feedback,输出反馈模式)。
CBC需要设定初始值iv,每组明文先与iv异或再进行ECB加密,并将当前密文作为下一组明文的iv。
1 |
|
IDEA(International Data Encryption Algorithm)算法
密钥key长度128bit=16byte,以16bit整形数组uint16_t key[8]方式读入,产生52=8×6+4个子密钥。明文以64bit=8byte为一组,以64bit长整型数组uint64_t plaintext[1024]方式读入,分成4个16-位子分组:X1,X2,X3和X4。这4个子分组成为算法的第一轮的输入,总共有8轮。在每一轮中,这4个子分组相互异或,相加,相乘,且与6个16-位子密钥相异或,相加,相乘。解密过程类似,使用的子密钥对应加密时所使用子密钥的逆元,并且需要逆序使用。
1 |
|
1 |
|
1 |
|
TEA(Tiny Encryption Algorithm)算法
密钥长度128bit=16byte,以32bit整形数组unsigned long key[16]方式读入,分为4个32bit子密钥K[4]。明文以64bit=8byte为一组,以32bit整形数组unsigned long data[1024]方式读入,分为2个32bit整形v[2],经过32次循环加密,借助密钥常量:0x9e3779b9(黄金分割点,delta=sqr(5)-1 * 2^31),解密算法是加密算法的逆过程。XTEA是TEA的升级版,增加了更多的密钥表,移位和异或操作。识别方法:密钥常量0x9e3779b9(-0x61C88647 )。
1 |
|
1 |
|
1 |
|
BlowFish算法
密钥长度4-56byte,以字节数组uint8_t key[60]方式读入。明文以64bit=8byte为一组,以32bit整形数组uint32_t data[1024]方式读入,分为两个32位整型L,R。识别方法:uint32_t P[16 + 2] = {0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,…和uint32_t Sbox[4*256] = {0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,…
- 密钥扩展部分借助常量数组P[18]和S-box[4][256](使用常数pi的小数部分初始化),将最长56byte的密钥转化为共(18+1024)*4=4168byte的子密钥。
- 数据加密部分共16轮,与子密钥进行相应异或运算。
- 解密过程相同,只是以相反顺序使用P[18]数组。
1 |
|
1 |
|
DES(Data Encryption Standard)算法
密钥长度56bit=7byte,附加8bit(第8,16,24,32,40,48,56,64)奇偶校验位。明文以64bit=8byte为一组,分为2个32bit整形。密钥和明文均以字节数组unsigned char key[8]方式读入。
- 初始化子密钥:将密钥按置换函数PC-1(8*7)表进行压缩置换,变成56bit,分成前28bit和后28bit的C0/D0,再将其进行16轮的循环左移以及压缩置换PC-2(8*6),最后生成16个48bit的子密钥。
- 加密过程:每8byte为一组,通过初始置换,然后与子密钥数组进行16轮迭代运算,再经过终结置换得到密文。
L_n = R_n-1;R_n = L_n-1 ^ P(S(E(R_n-1) ^ k_n-1))
,R_n的计算由四步运算构成:秘钥置换(Kn的生成,n=0~16);E-盒扩展置换;S-盒代替;P-盒置换。 - 解密过程类似,使用逆序的子密钥。
1 |
|
1 |
|
Triple DES:密钥长度为56*3bit=21byte,进行3次DES运算,加密过程:
- 以K1加密
- 以K2解密
- 以K3加密
因此,如果令K1=K3,则等效于进行了双密钥加密;如果令K1=K2=K3,则等效于进行了普通的单密钥加密(因为先K1加密,再K2=K1解密得到明文,再以K3=K1加密,等效于直接对明文进行DES加密)
AES(Advanced Encryption Standard)算法
密钥长度128bit=16byte、192bit=24byte、256bit=32byte,分别称作AES-128、AES-192、AES-256。明文以128bit=16byte为一组。密钥和明文均以字节数组unsigned char key[AES_KEYLEN]方式读入。识别方法:uint8_t sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,…
- 密钥扩展:对128bit、192bit、256bit,借助SBox分别生成4*(10+1)=44、4*(12 + 1)=52、4*(14+1)=60个32bit的子密钥。
- 加密过程:AES-128、AES-192、AES-256分别执行10、12、14次轮函数进行变换。轮函数由SubBytes(查表)、ShiftRows(第一行保持不变、第二行左移一个字节、第三行左移两个字节、第四行左移三个字节)、MixColumns(矩阵乘法)、AddRoundKey(与密钥异或)。最后一轮没有MixColumns。
- 解密过程类似,使用加密的逆算法。
1 |
|
1 |
|
例:tailbone(高校运维赛eis-2018)
Intel的aesenc指令是:
1 |
|
解密不能直接使用aesdec指令,而需要仿照AES解密算法:
1 |
|
因此当加密步骤为:
.eh_frame:00000000004007D8 66 0F 38 DC C2 aesenc xmm0, xmm2
.eh_frame:00000000004007DD 66 0F 38 DC C3 aesenc xmm0, xmm3
.eh_frame:00000000004007E2 66 0F 38 DC C4 aesenc xmm0, xmm4
.eh_frame:00000000004007E7 66 0F 38 DC C5 aesenc xmm0, xmm5
则需要逆序使用key进行解密:
1 |
|
附:Intel的aesdec指令:
1 |
|
SM4国密算法(无线局域网标准的分组数据算法)
密钥长度128bit=16byte,明文以128bit=16byte为一组。密钥和明文均以字节数组unsigned char key[16]方式读入。识别方法:char Sbox[256]={0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,…
- 初始化密钥:将key转化为4个32bit整形先于常量数组FK[4]异或,再借助Sbox生成32个32bit子密钥。
- 加密过程与DES算法相似,每一轮中将128bit转为4个32bit的整数放入unsigned long ulbuf[4]中。迭代地使用Sbox进行非线性变换,然后再通过循环移位操作进行线性变换进行32轮加密。其每轮加密用到了之前四轮加密的结果,进一步提高了加密的强度。
- 解密过程类似,使用逆序的子密钥。
1 |
|
1 |
|
1 |
|
编码算法
base32
每5byte为一组,编码成8个5bit编码的字符。因此,最后余1个byte,补6个等号;余2个byte,补4个等号;余3个byte,补3个等号;余4个byte,补1个等号。
1 |
|
base64
每6byte为一组,编码成8个6bit编码的字符,也就是每3个byte即可编码成4个字符。因此,最后余1个byte,补2个等号;余2个byte,补1个等号。
1 |
|
此外,还有base16(将每个字节按hex输出),base24,base60。