常见的加密算法 Base64 简介 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
规则 把3个字节(3*8bit)变成4个字节(4*6bit),然后把6Bit再添两位高位0,组成四个8bit的字节
字母表如下 需要注意的是,在CTF题目中,有些题目索引表会做出改变
特点 当反编译发现字母表时,可能存在base64编码,需要注意的是,CTF中base64的索引表可能被更换
脚本 1 2 3 4 5 6 import base64my_base64table = "" std_base64table ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" s = "" s = s.translate(str .maketrans(my_base64table,std_base64table)) print (base64.b64decode(s))
Tea 简介 在密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。其设计者是剑桥大学计算机实验室的大卫 · 惠勒与罗杰 · 尼达姆。
规则 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdint.h> void encrypt (uint32_t * v, uint32_t * k) { uint32_t v0=v[0 ], v1=v[1 ], sum=0 , i; uint32_t delta=0x9e3779b9 ; uint32_t k0=k[0 ], k1=k[1 ], k2=k[2 ], k3=k[3 ]; for (i=0 ; i < 32 ; i++) { sum += delta; v0 += ((v1<<4 ) + k0) ^ (v1 + sum) ^ ((v1>>5 ) + k1); v1 += ((v0<<4 ) + k2) ^ (v0 + sum) ^ ((v0>>5 ) + k3); } v[0 ]=v0; v[1 ]=v1; } void decrypt (uint32_t * v, uint32_t * k) { uint32_t v0=v[0 ], v1=v[1 ], sum=0xC6EF3720 , i; uint32_t delta=0x9e3779b9 ; uint32_t k0=k[0 ], k1=k[1 ], k2=k[2 ], k3=k[3 ]; for (i=0 ; i<32 ; i++) { v1 -= ((v0<<4 ) + k2) ^ (v0 + sum) ^ ((v0>>5 ) + k3); v0 -= ((v1<<4 ) + k0) ^ (v1 + sum) ^ ((v1>>5 ) + k1); sum -= delta; } v[0 ]=v0; v[1 ]=v1; }
特点 Tea算法比较简单,且可以根据需求设置不同加密轮数来增加加密强度。 最主要的识别特征为delta = 0x9e3779b9
脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class MyTea : def __init__ (self, key ): assert (type (key) == bytes ) assert (len (key) == 16 ) self.k = [0 ]*4 for i in range (4 ): self.k[i] = self.btoi(key[4 *i:4 *i+4 ]) @staticmethod def btoi (b ): return int .from_bytes(b, byteorder="little" , signed=False ) @staticmethod def itob (i ): return int .to_bytes(i, 4 , "little" ) def decrypt (self, ciphertext: bytes ): plaintext = b'' for i in range (len (ciphertext)//8 ): plaintext += self.decrypt_8_char(ciphertext[i*8 :i*8 +8 ]) return plaintext def decrypt_8_char (self, sub_str ): assert (type (sub_str) == bytes ) assert (len (sub_str) == 8 ) v0 = self.btoi(sub_str[:4 ]) v1 = self.btoi(sub_str[4 :]) delta = 0x9e3779b9 sum = delta * 32 sum &= 0xffffffff for _ in range (32 ): v1 -= ((v0 << 4 ) + self.k[2 ]) ^ (v0 + sum ) ^ ((v0 >> 5 ) + self.k[3 ]) v1 &= 0xFFFFFFFF v0 -= ((v1 << 4 ) + self.k[0 ]) ^ (v1 + sum ) ^ ((v1 >> 5 ) + self.k[1 ]) v0 &= 0xFFFFFFFF sum -= delta sum &= 0xffffffff return self.itob(v0)+self.itob(v1) if __name__ == "__main__" : cipher = [int .to_bytes(n, 1 , "little" )for n in [ ]] cipher=b'' .join(cipher) key = b'' t = MyTea(key) plain = t.decrypt(cipher) print (plain)
RC4 简介 在密码学中,RC4(来自 Rivest Cipher 4 的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。
规则 RC4生成一种称为密钥流的伪随机流,它同明文通过异或操作以达到加密的目的,伪代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数 { int i =0, j = 0; char k[256] = {0}; unsigned char tmp = 0; for (i=0;i<256;i++) { s[i] = i; k[i] = key[i%Len]; } for (i=0; i<256; i++) { j=(j+s[i]+k[i])%256; tmp = s[i]; s[i] = s[j]; //交换s[i]和s[j] s[j] = tmp; } } //密钥调度算法,用0-255初始化数组S,然后用密钥进行替换 void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密 { int i = 0, j = 0, t = 0; unsigned long k = 0; unsigned char tmp; for(k=0;k<Len;k++) { i=(i+1)%256; j=(j+s[i])%256; tmp = s[i]; s[i] = s[j]; //交换s[x]和s[y] s[j] = tmp; t=(s[i]+s[j])%256; Data[k] ^= s[t]; } //对每个S[i]根据当前的值与S中的另一元素替换,得到的密钥流与明文进行异或操作 }
特点 2个长度为256的For循环 S盒乱序时的数据交换 异或加解密
脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 from Crypto.Cipher import ARC4 from binascii import b2a_hex, a2b_hex def myRC4(data,key): rc41 = ARC4.new(key) encrypted = rc41.encrypt(data) return encrypted.encode('hex') def rc4_decrpt_hex(data,key): rc41=ARC4.new(key)S return rc41.decrypt(a2b_hex(data)) key='' data=r'' print myRC4(data,key) print rc4_decrpt_hex('e79aaf7a42d9a1',key)
MD5 简介 一种被广泛使用的密码散列函数,可以产生16字节的散列值
规则 (1)数据填充 填充消息使其长度与448模512同余,方法是附一个1在后面,然后用0填充。 (2)添加长度 附上64位消息长度,使之成为512的整数倍 (3)初始化变量(MD5Init()) 初始化A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210用来计算。 (4)数据处理(MD5Update()、MD5Final()) 主循环有四轮,每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。 以下是每次操作中用到的四个辅助函数(每轮一个)。 F( X ,Y ,Z ) = ( X & Y ) | ( (X) & Z ) G( X ,Y ,Z ) = ( X & Z ) | ( Y & (Z) ) H( X ,Y ,Z ) =X ^ Y ^ Z I( X ,Y ,Z ) =Y ^ ( X | (~Z) )
特点 四个常数 h0 = 0x67452301; h1 = 0xefcdab89; h2 = 0x98badcfe; h3 = 0x10325476; MD5变形:改变4个常数、改变填充的方法、改变hash变换的处理过程