lengshizai 2024-09-21 18:44 采纳率: 31.7%
浏览 13
已结题

C++ MFC 标准库 加密解密解惑

在学习加密解密的过程中,我脑子不够用了。
解密函数decrypt 以及加密块函数encryptBlock与解密块函数decryptBlock 是正确的,
并且已知 加密块函数encryptBlock与解密块函数decryptBlock 是完全可逆的函数;
但是运行测试代码 ,输出信息如下:
16|16|16
密钥加密数据: 12 34 56 78 9a bc de f0 23 45 67 89 ab cd ef 01
验证加密数据: 00 00 00 00 00 00 00 7d 29 4f 48 72 03 62 e8 b9
信息框提示 信息不匹配

请为我检查加密函数 encrypt 是否为decrypt 的完全逆向函数。 并给出decrypt 的逆向版本。
不要照搬AI,我会举报。


std::vector<uint8_t> 密钥加密 = {
    0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
    0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01
};//假设这个是被密钥加密过的数据,长度合适 且为8的倍数; 
//本文以16字节伪数据代表 ;并且  加密块函数encryptBlock与解密块函数decryptBlock  是完全可逆的函数
std::vector<uint8_t> CMFCPKGDlg::decrypt(const std::vector<uint8_t>& body, const std::vector<uint8_t>& key)
{
    if (body.size() % 8 != 0 || key.size()!=16)
    {
        return{};
    }

    std::vector<uint8_t> prev_block(8, 0);
    std::vector<uint8_t> prev_original_block(8, 0);

    std::vector<uint8_t> result(body.size());
    int resultIndex = 0;
    int remain_j = 0;

    for (size_t i = 0; i < body.size(); i += 8)
    {
        std::vector<uint8_t> decrypt_block(8);
        for (int k = 0; k < 8; k++)
        {
            decrypt_block[k] = prev_block[k] ^ body[i + k];
        }

        std::vector<uint8_t> block = decryptBlock(decrypt_block, key);
        int j = remain_j;

        if (i == 0)
        {
            int header_offset = block[0] & 0x07;
            j = header_offset + 3;
        }

        for (; j < 8; j++)
        {
            result[resultIndex++] = block[j] ^ prev_original_block[j];
        }

        if (j > 8)
        {
            remain_j = j % 8;
        }
        else
        {
            remain_j = 0;
        }

        prev_block = block;
        prev_original_block = std::vector<uint8_t>(body.begin() + i, body.begin() + i + 8);
    }
    
    //while (resultIndex > 0 && result[resultIndex - 1] == 0x0)
    //{
    //    --resultIndex;
    //}

    //result.resize(resultIndex);
    return result;
}
std::vector<uint8_t> CMFCPKGDlg::encrypt(const std::vector<uint8_t>& body, const std::vector<uint8_t>& key)
{
    if (body.size() % 8 != 0 || key.size() != 16)
    {
        return {};
    }
    

    std::vector<uint8_t> prev_block(8, 0);
    std::vector<uint8_t> prev_original_block(8, 0);

    std::vector<uint8_t> result(body.size());
    int resultIndex = static_cast<int>(body.size()) - 1;
    int remain_j = 0;

    for (size_t i = body.size(); i > 0; i -= 8)
    {
        size_t current_index = i - 8;

        std::vector<uint8_t> block(8);

        if (i == body.size())
        {
            block = prev_block;
        }
        else
        {
            for (int k = 0; k < 8; k++)
            {
                block[k] = body[current_index + k] ^ prev_block[k];
            }
        }

        std::vector<uint8_t> encrypt_block = encryptBlock(block, key);

        int j = remain_j;

        if (i == 8)  // 处理最后一个块
        {
            int header_offset = block[0] & 0x07;
            j = header_offset + 3;
        }

        for (int k = 7; k >= 0; k--)
        {
            if (k >= j)
            {
                result[resultIndex--] = encrypt_block[k] ^ prev_block[k];
            }
        }

        if (j > 8)
        {
            remain_j = j % 8;
        }
        else
        {
            remain_j = 0;
        }

        prev_block = encrypt_block;
        prev_original_block = std::vector<uint8_t>(body.begin() + current_index, body.begin() + current_index + 8);
    }

    return result;
}


void OnBnClickedEncript()
{
    std::vector<uint8_t> originalData = 密钥加密;

    std::string privateKey = "woreaishenghuo!!";

    std::vector<uint8_t> key(privateKey.begin(), privateKey.end());

    std::vector<uint8_t> encryptedData = decrypt(originalData, key);

    //此处经过手动检验  解密数据正确

    std::vector<uint8_t> decryptedData = encrypt(encryptedData, key);


    if (decryptedData != 密钥加密)
        {


        AfxMessageBox(_T("数据不匹配!"));

        std::cout << originalData.size() << "|" << 密钥加密.size() << "|" << decryptedData.size() << std::endl;
        std::cout << "密钥加密数据: ";
        for (const auto& byte : 密钥加密) {
            std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
        }
        std::cout << std::endl;

        std::cout << "验证加密数据: ";
        for (const auto& byte : decryptedData) {
            std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
        }
        std::cout << std::endl;
        }
}

  • 写回答

26条回答 默认 最新

  • 一轮明月照丘壑 2024-09-21 18:46
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从你给出的代码来看,encrypt 和 decrypt 函数看上去非常类似,基本上都是在加密解密的时候先执行 XOR 操作和加密解密块函数encryptBlock和decryptBlock。所以理论上来说,如果encryptBlock和decryptBlock是完全可逆的,那么encrypt和decrypt也应该是完全可逆的。然而,你遇到的问题可能是因为在处理数据的边界情况时,encrypt和decrypt的行为存在差异。在你的代码中,你在encrypt和decrypt中都对处理结果的最后一个元素进行了特殊处理。这是很常见的处理策略,用于处理块加密算法中的数据填充问题。但是在这种情况下,你可能需要考虑的是当对相同数据进行加密和解密操作时,处理结果的边界应该是一致的。因此你需要确保encrypt和decrypt在处理数据的边界时,其行为是对称的。一种可能的解决方法是简化你的代码并删除处理边界的特定部分。当然这并不是一个好的实践方法,但是只是为了帮助找到问题的可能所在。然而问题的关键在于确认encryptBlock和decryptBlock是否正确实现了它们宣称的可逆性。我建议你分别打印出加密块和解密块的结果进行比对。如果你确信encryptBlock和decryptBlock是正确的,那么问题可能出在边界处理上。对于此问题的一个解决方案可能是创建额外的测试用例专门用于测试边界条件。你需要尝试解密不同长度的数据块并确认结果是否一致。另外,你提到你的代码提示信息不匹配,这可能由于内存泄漏等问题引起的其他副作用效应有关,可以尝试在加密解密之后打印相关的数据,并进行详细对比,以便找到具体的问题所在。如果你能提供更多关于encryptBlock和decryptBlock的具体实现信息以及他们的测试案例结果,我可以更精确地帮助你解决问题。

    评论

报告相同问题?

问题事件

  • 系统已结题 9月29日
  • 赞助了问题酬金15元 9月21日
  • 创建了问题 9月21日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见