打开url时,我正在尝试加密游戏中的查询字符串。它不一定很复杂,事实上,由于我使用的是游戏引擎,所以它需要尽可能简单。如果我的水平太低,那就太麻烦了。
我已经创建了查询字符串,我只需要取其中的每个字符,从字符中减去15就可以对其进行轻度加密。我只想做一个简单的加密,让大多数用户望而却步。
我希望我能给出一个代码示例,但我对C没有太多经验,甚至不知道从哪里开始游戏引擎的api通常让一切对我来说都很简单。
这些答案都不构成任何形式的合理加密。
您实际想要做的是使用某种形式的身份验证加密和某种形式的安全密钥派生算法。我个人推荐的是利钠。它提供了非常好的默认值,并且提供了一个相对很难出错的API。
有几种不同的方法可以做到这一点:
- 使用随机密钥的密钥加密身份验证加密
- 使用从密码短语派生的密钥进行密钥加密密钥派生
- 混合加密与密钥协议。公钥加密
所有这些可能性都集成到libsodium中,并且可以相对轻松地实现。
以下代码示例直接取自libsodium文档。
对于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 */
}
现在,键数组包含一个适合在上面的代码示例中使用的键。我们不是用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的公钥来验证签名(。如果消息的验证由于某种原因失败(有人试图篡改它(,则由非零返回代码表示。
您的"加密"不会欺骗任何人。
网上有很多知名且安全的加密算法。
例如: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
的长度以满足您的需求。
void doTerribleEncryptionMethod(char * arr, int arrSize)
{
int i;
for(i = 0; i < arrSize; i++)
{
arr[i] -= 15;
}
}
请注意函数名称。你想做的事很愚蠢,而且毫无价值。
您可以使用一个非常简单的函数:
void encrypt(char *s)
{
int i, l = strlen(s);
for(i = 0; i < l; i++)
s[i] -= 15;
}
还有一种你可能感兴趣的简单加密算法,它被称为XOR密码。
SonOfRa已经提出了正确的答案。
但是,如果您打算使用一些可怕的东西来模糊字符串,而不实际对其进行加密,那么GNU C库提供了一个已经编写好且易于可逆的memfrob(3)
。
如果你想,你可以对字节进行异或
通过迭代数组并使用^=这会解密和加密
#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;
}
您可以将base64的变体与自定义字母表一起使用,也可以仅使用混洗字母表。这不是真正的安全,但在你的情况下,这可能已经足够了。该算法被广泛使用,因此您很容易找到一个可以提供自定义字母表的实现。
额外的一点是,无论你在查询字符串中输入什么,如果你选择了适当的字母表,编码的表单都将由有效的URL字符组成。