逆向加密算法

常见加密算法和编码识别 

前言 

在对数据进行变换的过程中,除了简单的字节操作之外,还会使用一些常用的编码加密算法,因此如果能够快速识别出对应的编码或者加密算法,就能更快的分析出整个完整的算法。CTF 逆向中通常出现的加密算法包括 base64、TEA、AES、RC4、MD5 等。

Base64

Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。转换的时候,将 3 字节的数据,先后放入一个 24 位的缓冲区中,先来的字节占高位。数据不足 3 字节的话,于缓冲器中剩下的比特用 0 补足。每次取出 6 比特,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出,直到全部输入数据转换完成。

通常而言 Base64 的识别特征为索引表,当我们能找到 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 这样索引表,再经过简单的分析基本就能判定是 Base64 编码。

当然,有些题目 base64 的索引表是会变的,一些变种的 base64 主要 就是修改了这个索引表。

Tea

密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行块密码,通常只需要很少的代码就可实现。其设计者是剑桥大学计算机实验室大卫 · 惠勒罗杰 · 尼达姆

	#include <stdint.h>
#include <string.h>
 
#define DELTA 0x9e3779b9
#define ROUNDS 32
 
// TEA加密算法
void tea_encrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0, i; // 设置初始变量
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; // 密钥块
 
    for (i = 0; i < ROUNDS; ++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;
}
 
// TEA解密算法
void tea_decrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum, i;
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
 
    sum = DELTA * ROUNDS;
    for (i = 0; i < ROUNDS; ++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;
}
 
int main() {
    uint32_t plaintext[2] = {0x12345678, 0x9abcdef0}; // 64位明文
    uint32_t key[4] = {0x0, 0x1, 0x2, 0x3}; // 128位密钥(实际使用时需要更强的密钥)
    uint32_t ciphertext[2];
    uint32_t decryptedtext[2];
 
    // 加密
    memcpy(ciphertext, plaintext, sizeof(plaintext));
    tea_encrypt(ciphertext, key);
 
    // 打印加密后的密文
    printf("Ciphertext: %08x %08x\n", ciphertext[0], ciphertext[1]);
 
    // 解密
    memcpy(decryptedtext, ciphertext, sizeof(ciphertext));
    tea_decrypt(decryptedtext, key);
 
    // 打印解密后的明文
    printf("Decrypted text: %08x %08x\n", decryptedtext[0], decryptedtext[1]);
 
    return 0;
}

RC4

RC4(Rivest Cipher 4)是一种流加密算法,它基于bit进行加密,密钥长度可变,且加解密使用相同的密钥,因此也属于对称加密算法。以下是一个逆向RC4加密的示例,包括RC4加密算法的初始化和加密过程,以及如何使用这些过程来解密数据。

一、RC4加密算法概述

  1. 初始化

    • 创建一个256字节的S盒(S-box),初始化为0到255的序列。
    • 创建一个256字节的T盒(T-box),用密钥填充。如果密钥长度小于256字节,则循环使用密钥直到填满T盒。
    • 通过一系列交换操作,使用T盒对S盒进行初始非线性置换。
  2. 加密

    • 对于每个待加密的字符,生成一个伪随机数作为密钥流。
    • 将该字符与密钥流进行异或操作,得到加密后的字符。
  3. 代码示例:
    	#include <stdio.h>
    #include <string.h>
     
    // 定义RC4结构体
    typedef struct _RC4INFO {
        unsigned char s_box[256]; // S盒
        unsigned char t_box[256]; // T盒
    } RC4_INFO, *PRC4_INFO;
     
    // 初始化RC4
    void rc4_init(PRC4_INFO prc4, unsigned char key[], unsigned int keylen) {
        int i = 0, j = 0;
        unsigned char tmp;
     
        // 初始化S盒和T盒
        for (i = 0; i < 256; i++) {
            prc4->s_box[i] = i;
            prc4->t_box[i] = key[i % keylen];
        }
     
        // 初始非线性置换
        for (i = 0; i < 256; i++) {
            j = (j + prc4->s_box[i] + prc4->t_box[i]) % 256;
            tmp = prc4->s_box[i];
            prc4->s_box[i] = prc4->s_box[j];
            prc4->s_box[j] = tmp;
        }
    }
     
    // RC4加密/解密函数(由于是对称加密,加密和解密过程相同)
    void rc4_crypt(unsigned char data[], unsigned int datalen, unsigned char key[], unsigned int keylen) {
        int i = 0, j = 0, t = 0;
        unsigned long k = 0;
        unsigned char tmp;
        RC4_INFO rc4;
     
        // 初始化RC4
        rc4_init(&rc4, key, keylen);
     
        // 加密/解密过程
        for (k = 0; k < datalen; k++) {
            i = (i + 1) % 256;
            j = (j + rc4.s_box[i]) % 256;
            tmp = rc4.s_box[i];
            rc4.s_box[i] = rc4.s_box[j];
            rc4.s_box[j] = tmp;
            t = (rc4.s_box[i] + rc4.s_box[j]) % 256;
            data[k] ^= rc4.s_box[t]; // 异或操作,既是加密也是解密
        }
    }
     
    int main() {
        unsigned char key[] = "your_key"; // 密钥
        unsigned int keylen = strlen((char *)key);
        unsigned char ciphertext[] = "your_ciphertext"; // 密文(此处也作为待解密的输入)
        unsigned int datalen = strlen((char *)ciphertext);
        unsigned char plaintext[256] = {0}; // 用于存储解密后的明文
     
        // 复制密文到plaintext数组,因为我们要在原地解密
        memcpy(plaintext, ciphertext, datalen);
     
        // 执行解密操作(实际上是加密/解密同用的函数)
        rc4_crypt(plaintext, datalen, key, keylen);
     
        // 输出解密后的明文
        printf("Decrypted text: %s\n", plaintext);
     
        return 0;
    }

MD5

MD5 消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个 128 位(16 字节)的散列值(hash value),用于确保信息传输完整一致。MD5 由美国密码学家罗纳德 · 李维斯特(Ronald Linn Rivest)设计,于 1992 年公开,用以取代 MD4 算法。这套算法的程序在 RFC 1321 中被加以规范。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值