个人常见的逆向算法总结
请看加密与解密()
TEA类算法
轮加密 块加密
特征可能是大量循环移位位运算吧
魔术常数delta = 0x9e3779b9或0x61C88647
但也有时候魔改了delta和rounds
解密算法相当好写 倒着写加密过程就好~
TEA原版
void Encrypt(long* v, long* k) {
unsigned long y = v[0], z = v[1];
unsigned long sum = 0;/* 初始化 */
unsigned long delta = 0x9e3779b9;/* 密钥调度常数 */
unsigned long n = 32;/* 轮数 */
while (n-- > 0) {/* 基本循环开始 */
sum += delta;
y += ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
z += ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]);
}
/*循环结束*/
v[0] = y;
v[1] = z;
}
void Decrypt(long* v, long* k) {
unsigned long n = 32, sum, y = v[0], z = v[1];
/*初始化*/
unsigned long delta = 0x9e3779b9; /* 密钥调度常数*/
sum = delta << 5;
/*即0xC6EF3720 */
while (n-- > 0) {
/*基本循环开始*/
z -= ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + K[3]);
y -= ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
sum -= delta;
}
/*循环结束*/
v[0] = y;
v[1] = z;
}
XTEA
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
void XTEA_encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x9E3779B9;
for (i = 0; i < num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = v0; v[1] = v1;
}
void XTEA_decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3779B9, sum = delta * num_rounds;
for (i = 0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0] = v0; v[1] = v1;
}
特征是 位运算比较大?
XXTEA
#include <stdint.h>
#include <stdio.h>
using namespace std;
#define DELTA 0x9e3779b9
#define MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)))
void xxtea(uint32_t* v, int n, uint32_t* key)
{
uint32_t y, z;
int sum;
unsigned p, rounds, e;
// encrypt
if (n > 1) {
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do {
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++) {
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
// decrypt
else if (n < -1) {
n = -n;
rounds = 6 + 52 / n;
sum = rounds * DELTA;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--) {
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}
int main()
{
uint32_t v[9] = { 0xD8F758F5, 0x526849DB, 0xE2D72563, 0x485EEFAC, 0x608F4BC6, 0x5859F76A, 0xB03565A3, 0x3E4091C1,
0xD3DB5B9A };
// uint32_t v[9] = { 1,1,1,1,1,1,1,1,1 };
// 四个32位无符号整数,即128bit的key
uint32_t k[4] = { 0xEFCDAB89, 0x10325476, 0x98BADCFE, 0xC3D2E1F0 };
//n的绝对值表示v的长度,取正表示加密,取负表示解密
int n = 9;
printf("Data is : %x %x %X %x %x %X %x %x %X\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]);
xxtea(v, n, k);
printf("Encrypted data is : %x %x %X %x %x %X %x %x %X\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]);
xxtea(v, -n, k);
printf("Decrypted data is : %x %x %X %x %x %X %x %x %X\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]);
printf("最后结果为%s", v);
return 0;
}
MD5
就不丢代码了 加密代码特别长 解密请去cmd5
特征是四个常数
v5 = 0x67452301 ;
V6 = 0xEFCDAB89 ;
v7 = 0x98BADCFE;
v8 = 0x10325476;
RC4
特征是256长度的S盒
然后和明文异或得到密文
所有根据异或特征 可以输入'a'*256
拿到密文后 密文明文异或就可以拿到密钥
base系列换表密码
拿到表之后换回来再base解密即可
丢一个base64换表密码的脚本
import base64
a="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+"
b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
c="mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI=="
r=""
for x in c:
if x !="=":
r+=b[a.index(x)]
else:
r+="="
print(base64.b64decode(r))