【问题标题】:Simply encrypt a string in C只需在 C 中加密一个字符串
【发布时间】:2011-10-01 20:02:11
【问题描述】:

我正在尝试在打开 url 时对正在制作的游戏中的查询字符串进行加密。它不必很复杂,事实上,因为我正在使用游戏引擎工作,所以它需要尽可能简单。如果我的水平太低,它往往会大惊小怪。

我已经创建了查询字符串,我只需要获取它的每个字符并从 char 中减去 15 即可对其进行轻微加密。我只是想做一个简单的加密来阻止大多数用户。

我希望我能给出一个代码示例,但我对 C 语言的经验并不多,我什至不知道从哪里开始。 游戏引擎的 api 通常对我来说一切都很简单。

【问题讨论】:

  • XOR 每个字节与一个任意值加密,做同样的解密
  • 为了可怜的灵魂,他们会访问这个问题以寻找一种简单的方法来加密字符串并尝试从答案中随机复制和粘贴一些代码,我会大声说出来。 编码不是加密。模糊性不是加密。这个问题的一些答案根本不是加密。请小心。

标签: c encryption query-string cstring


【解决方案1】:

SonOfRa already proposed the right answer.

但是,如果您打算使用可怕的东西来模糊一个字符串而不实际加密它,GNU C 库提供了一个已经编写好的memfrob(3)并且很容易可逆。

