C语言 简单地用 C 加密一个字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7622617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:46:39  来源:igfitidea点击:

Simply encrypt a string in C

cencryptionquery-stringcstring

提问by Isaiah

I'm trying to encrypt a query string on a game I'm making when opening a url. It doesn't have to be complicated, in fact since I'm working from a game engine it needs to be as simple as possible. It tends to fuss if I get too low level.

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

I've already created the query string, I just need to take each char of it and subtract 15 from the char to lightly encrypt it. I'm just wanting to make a simple encryption that will deter most users.

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

I wish I could give a code example but I'm not too experienced in C, and I'm not even sure where to begin.The game engine's api usually makes everything simple for me.

我希望我能给出一个代码示例,但我在 C 方面没有太多经验,我什至不知道从哪里开始。游戏引擎的 api 通常让我觉得一切都很简单。

回答by sonOfRa

None of these answers really constitute any form of reasonable encryption.

这些答案都没有真正构成任何形式的合理加密。

What you actually want to do, is use some form of authenticated encryption, and some form of secure key derivation algorithm. My personal recommendation is libsodium. It provides very good defaults, and an API that is relatively hard to get wrong.

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

There's several different ways to do this:

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

  1. Secret key encryption with a random key Authenticated Encryption
  2. Secret key encryption with a key derived from a passphrase Key Derivation
  3. Hybrid encryption with Key Agreement. Public Key Encryption
  1. 使用随机密钥进行密钥加密Authenticated Encryption
  2. 从口令派生的密钥的秘密密钥加密密钥派生
  3. 带有密钥协议的混合加密。公钥加密

All of these possibilities are integrated into libsodium and implementable with relative ease.

所有这些可能性都集成到 libsodium 中,并且可以相对轻松地实现。

The following code examples are taken directly from the libsodium documentation.

以下代码示例直接取自libsodium 文档

For 1:

对于 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: (Deriving a key from a password)

对于 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 */
}

Now, the key-array contains a key that is suitable for the use in the code sample above. Instead of randombytes_buf(key, sizeof key)for generating a random key, we generated a key derived from a user-defined password, and use that for encryption.

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

3 is the "most complicated" of the 3 types. It is what you use if you have two parties communicating. Each of the parties generates a "keypair", which contains a public and a secret key. With those keypairs, they can together agree on a "shared key" that they can use for encrypting (and signing) data for each other:

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

This code first generates both keypairs (typically, this would happen on bob's and alice's machine separately, and they would send each other their publickey, while keeping their secret key, well, secret).

此代码首先生成密钥对双方(通常,这种情况会发生bob的和Alice的机器上分开,他们会互相发送的公共密钥,同时保持自己的密钥,那么,秘密)。

Then, a random nonce is generated, and the call to crypto_box_easy(...)encrypts a message from alice to bob(using bob's public key to encrypt, and alice's secret key to make a signature).

然后,生成一个随机nonce,调用从alice 到bobcrypto_box_easy(...)的消息加密(使用bob 的公钥进行加密,使用alice 的私钥进行签名)。

Then (after potentially sending the message over the network), the call to crypto_box_open_easy(...)is used by bob to decrypt the message (using his own secret key to decrypt, and alice's public key to verify the signature). If the verification of the message failed for some reason (someone tried to tamper with it), this is indicated by the non-zero return code.

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

回答by Dennis

Your "encryption" won't fool anybody.

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

There are good implementatons of well-known and secure encryption algorithms available online.

网上有一些众所周知的安全加密算法的良好实现。

For example: Twofish

例如:双鱼

Edit:

编辑:

Example implementation of XOR:

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

Assumes that the array containing the query string is 8 or less bytes long. Increase the length of secretto meet your needs.

假设包含查询字符串的数组长度为 8 字节或更少。增加长度secret以满足您的需要。

回答by San Jacinto

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

Notice the function name. What you want to do is silly, and pretty worthless.

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

回答by BlackBear

You can do it with a very simple function:

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

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

There's also a simple encryption algorithm you may be interested in, it's called XOR cipher.

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

回答by sarnold

SonOfRa already proposed the right answer.

SonOfRa 已经提出了正确的答案

But if you're intent on using something terrible to obscurea string without actually encryptingit, the GNU C library provides a memfrob(3)that is already-written and easily reversible.

但是,如果您打算使用一些可怕的东西来掩盖字符串而不对其进行实际加密,那么 GNU C 库提供了一个memfrob(3)已经编写好的并且易于可逆的方法。

回答by Screwballer

if you want to, you can just xor the bytes
by iterating through the array and using ^= this decrypts and encrypts

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

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

回答by Roland Illig

You can use a variant of base64with a custom alphabet, or just a shuffled alphabet. It's not really secure, but in your case it is probably sufficient. The algorithm is widely used, so it will be easy for you to find an implementation where you can provide a custom alphabet.

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

The bonus point is, that whatever you put into the query string, the encoded form will consist of valid URL characters, if you choose the alphabet appropriately.

加分点是,无论您在查询字符串中输入什么,如果您适当地选择字母表,编码形式都将由有效的 URL 字符组成。