只需加密C中的字符串即可

时间:2011-10-01 20:02:12

标签: c encryption query-string cstring

我正在尝试加密打开网址时正在制作的游戏上的查询字符串。它并不复杂,实际上因为我在游戏引擎上工作所以它需要尽可能简单。如果我的等级过低,往往会大惊小怪。

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

我希望我能给出一个代码示例,但我对C没有太多经验,我甚至不确定从哪里开始。游戏引擎的api通常会让一切变得简单。

7 个答案:

答案 0 :(得分:17)

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

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

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

  1. 使用随机密钥Authenticated Encryption
  2. 进行密钥加密
  3. 密钥加密,密钥来自密码Key Derivation
  4. 使用密钥协议进行混合加密。 Public Key Encryption
  5. 所有这些可能性都被整合到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*/
    }
    

    For 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 */
    }
    

    现在,密钥数组包含一个适合在上面的代码示例中使用的密钥。我们生成了一个从用户定义的密码派生的密钥,而不是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的机器上,并且他们会相互发送他们的公共密钥,同时保持他们的密钥,好吧,秘密)。

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

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

答案 1 :(得分:9)

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

在线提供了众所周知的安全加密算法。

例如: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的长度以满足您的需求。

答案 2 :(得分:6)

void doTerribleEncryptionMethod(char * arr, int arrSize)
{
    int i;
    for(i = 0; i < arrSize; i++)
    {
      arr[i] -= 15;
    }
}

注意功能名称。你想做的事情是愚蠢的,而且毫无价值。

答案 3 :(得分:5)

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

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

还有一个您可能感兴趣的简单加密算法,它被称为XOR cipher

答案 4 :(得分:1)

SonOfRa already proposed the right answer

但是如果你打算使用一些可怕的东西隐藏一个字符串而不实际加密它,那么GNU C库提供的memfrob(3)已经是写的,很容易逆转。

答案 5 :(得分:0)

如果需要,可以对字节进行异或运算
通过遍历数组并使用^ = 解密和加密

#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;
}

答案 6 :(得分:-1)

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

奖励点是,无论您将哪些内容放入查询字符串,如果您选择合适的字母,编码表单将包含有效的网址字符。