【讨论】:

    【解决方案2】:

    如果你愿意,你可以对字节进行异或操作
    通过遍历数组并使用 ^= 这会解密和加密

    #include <string.h>
    char* xorit(char* str, int key){ // any number for key except 
      for(int i=0; i<strlen(str);i++){
          str[i] ^= key; 
      }
      return str;
    }
    

    【讨论】:

      【解决方案3】:

      这些答案都不构成任何形式的合理加密。

      您真正想要做的是使用某种形式的经过身份验证的加密,以及某种形式的安全密钥派生算法。我个人的推荐是libsodium。它提供了非常好的默认值,以及一个相对不易出错的 API。

      有几种不同的方法可以做到这一点:

      1. 使用随机密钥Authenticated Encryption 进行密钥加密
      2. 使用从密码短语Key Derivation 派生的密钥进行密钥加密
      3. 使用密钥协议的混合加密。 Public Key Encryption

      所有这些可能性都集成到 libsodium 中,并且相对容易实现。

      以下代码示例直接取自libsodium documentation。

      对于 1:

      #define MESSAGE ((const unsigned char *) "test")
      #define MESSAGE_LEN 4
      #define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)
      
      unsigned char nonce[crypto_secretbox_NONCEBYTES];
      unsigned char key[crypto_secretbox_KEYBYTES];
      unsigned char ciphertext[CIPHERTEXT_LEN];
      
      /* Generate a secure random key and nonce */
      randombytes_buf(nonce, sizeof nonce);
      randombytes_buf(key, sizeof key);
      /* Encrypt the message with the given nonce and key, putting the result in ciphertext */
      crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);
      
      unsigned char decrypted[MESSAGE_LEN];
      if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) {
          /* If we get here, the Message was a forgery. This means someone (or the network) somehow tried to tamper with the message*/
      }
      

      对于 2:(从密码中导出密钥)

      #define PASSWORD "Correct Horse Battery Staple"
      #define KEY_LEN crypto_secretbox_KEYBYTES
      
      unsigned char salt[crypto_pwhash_SALTBYTES];
      unsigned char key[KEY_LEN];
      
      /* Choose a random salt */
      randombytes_buf(salt, sizeof salt);
      
      if (crypto_pwhash
          (key, sizeof key, PASSWORD, strlen(PASSWORD), salt,
           crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE,
           crypto_pwhash_ALG_DEFAULT) != 0) {
          /* out of memory */
      }
      

      现在,key-array 包含一个适合在上面的代码示例中使用的键。我们没有使用randombytes_buf(key, sizeof key) 生成随机密钥,而是从用户定义的密码中生成了一个密钥,并将其用于加密。

      3 是 3 种类型中“最复杂的”。如果您有两方通信,这就是您使用的。每一方都生成一个“密钥对”,其中包含一个公共密钥和一个秘密密钥。使用这些密钥对,他们可以共同商定一个“共享密钥”,他们可以使用该密钥对彼此加密(和签名)数据:

      #define MESSAGE (const unsigned char *) "test"
      #define MESSAGE_LEN 4
      #define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)
      
      unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
      unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
      crypto_box_keypair(alice_publickey, alice_secretkey);
      
      unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
      unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
      crypto_box_keypair(bob_publickey, bob_secretkey);
      
      unsigned char nonce[crypto_box_NONCEBYTES];
      unsigned char ciphertext[CIPHERTEXT_LEN];
      randombytes_buf(nonce, sizeof nonce);
      if (crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce,
                          bob_publickey, alice_secretkey) != 0) {
          /* error */
      }
      
      unsigned char decrypted[MESSAGE_LEN];
      if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce,
                               alice_publickey, bob_secretkey) != 0) {
          /* message for Bob pretending to be from Alice has been forged! */
      }
      

      此代码首先生成两个密钥对(通常,这将分别发生在 bob 和 alice 的机器上,他们将相互发送他们的 public 密钥,同时保持他们的密钥,嗯,秘密)。

      然后,随机生成一个随机数,并且对crypto_box_easy(...) 的调用加密了一条从 alice 到 bob 的消息(使用 bob 的公钥进行加密,并使用 alice 的密钥进行签名)。

      然后(在可能通过网络发送消息之后),对crypto_box_open_easy(...) 的调用被 bob 用于解密消息(使用他自己的密钥进行解密,并使用 alice 的公钥来验证签名)。如果由于某种原因(有人试图篡改)消息验证失败,则由非零返回码指示。

      【讨论】:

        【解决方案4】:
        void doTerribleEncryptionMethod(char * arr, int arrSize)
        {
            int i;
            for(i = 0; i < arrSize; i++)
            {
              arr[i] -= 15;
            }
        }
        

        注意函数名。你想做的事很愚蠢,而且毫无价值。

        【讨论】:

        • 这只是一个在线记分牌。一旦通过查询字符串接收到分数,它几乎立即转发离开它。查询字符串只显示不到一秒钟。我只是想阻止想要添加假分数或其他东西的普通用户。这很糟糕,但它适合我认为的工作
        • 看到字符串的秒数无关紧要。 99% 的人不会得到它并不重要。只需要 1 个用户就能搞砸你的记分牌,不是吗?
        • 做你想做的。我很乐意为您提供帮助,并且您已收到警告。继续。
        • 注意到了,以后我总是可以改进它。无论如何,这款游戏现在只是 alpha 质量,主要是我只想让记分牌代码正常工作。 XOR 方法有多强大?
        • 不太安全,但比旋转 15 倍好很多。只要确保用 不同 数字对每个字符进行异或运算,否则它会像简单旋转一样不安全。
        【解决方案5】:

        您的“加密”不会欺骗任何人。

        网上有很好的知名安全加密算法实现。

        例如:Twofish

        编辑:

        XOR 的示例实现:

        void encrypt(char *array, int array_size)
        {
            int i;
            char secret[8] = { 22, 53, 44, 71, 66, 177, 253, 122 };
            for(i = 0; i < array_size; i++)
                array[i] ^= secret[i];
        }
        

        假设包含查询字符串的数组长度不超过 8 个字节。增加secret的长度以满足您的需求。

        【讨论】:

          【解决方案6】:

          你可以用一个非常简单的函数来做到这一点:

          void encrypt(char *s)
          {
              int i, l = strlen(s);
              for(i = 0; i < l; i++)
                  s[i] -= 15;
          }
          

          还有一个你可能感兴趣的简单加密算法,它叫做XOR cipher。

          【讨论】:

            【解决方案7】:

            您可以将 base64 的变体与自定义字母表一起使用,或者仅使用打乱后的字母表。它不是很安全,但在你的情况下它可能就足够了。该算法被广泛使用,因此您很容易找到可以提供自定义字母表的实现。

            奖励点是,无论您在查询字符串中输入什么内容,如果您正确选择字母表,编码形式将由有效的 URL 字符组成。

            【讨论】:

            • 我做了很多研究,认为你是对的。我做了一些事情,但后来有些事情搞砸了网址。是否有一些简单的 c base64 函数的资源?
            • google.com/search?q=base64+implementation+c。我看到的实现很容易理解。
            • 混淆伪装成加密的问题在于它给人一种虚假的安全感。有一天,有人会依赖这种“安全”,并在其上运行一些重要的东西。
            猜你喜欢
            • 2023-04-01
            • 1970-01-01
            • 2010-09-18
            • 1970-01-01
            • 1970-01-01
            • 2012-07-25
            • 2013-05-29
            • 1970-01-01
            • 2018-04-16
            相关资源
            最近更新 更多