一道Crypto题

【题源】北京理工大学计算机学院创新创业基地2018年2017级暑假集训选拔赛

【问题背景】
CTF比赛中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。其大致流程是,参赛团队之间通过进行攻防对抗、程序分析等形式,率先从主办方给出的比赛环境中得到一串具有一定格式的字符串或其他内容,并将其提交给主办方,从而夺得分数。为了方便称呼,我们把这样的内容称之为“Flag”。

【问题描述】
Crypto是CTF比赛中常见的一种题型,其问题大多与加密有关。这一天Alice就遇到了一道简单的Crypto题目,题目给出了对字符串的一个加密算法和密文,要求你破解这个加密算法,并解密出Flag。该加密算法是这样的:首先读入明文字符串,随后使用下方代码中的unpack函数把明文字符串编码为长度为w的数字序列datas,随后使用encode函数对datas数组进行了加密。encode函数的参数n为数字序列的长度,iv是将给定的参数。

int unpack(char * str, unsigned int * datas) {
    int len = strlen(str), w = len / 4;
    if (len % 4 != 0) w++;
    for (int i = 0; i < w; i++) {
        datas[i] = 0;
        for (int j = 0; j < 4; j++) {
            datas[i] <<= 8;
            datas[i] += (i * 4 + j < len) ? str[i * 4 + j] : 0;
        }
    }
    return w;
}

unsigned int crypto(unsigned int x) {
    return x ^ (x >> 16);
}

void encode(unsigned int * datas, unsigned int iv, int n) {
    datas[0] = crypto(datas[0] ^ iv);
    for (int i = 1; i < n; i++)
        datas[i] = crypto(datas[i] ^ datas[i - 1]);
}

现在给出加密后的密文数字序列,请编写解密算法解密出明文字符串。保证加密前的明文字符串仅包含数字、大小写英文字母、下划线和左右花括号(“{”和“}”)。

【输入描述】
本题有多组测试用例,用例之间用空行隔开,处理到文件末为止。
对每组用例,第一行两个整数为n(n<=10^5)和iv(0<iv<2^32-1),iv代表数字序列的长度和加密参数;第二行为n个整数,代表密文数字序列。保证数字序列中每一个数字均在32位无符号整数范围内。保证输入文件中所有数字串长度之和不超过6^10。
【输出描述】
对每组测试用例输出一行一个字符串,为解密后的明文字符串。

【示例输入】
4 666666
1667575340 186401886 1816346995 172182320
5 1120170000
76035551 2146073409 1251569323 536091756 1837724133

【示例输出】
coachyang_inf
FLAG{b1t5s_sUmm3r}

 

【解题思路】

首先分析题目给定的三个函数。

unpack()是将字符串转化成unsign int矩阵,实际上保存的是ASCII码。

encode()和crypto()则是利用异或运算进行加密计算。

不难注意到异或运算和crypto()的可逆性,即加密和解密可通过相同的运算来实现。再注意一下矩阵每一行解密的顺序,即可完成这道题。

具体细节以后再补充。

【代码】

在题目给定三个函数的基础上编程

unsigned int * uncode(unsigned int *datas, int n, int iv) {
    unsigned int *solve = new unsigned int[n];
    for (int i = n - 1; i > 0; i--) {
        solve[i] = crypto(datas[i]);
        solve[i] ^= datas[i - 1];
    }
    solve[0] = crypto(datas[0]);
    solve[0] ^= iv;
    return solve;
}

char* pack(unsigned int *codeArr, int n) {
    char *flag = new char[4 * n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 4; j++) {
            flag[i * 4 + j] = (codeArr[i] >> (8 * (3 - j))) & 127;
        }
    }
    return flag;
}

int main() {
    int n;
    int iv;
    unsigned int *cryptograph;
    while (cin >> n) {
        cin >> iv;
        cryptograph = new unsigned int[n];
        for (int i = 0; i < n; i++) {
            cin >> cryptograph[i];
        }
        unsigned int *code = uncode(cryptograph, n, iv);
        char *flag = pack(code, n);
        cout << flag << endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/null-0/p/9277839.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js 中的 crypto 是一个内置模块,用于提供加密和解密功能。它支持各种加密算法和操作,包括哈希函数、对称加密和非对称加密。你可以使用 crypto 模块来实现数据的加密、解密、签名和验证等操作。 要使用 crypto 模块,你需要在你的代码中引入它,例如: ```javascript const crypto = require('crypto'); ``` 一些常见的 crypto 操作包括: 1. 哈希函数:crypto 模块提供了多个哈希函数,如 MD5、SHA-1、SHA-256 等。你可以使用这些函数对数据进行哈希处理,生成唯一的摘要。例如: ```javascript const hash = crypto.createHash('sha256'); hash.update('Hello, world!'); const digest = hash.digest('hex'); console.log(digest); // 输出生成的摘要 ``` 2. 对称加密:crypto 模块支持对称加密算法,如 AES、DES、3DES 等。你可以使用这些算法对数据进行加密和解密。例如: ```javascript const cipher = crypto.createCipher('aes192', 'password'); let encrypted = cipher.update('Hello, world!', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); // 输出加密后的数据 const decipher = crypto.createDecipher('aes192', 'password'); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // 输出解密后的数据 ``` 3. 非对称加密:crypto 模块还支持非对称加密算法,如 RSA。你可以使用这些算法生成公钥和私钥,进行加密和解密。例如: ```javascript const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); console.log(publicKey); // 输出生成的公钥 console.log(privateKey); // 输出生成的私钥 const encrypted = crypto.publicEncrypt(publicKey, Buffer.from('Hello, world!')); console.log(encrypted.toString('base64')); // 输出加密后的数据 const decrypted = crypto.privateDecrypt(privateKey, encrypted); console.log(decrypted.toString('utf8')); // 输出解密后的数据 ``` 这只是 crypto 模块的一小部分功能,你可以查阅 Node.js 文档以获取更详细的信息和使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值