【问题标题】:XOR String Encryption/DecryptionXOR 字符串加密/解密
【发布时间】:2010-10-20 09:36:26
【问题描述】:

我之前已经制作了使用 XOR 加密数据的程序并完全理解它,但是我如何将其实现到程序中以便对字符串文字进行加密?例如,我不想使用:

string name = "My name is Matt";

这将导致“我的名字是马特”位于可执行文件中。我猜我必须用一个单独的程序加密文字,但我真正的问题是如何将加密的字符串存储在可执行文件中(最好不在单独的文件中)?

再次,我完全了解如何解密字符串以及它是如何工作的,我只需要知道如何在编译结果中传输加密字符串。

感谢您的宝贵时间,我真的很感激。

【问题讨论】:

  • “XOR 加密”的真正意思是“使使用 XOR 转换提取信息变得有点困难”,对吗?因为所谓的“XOR 加密”算法确实不提供安全性。
  • 异或加密是 100% 可靠的一次性填充...
  • 鉴于他对 XOR 加密的“完全理解”,我很惊讶信息存储在何处或如何存储很重要。 :P 只需将其保存在程序所在目录中的 ASCII 文本文件中,然后每隔一个字母插入一个字母 Z。 :P
  • @Cameron :我想我们“相当合理”的想法会有很大不同。我不认为普通成年人可以在几个小时内用纸和笔破译的任何东西都是“合理的”。
  • @Martin:哎呀,最好把 tuxyz 和 45689 作为可能性。无论如何,在您的假设示例中,我很确定专业的密码分析员可以很容易地发现您的密文是两个英文文本的 XOR。如果密钥恰好在可用的语料库中,那么识别密钥很容易(因为你最喜欢的书无疑是我作为一个人为 GCHQ 工作),否则就更难了。但我个人不为 GCHQ 工作。如果 James 或 Andrew 这样做,我认为您的断言是不正确的 - 书中的一章不是坏钥匙,而是一把糟糕的钥匙。

标签: c++ encryption


【解决方案1】:

第一步:编写一个程序来加密你的字符串,然后将它们打印为十六进制数字:

#include <iostream>
#include <iomanip>
#include <iostream>

int main(int argc,char* argv[])
{
    std::string const  value = argv[1];
    std::string const  key   = argv[2];

    std::cout << "string " << argv[3] << " (\"";
    for(std::size_t loop = 0; loop < value.size(); ++loop)
    {
        std::cout << "\\x"
                  << std::hex
                  << std::setw(2)
                  << std::setfill('0')
                  << static_cast<unsigned int>(value[loop] ^ key[loop % key.size()]);
    }
    std::cout << "\"," << value.size() << ");\n";
}

第 2 步:为每个文字运行应用程序。它应该输出可以粘贴到应用程序中的代码。

> ./a.exe Martin York Cool
string Cool ("\x14\x0e\x00\x1f\x30\x01",6);

注意:由于字符串现在可能包含 nul 字符,因此您不能使用采用 C-String 的普通字符串构造函数。您需要使用带有 char* 和长度的构造函数。

【讨论】:

    【解决方案2】:

    假设您正在剥离符号,您应该能够摆脱执行以下操作:

    static const char *kMyNameIsMatt = "arosietnarsoitne";  // Where that mess is the XOR-obfuscated string.
    string name = kMyNameIsMatt;
    std::cout << XORUnobfuscate(name) << std::endl;
    

    如果您不剥离符号,那么您也可以使用以下方式混淆符号:

    #define kMyNameIsMatt ABC123XYZZY
    

    【讨论】:

    • 哇,就是这么简单。出于某种原因,我认为我必须粘贴的加密字符会有一些编码问题,因为它们可能超出正常的 ASCII 范围,但我所要做的就是使用#define。
    【解决方案3】:

    如果您正在执行按位异或,那么您的“字符串”可能会包含大量不可打印的字符,因此您无法通过String str = "[something]" 定义它。最好的办法是将其表示为代表每个字符的整数数组。然后要取回您的字符串,只需对各种字符进行异或运算,并将它们全部附加在一起以形成您的未加密字符串。

    【讨论】:

      【解决方案4】:

      如果您使用的是 ascii,请使用十六进制字符表示法...

      void formatString(char *buffer, char *input) {
          char *pos = buffer;
          while (*input != '\0') {
              sprintf(pos, "\\x%02x", (int)*input);
              input++;
              pos += 4;
          }
      }
      
      void main() {
          char buffer[100]; // 4 chars for every char in the input
          char *original = "ABCD";
          int size = formatString(buffer, original);
      }
      

      这应该会给您一个结果字符串,例如“\x41\x42\x43\x44”,您可以将其放入您的程序中。不幸的是,当您异或时,某些结果字节可能为空。如果您在程序中以 "\x57\x00\x68\xf7" 结尾,则该字符串将仅报告为一个字符长,因为 null 将终止它,因此您需要单独存储字符串的大小。这可以通过对加密字符串进行 Base64 编码来处理。否则,如果您只使用 ASCII 0-127,您可以在每个字符上设置第 7 位并以空值结尾。如果您的 XOR 值为 0x55、0x42、0x55、0x55,这会将“ABCD”转换为 0x14、0x00、0x16、0x11,通过设置位 7,您将得到 0x94、0x80、0x96、0x91:

      void main() {
          char encryptedString = "\x94\x80\x96\x91";
          char buffer[100];
          decryptString(buffer, encryptedString);
          printf("Original: %s\n", buffer);
      }
      

      decryptString 在哪里进行 XOR,然后通过与 0x7f 进行与运算来剥离位 7。

      尽管有很多针对 Base64 的免费代码,所以我只会在 XOR 之后对结果字节进行 Base64 编码,然后在 XOR 恢复为原始字节之前对字符串进行 Base64 解码。

      【讨论】:

        猜你喜欢
        • 2020-03-20
        • 2019-10-22
        • 1970-01-01
        • 2014-08-01
        • 1970-01-01
        • 2017-12-18
        • 2012-07-01
        • 2018-08-26
        • 1970-01-01
        相关资源
        最近更新 更多