Crypter simplement une chaîne en C

J’essaie de chiffrer une chaîne de requête sur un jeu que je crée en ouvrant une URL. Cela n’a pas besoin d’être compliqué, en fait, comme je travaille à partir d’un moteur de jeu, il doit être aussi simple que possible. Cela a tendance à s’agiter si mon niveau est trop bas.

J’ai déjà créé la chaîne de requête, il me suffit de prendre chaque caractère de celle-ci et de soustraire 15 de celui-ci pour le chiffrer légèrement. Je veux juste créer un cryptage simple qui dissuadera la plupart des utilisateurs.

J’aimerais pouvoir donner un exemple de code, mais je n’ai pas trop d’expérience en C et je ne sais même pas par où commencer. L’API du moteur de jeu rend tout simple pour moi.

Aucune de ces réponses ne constitue réellement une forme de cryptage raisonnable.

Ce que vous voulez réellement faire, c’est utiliser une forme de cryptage authentifié et une forme d’algorithme de dérivation de clé sécurisée. Ma recommandation personnelle est libsodium . Il fournit de très bons parameters par défaut et une API relativement difficile à se tromper.

Il y a plusieurs façons de faire cela:

  1. Cryptage par clé secrète avec une clé aléatoire Cryptage authentifié
  2. Cryptage de clé secrète avec une clé dérivée d’une phrase secrète Dérivation de clé
  3. Cryptage hybride avec accord de clé. Cryptage à clé publique

Toutes ces possibilités sont intégrées à libsodium et peuvent être mises en œuvre avec une relative facilité.

Les exemples de code suivants sont extraits directement de la documentation de libsodium .

Pour 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 sortinged to tamper with the message*/ } 

Pour 2: (dériver une clé d’un mot de passe)

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

Maintenant, le tableau de clés contient une clé qui convient à l’utilisation dans l’exemple de code ci-dessus. Au lieu de randombytes_buf(key, sizeof key) pour générer une clé aléatoire, nous avons généré une clé dérivée d’un mot de passe défini par l’utilisateur, que nous avons utilisé pour le chiffrement.

3 est le “plus compliqué” des 3 types. C’est ce que vous utilisez si vous avez deux interlocuteurs en communication. Chacune des parties génère une “paire de clés”, qui contient une clé publique et une clé secrète. Avec ces paires de clés, ils peuvent convenir d’une “clé partagée” qu’ils peuvent utiliser pour chiffrer (et signer) les données les unes pour les autres:

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

Ce code génère d’abord les deux paires de clés (généralement, cela se produirait séparément sur la machine de Bob et d’Alice, et ils échangeraient leur clé publique tout en gardant leur clé secrète).

Ensuite, un nonce aléatoire est généré et l’appel à crypto_box_easy(...) chiffre un message d’alice à bob (en utilisant la clé publique de bob pour chiffrer et la clé secrète d’alice pour établir une signature).

Ensuite (après l’envoi potentiel du message sur le réseau), l’appel de crypto_box_open_easy(...) est utilisé par Bob pour déchiffrer le message (en utilisant sa propre clé secrète pour déchiffrer et la clé publique d’alice pour vérifier la signature). Si la vérification du message échoue pour une raison quelconque (quelqu’un tente de l’altérer), cela est indiqué par le code de retour différent de zéro.

Votre “cryptage” ne trompera personne.

Il existe de bonnes implémentations d’algorithmes de cryptage bien connus et sécurisés disponibles en ligne.

Par exemple: Twofish

Modifier:

Exemple d’implémentation de 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]; } 

Suppose que le tableau contenant la chaîne de requête a une longueur de 8 octets ou moins. Augmentez la durée du secret pour répondre à vos besoins.

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

Notez le nom de la fonction. Ce que vous voulez faire est stupide et plutôt sans valeur.

Vous pouvez le faire avec une fonction très simple:

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

Il existe également un algorithme de cryptage simple qui pourrait vous intéresser, il s'appelle XOR Cipher .

SonOfRa a déjà proposé la bonne réponse .

Mais si vous souhaitez utiliser quelque chose de terrible pour masquer une chaîne sans la chiffrer , la bibliothèque GNU C fournit un memfrob(3) déjà écrit et facilement réversible.

si vous voulez, vous pouvez simplement xor les octets
en parcourant le tableau et en utilisant ^ = ceci déchiffre et chiffre

 #include  char* xorit(char* str, int key){ // any number for key except for(int i=0; i 

Vous pouvez utiliser une variante de base64 avec un alphabet personnalisé ou tout simplement un alphabet aléatoire. Ce n’est pas vraiment sécurisé, mais dans votre cas, c’est probablement suffisant. L’algorithme étant largement utilisé, il vous sera donc facile de trouver une implémentation permettant de fournir un alphabet personnalisé.

Le point positif est que, quoi que vous mettiez dans la chaîne de requête, la forme codée sera composée de caractères URL valides, si vous choisissez l’alphabet de manière appropriée.