Obfuscation bidirectionnelle simple et non sécurisée pour C #

Je recherche des fonctionnalités très simples (comme le chiffrement et le déchiffrement, mais pas nécessairement la sécurité) pour certaines données. Ce n’est pas essentiel à la mission. J’ai besoin de quelque chose pour garder les gens honnêtes honnêtes, mais quelque chose d’un peu plus fort que ROT13 ou Base64 .

Je préférerais quelque chose qui est déjà inclus dans .NET Framework 2.0, donc je n’ai pas à me soucier des dépendances externes.

Je ne veux vraiment pas avoir à me soucier des clés publiques / privées, etc. Je ne connais pas grand chose au cryptage, mais j’en sais assez pour savoir que tout ce que j’ai écrit ne serait pas inutile … En fait, Je bousillerais probablement le calcul et le rendrais banal à craquer.

D’autres réponses ici fonctionnent très bien, mais AES est un algorithme de cryptage plus sécurisé et à jour. C’est une classe que j’ai obtenue il y a quelques années pour effectuer un chiffrement AES que j’ai modifié au fil du temps pour être plus convivial pour les applications Web (j’ai construit des méthodes Encrypt / Decrypt qui fonctionnent avec des chaînes compatibles avec les URL). Il a également les méthodes qui fonctionnent avec les tableaux d’octets.

REMARQUE: vous devez utiliser des valeurs différentes dans les tableaux Clé (32 octets) et Vecteur (16 octets)! Vous ne voudriez pas que quelqu’un trouve vos clés en supposant que vous avez utilisé ce code tel quel! Tout ce que vous avez à faire est de changer certains des nombres (doit être <= 255) dans les tableaux Key et Vector (j'ai laissé une valeur non valide dans le tableau Vector pour vous assurer que vous le faites ...). Vous pouvez utiliser https://www.random.org/bytes/ pour générer facilement un nouvel ensemble:

  • générer la Key
  • générer un Vector

L’utilisation est simple: instanciez simplement la classe, puis appelez (généralement) EncryptToSsortingng (ssortingng SsortingngToEncrypt) et DecryptSsortingng (ssortingng SsortingngToDecrypt) en tant que méthodes. Cela ne pourrait pas être plus facile (ou plus sûr) une fois que vous avez cette classe en place.


 using System; using System.Data; using System.Security.Cryptography; using System.IO; public class SimpleAES { // Change these keys private byte[] Key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 }); // a hardcoded IV should not be used for production AES-CBC code // IVs should be unpredictable per ciphertext private byte[] Vector = __Replace_Me__({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 }); private ICryptoTransform EncryptorTransform, DecryptorTransform; private System.Text.UTF8Encoding UTFEncoder; public SimpleAES() { //This is our encryption method RijndaelManaged rm = new RijndaelManaged(); //Create an encryptor and a decryptor using our encryption method, key, and vector. EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector); DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector); //Used to translate bytes to text and vice versa UTFEncoder = new System.Text.UTF8Encoding(); } /// -------------- Two Utility Methods (not used but may be useful) ----------- /// Generates an encryption key. static public byte[] GenerateEncryptionKey() { //Generate a Key. RijndaelManaged rm = new RijndaelManaged(); rm.GenerateKey(); return rm.Key; } /// Generates a unique encryption vector static public byte[] GenerateEncryptionVector() { //Generate a Vector RijndaelManaged rm = new RijndaelManaged(); rm.GenerateIV(); return rm.IV; } /// ----------- The commonly used methods ------------------------------ /// Encrypt some text and return a ssortingng suitable for passing in a URL. public ssortingng EncryptToSsortingng(ssortingng TextValue) { return ByteArrToSsortingng(Encrypt(TextValue)); } /// Encrypt some text and return an encrypted byte array. public byte[] Encrypt(ssortingng TextValue) { //Translates our text value into a byte array. Byte[] bytes = UTFEncoder.GetBytes(TextValue); //Used to stream the data in and out of the CryptoStream. MemoryStream memoryStream = new MemoryStream(); /* * We will have to write the unencrypted bytes to the stream, * then read the encrypted result back from the stream. */ #region Write the decrypted value to the encryption stream CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write); cs.Write(bytes, 0, bytes.Length); cs.FlushFinalBlock(); #endregion #region Read encrypted value back out of the stream memoryStream.Position = 0; byte[] encrypted = new byte[memoryStream.Length]; memoryStream.Read(encrypted, 0, encrypted.Length); #endregion //Clean up. cs.Close(); memoryStream.Close(); return encrypted; } /// The other side: Decryption methods public ssortingng DecryptSsortingng(ssortingng EncryptedSsortingng) { return Decrypt(StrToByteArray(EncryptedSsortingng)); } /// Decryption when working with byte arrays. public ssortingng Decrypt(byte[] EncryptedValue) { #region Write the encrypted value to the decryption stream MemoryStream encryptedStream = new MemoryStream(); CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write); decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length); decryptStream.FlushFinalBlock(); #endregion #region Read the decrypted value from the stream. encryptedStream.Position = 0; Byte[] decryptedBytes = new Byte[encryptedStream.Length]; encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length); encryptedStream.Close(); #endregion return UTFEncoder.GetSsortingng(decryptedBytes); } /// Convert a ssortingng to a byte array. NOTE: Normally we'd create a Byte Array from a ssortingng using an ASCII encoding (like so). // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); // return encoding.GetBytes(str); // However, this results in character values that cannot be passed in a URL. So, instead, I just // lay out all of the byte values in a long ssortingng of numbers (three per - must pad numbers less than 100). public byte[] StrToByteArray(ssortingng str) { if (str.Length == 0) throw new Exception("Invalid ssortingng value in StrToByteArray"); byte val; byte[] byteArr = new byte[str.Length / 3]; int i = 0; int j = 0; do { val = byte.Parse(str.Subssortingng(i, 3)); byteArr[j++] = val; i += 3; } while (i < str.Length); return byteArr; } // Same comment as above. Normally the conversion would use an ASCII encoding in the other direction: // System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); // return enc.GetString(byteArr); public string ByteArrToString(byte[] byteArr) { byte val; string tempStr = ""; for (int i = 0; i <= byteArr.GetUpperBound(0); i++) { val = byteArr[i]; if (val < (byte)10) tempStr += "00" + val.ToString(); else if (val < (byte)100) tempStr += "0" + val.ToString(); else tempStr += val.ToString(); } return tempStr; } } 

J’ai nettoyé SimpleAES (ci-dessus) pour mon usage. Correction des méthodes de chiffrement / déchiffrement compliquées; des méthodes séparées pour le codage des tampons d’octets, des chaînes et des chaînes compatibles avec les URL; utilisé des bibliothèques existantes pour le codage d’URL.

Le code est petit, plus simple, plus rapide et le résultat est plus concis. Par exemple, johnsmith@gmail.com produit:

 SimpleAES: "096114178117140150104121138042115022037019164188092040214235183167012211175176167001017163166152" SimplerAES: "YHKydYyWaHmKKnMWJROkvFwo1uu3pwzTr7CnARGjppg%3d" 

Code:

 public class SimplerAES { private static byte[] key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 }); // a hardcoded IV should not be used for production AES-CBC code // IVs should be unpredictable per ciphertext private static byte[] vector = __Replace_Me_({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 }); private ICryptoTransform encryptor, decryptor; private UTF8Encoding encoder; public SimplerAES() { RijndaelManaged rm = new RijndaelManaged(); encryptor = rm.CreateEncryptor(key, vector); decryptor = rm.CreateDecryptor(key, vector); encoder = new UTF8Encoding(); } public ssortingng Encrypt(ssortingng unencrypted) { return Convert.ToBase64Ssortingng(Encrypt(encoder.GetBytes(unencrypted))); } public ssortingng Decrypt(ssortingng encrypted) { return encoder.GetSsortingng(Decrypt(Convert.FromBase64Ssortingng(encrypted))); } public byte[] Encrypt(byte[] buffer) { return Transform(buffer, encryptor); } public byte[] Decrypt(byte[] buffer) { return Transform(buffer, decryptor); } protected byte[] Transform(byte[] buffer, ICryptoTransform transform) { MemoryStream stream = new MemoryStream(); using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write)) { cs.Write(buffer, 0, buffer.Length); } return stream.ToArray(); } } 

Oui, ajoutez l’assembly System.Security , importez l’espace de noms System.Security.Cryptography . Voici un exemple simple de chiffrement par algorithme symésortingque (DES):

 DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.GenerateKey(); byte[] key = des.Key; // save this! ICryptoTransform encryptor = des.CreateEncryptor(); // encrypt byte[] enc = encryptor.TransformFinalBlock(new byte[] { 1, 2, 3, 4 }, 0, 4); ICryptoTransform decryptor = des.CreateDecryptor(); // decrypt byte[] originalAgain = decryptor.TransformFinalBlock(enc, 0, enc.Length); Debug.Assert(originalAgain[0] == 1); 

Je pensais juste append que j’ai amélioré SimplerAES de Mud en ajoutant une IV aléatoire qui est passée dans la chaîne cryptée. Cela améliore le cryptage car le cryptage de la même chaîne se traduira par une sortie différente à chaque fois.

 public class SsortingngEncryption { private readonly Random random; private readonly byte[] key; private readonly RijndaelManaged rm; private readonly UTF8Encoding encoder; public SsortingngEncryption() { this.random = new Random(); this.rm = new RijndaelManaged(); this.encoder = new UTF8Encoding(); this.key = Convert.FromBase64Ssortingng("Your+Secret+Static+Encryption+Key+Goes+Here="); } public ssortingng Encrypt(ssortingng unencrypted) { var vector = new byte[16]; this.random.NextBytes(vector); var cryptogram = vector.Concat(this.Encrypt(this.encoder.GetBytes(unencrypted), vector)); return Convert.ToBase64Ssortingng(cryptogram.ToArray()); } public ssortingng Decrypt(ssortingng encrypted) { var cryptogram = Convert.FromBase64Ssortingng(encrypted); if (cryptogram.Length < 17) { throw new ArgumentException("Not a valid encrypted string", "encrypted"); } var vector = cryptogram.Take(16).ToArray(); var buffer = cryptogram.Skip(16).ToArray(); return this.encoder.GetString(this.Decrypt(buffer, vector)); } private byte[] Encrypt(byte[] buffer, byte[] vector) { var encryptor = this.rm.CreateEncryptor(this.key, vector); return this.Transform(buffer, encryptor); } private byte[] Decrypt(byte[] buffer, byte[] vector) { var decryptor = this.rm.CreateDecryptor(this.key, vector); return this.Transform(buffer, decryptor); } private byte[] Transform(byte[] buffer, ICryptoTransform transform) { var stream = new MemoryStream(); using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write)) { cs.Write(buffer, 0, buffer.Length); } return stream.ToArray(); } } 

Et test d'unité de bonus

 [Test] public void EncryptDecrypt() { // Arrange var subject = new SsortingngEncryption(); var originalSsortingng = "Testing123!£$"; // Act var encryptedSsortingng1 = subject.Encrypt(originalSsortingng); var encryptedSsortingng2 = subject.Encrypt(originalSsortingng); var decryptedSsortingng1 = subject.Decrypt(encryptedSsortingng1); var decryptedSsortingng2 = subject.Decrypt(encryptedSsortingng2); // Assert Assert.AreEqual(originalSsortingng, decryptedSsortingng1, "Decrypted ssortingng should match original ssortingng"); Assert.AreEqual(originalSsortingng, decryptedSsortingng2, "Decrypted ssortingng should match original ssortingng"); Assert.AreNotEqual(originalSsortingng, encryptedSsortingng1, "Encrypted ssortingng should not match original ssortingng"); Assert.AreNotEqual(encryptedSsortingng1, encryptedSsortingng2, "Ssortingng should never be encrypted the same twice"); } 

Une variante de Marks (excellent) réponse

  • Ajouter “en utilisant” s
  • Rendre la classe IDisposable
  • Supprimez le code d’encodage d’URL pour simplifier l’exemple.
  • Ajouter un dispositif de test simple pour démontrer l’utilisation

J’espère que cela t’aides

 [TestFixture] public class RijndaelHelperTests { [Test] public void UseCase() { //These two values should not be hard coded in your code. byte[] key = {251, 9, 67, 117, 237, 158, 138, 150, 255, 97, 103, 128, 183, 65, 76, 161, 7, 79, 244, 225, 146, 180, 51, 123, 118, 167, 45, 10, 184, 181, 202, 190}; byte[] vector = {214, 11, 221, 108, 210, 71, 14, 15, 151, 57, 241, 174, 177, 142, 115, 137}; using (var rijndaelHelper = new RijndaelHelper(key, vector)) { var encrypt = rijndaelHelper.Encrypt("SsortingngToEncrypt"); var decrypt = rijndaelHelper.Decrypt(encrypt); Assert.AreEqual("SsortingngToEncrypt", decrypt); } } } public class RijndaelHelper : IDisposable { Rijndael rijndael; UTF8Encoding encoding; public RijndaelHelper(byte[] key, byte[] vector) { encoding = new UTF8Encoding(); rijndael = Rijndael.Create(); rijndael.Key = key; rijndael.IV = vector; } public byte[] Encrypt(ssortingng valueToEncrypt) { var bytes = encoding.GetBytes(valueToEncrypt); using (var encryptor = rijndael.CreateEncryptor()) using (var stream = new MemoryStream()) using (var crypto = new CryptoStream(stream, encryptor, CryptoStreamMode.Write)) { crypto.Write(bytes, 0, bytes.Length); crypto.FlushFinalBlock(); stream.Position = 0; var encrypted = new byte[stream.Length]; stream.Read(encrypted, 0, encrypted.Length); return encrypted; } } public ssortingng Decrypt(byte[] encryptedValue) { using (var decryptor = rijndael.CreateDecryptor()) using (var stream = new MemoryStream()) using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode.Write)) { crypto.Write(encryptedValue, 0, encryptedValue.Length); crypto.FlushFinalBlock(); stream.Position = 0; var decryptedBytes = new Byte[stream.Length]; stream.Read(decryptedBytes, 0, decryptedBytes.Length); return encoding.GetSsortingng(decryptedBytes); } } public void Dispose() { if (rijndael != null) { rijndael.Dispose(); } } } 

[EDIT] Des années plus tard, je suis revenu pour dire: ne faites pas ça! Voir Qu’est-ce qui ne va pas avec le cryptage XOR? pour plus de détails.

Un cryptage bidirectionnel très simple et facile est le cryptage XOR.

  1. Venez avec un mot de passe. Soyons-le mypass .
  2. Convertissez le mot de passe en binary (selon ASCII). Le mot de passe devient 01101101 01111001 01110000 01100001 01110011 01110011.
  3. Prenez le message que vous souhaitez encoder. Convertissez cela en binary également.
  4. Regardez la longueur du message. Si la longueur du message est de 400 octets, transformez le mot de passe en une chaîne de 400 octets en le répétant encore et encore. Il deviendrait 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 … (ou mypassmypassmypass... )
  5. XOR le message avec le mot de passe long.
  6. Envoyer le résultat
  7. Une autre fois, XOR le message crypté avec le même mot de passe ( mypassmypassmypass... ).
  8. Votre message est là!

Si vous voulez simplement un cryptage simple (c.-à-d. Qu’un pirate déterminé peut casser, mais verrouille la plupart des utilisateurs occasionnels), choisissez simplement deux phrases de même longueur, à savoir:

 deoxyribonucleicacid while (x>0) { x-- }; 

et xor vos données avec les deux (boucler les phrases secrètes si nécessaire) (a) . Par exemple:

 1111-2222-3333-4444-5555-6666-7777 deoxyribonucleicaciddeoxyribonucle while (x>0) { x-- };while (x>0) { 

Quelqu’un qui recherche votre fichier binary peut penser que la chaîne ADN est une clé, mais il est peu probable que le code C soit autre chose qu’une mémoire non initialisée enregistrée avec votre fichier binary.


(a) Gardez à l’esprit que ce chiffrement est très simple et, selon certaines définitions, peut ne pas être considéré comme du chiffrement (puisque le chiffrement a pour but d’ empêcher tout access non autorisé plutôt que de le rendre plus difficile). Bien sûr, même le cryptage le plus fort n’est pas sûr lorsque quelqu’un se tient au-dessus des porte-clés avec un tuyau en acier.

Comme indiqué dans la première phrase, il s’agit d’un moyen de rendre la tâche difficile à l’attaquant occasionnel. C’est similaire à la prévention des cambriolages chez vous – vous n’avez pas besoin de la rendre imprenable, il vous suffit de la rendre moins prévisible que la maison voisine 🙂

J’ai combiné ce que j’ai trouvé le mieux de plusieurs réponses et commentaires.

  • Vecteur d’initialisation aléatoire ajouté au texte crypté (@jbtule)
  • Utilisez TransformFinalBlock () au lieu de MemoryStream (@RenniePet)
  • Pas de clés pré-remplies pour éviter que personne ne copie et ne colle un désastre
  • Dispose correctement et utilise des modèles

Code:

 ///  /// Simple encryption/decryption using a random initialization vector /// and prepending it to the crypto text. ///  /// Based on multiple answers in http://stackoverflow.com/questions/165808/simple-two-way-encryption-for-c-sharp  public class SimpleAes : IDisposable { ///  /// Initialization vector length in bytes. ///  private const int IvBytes = 16; ///  /// Must be exactly 16, 24 or 32 bytes long. ///  private static readonly byte[] Key = Convert.FromBase64Ssortingng("FILL ME WITH 24 (2 pad chars), 32 OR 44 (1 pad char) RANDOM CHARS"); // Base64 has a blowup of four-thirds (33%) private readonly UTF8Encoding _encoder; private readonly ICryptoTransform _encryptor; private readonly RijndaelManaged _rijndael; public SimpleAes() { _rijndael = new RijndaelManaged {Key = Key}; _rijndael.GenerateIV(); _encryptor = _rijndael.CreateEncryptor(); _encoder = new UTF8Encoding(); } public ssortingng Decrypt(ssortingng encrypted) { return _encoder.GetSsortingng(Decrypt(Convert.FromBase64Ssortingng(encrypted))); } public void Dispose() { _rijndael.Dispose(); _encryptor.Dispose(); } public ssortingng Encrypt(ssortingng unencrypted) { return Convert.ToBase64Ssortingng(Encrypt(_encoder.GetBytes(unencrypted))); } private byte[] Decrypt(byte[] buffer) { // IV is prepended to cryptotext byte[] iv = buffer.Take(IvBytes).ToArray(); using (ICryptoTransform decryptor = _rijndael.CreateDecryptor(_rijndael.Key, iv)) { return decryptor.TransformFinalBlock(buffer, IvBytes, buffer.Length - IvBytes); } } private byte[] Encrypt(byte[] buffer) { // Prepend cryptotext with IV byte [] inputBuffer = _encryptor.TransformFinalBlock(buffer, 0, buffer.Length); return _rijndael.IV.Concat(inputBuffer).ToArray(); } } 

Mise à jour 2015-07-18: Correction d’une erreur dans la méthode privée Encrypt () par les commentaires de @bpsilver et @Evereq. IV a été accidentellement chiffré, est maintenant ajouté en texte clair comme prévu par Decrypt ().

Le cryptage est simple: comme d’autres l’ont fait remarquer, il existe des classes dans l’espace de noms System.Security.Cryptography qui font tout le travail pour vous. Utilisez-les plutôt que n’importe quelle solution maison.

Mais le décryptage est également facile. Le problème que vous avez n’est pas l’algorithme de chiffrement, mais la protection de l’access à la clé utilisée pour le déchiffrement.

J’utiliserais l’une des solutions suivantes:

  • DPAPI utilisant la classe ProtectedData avec la scope CurrentUser. C’est facile car vous n’avez pas à vous soucier d’une clé. Les données ne peuvent être déchiffrées que par le même utilisateur, ce qui ne permet pas de partager des données entre utilisateurs ou machines.

  • DPAPI utilisant la classe ProtectedData avec la scope LocalMachine. Bon pour, par exemple, protéger les données de configuration sur un seul serveur sécurisé. Mais quiconque peut se connecter à la machine peut le chiffrer, ce qui ne sert à rien à moins que le serveur ne soit sécurisé.

  • Tout algorithme symésortingque. J’utilise généralement la méthode statique SymmesortingcAlgorithm.Create () si je ne me soucie pas de quel algorithme est utilisé (en fait, c’est Rijndael par défaut). Dans ce cas, vous devez protéger votre clé d’une manière ou d’une autre. Par exemple, vous pouvez le masquer d’une certaine manière et le cacher dans votre code. Mais sachez que toute personne suffisamment intelligente pour décomstackr votre code pourra probablement trouver la clé.

Je voulais poster ma solution car aucune des solutions ci-dessus n’est aussi simple que la mienne. Laissez-moi savoir ce que vous pensez:

  // This will return an encrypted ssortingng based on the unencrypted parameter public static ssortingng Encrypt(this ssortingng DecryptedValue) { HttpServerUtility.UrlTokenEncode(MachineKey.Protect(Encoding.UTF8.GetBytes(DecryptedValue.Trim()))); } // This will return an unencrypted ssortingng based on the parameter public static ssortingng Decrypt(this ssortingng EncryptedValue) { Encoding.UTF8.GetSsortingng(MachineKey.Unprotect(HttpServerUtility.UrlTokenDecode(EncryptedValue))); } 

Optionnel

Cela suppose que la MachineKey du serveur utilisé pour chiffrer la valeur est la même que celle utilisée pour déchiffrer la valeur. Si vous le souhaitez, vous pouvez spécifier une MachineKey statique dans Web.config afin que votre application puisse déchiffrer / chiffrer les données quel que soit l’endroit où elle est exécutée (par exemple, serveur de développement ou de production). Vous pouvez générer une clé d’ordinateur statique en suivant ces instructions .

L’espace de noms System.Security.Cryptography contient les classes TripleDESCryptoServiceProvider et RijndaelManaged

N’oubliez pas d’append une référence à l’assembly System.Security .

J’ai changé ceci :

 public ssortingng ByteArrToSsortingng(byte[] byteArr) { byte val; ssortingng tempStr = ""; for (int i = 0; i <= byteArr.GetUpperBound(0); i++) { val = byteArr[i]; if (val < (byte)10) tempStr += "00" + val.ToString(); else if (val < (byte)100) tempStr += "0" + val.ToString(); else tempStr += val.ToString(); } return tempStr; } 

pour ça:

  public ssortingng ByteArrToSsortingng(byte[] byteArr) { ssortingng temp = ""; foreach (byte b in byteArr) temp += b.ToSsortingng().PadLeft(3, '0'); return temp; } 

Utilisation de TripleDESCryptoServiceProvider dans System.Security.Cryptography :

 public static class CryptoHelper { private const ssortingng Key = "MyHashSsortingng"; private static TripleDESCryptoServiceProvider GetCryproProvider() { var md5 = new MD5CryptoServiceProvider(); var key = md5.ComputeHash(Encoding.UTF8.GetBytes(Key)); return new TripleDESCryptoServiceProvider() { Key = key, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; } public static ssortingng Encrypt(ssortingng plainSsortingng) { var data = Encoding.UTF8.GetBytes(plainSsortingng); var sortingpleDes = GetCryproProvider(); var transform = sortingpleDes.CreateEncryptor(); var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length); return Convert.ToBase64Ssortingng(resultsByteArray); } public static ssortingng Decrypt(ssortingng encryptedSsortingng) { var data = Convert.FromBase64Ssortingng(encryptedSsortingng); var sortingpleDes = GetCryproProvider(); var transform = sortingpleDes.CreateDecryptor(); var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length); return Encoding.UTF8.GetSsortingng(resultsByteArray); } } 

Je sais que vous avez dit que vous ne vous souciez pas de la sécurité, mais si vous choisissez DES, vous pourriez tout aussi bien prendre AES , la méthode de chiffrement la plus récente.

À l’aide de la bibliothèque intégrée Cryptography .Net, cet exemple montre comment utiliser la norme AES (Advanced Encryption Standard).

 using System; using System.IO; using System.Security.Cryptography; namespace Aes_Example { class AesExample { public static void Main() { try { ssortingng original = "Here is some data to encrypt!"; // Create a new instance of the Aes // class. This generates a new key and initialization // vector (IV). using (Aes myAes = Aes.Create()) { // Encrypt the ssortingng to an array of bytes. byte[] encrypted = EncryptSsortingngToBytes_Aes(original, myAes.Key, myAes.IV); // Decrypt the bytes to a ssortingng. ssortingng roundsortingp = DecryptSsortingngFromBytes_Aes(encrypted, myAes.Key, myAes.IV); //Display the original data and the decrypted data. Console.WriteLine("Original: {0}", original); Console.WriteLine("Round Trip: {0}", roundsortingp); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); } } static byte[] EncryptSsortingngToBytes_Aes(ssortingng plainText, byte[] Key,byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("Key"); byte[] encrypted; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; } static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("Key"); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; } } } 

I’ve been using the accepted answer by Mark Brittingham and its has helped me a lot. Recently I had to send encrypted text to a different organization and that’s where some issues came up. The OP does not require these options but since this is a popular question I’m posting my modification ( Encrypt and Decrypt functions borrowed from here ):

  1. Different IV for every message – Concatenates IV bytes to the cipher bytes before obtaining the hex. Of course this is a convention that needs to be conveyed to the parties receiving the cipher text.
  2. Allows two constructors – one for default RijndaelManaged values, and one where property values can be specified (based on mutual agreement between encrypting and decrypting parties)

Here is the class (test sample at the end):

 ///  /// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx /// Uses UTF8 Encoding /// http://security.stackexchange.com/a/90850 ///  public class AnotherAES : IDisposable { private RijndaelManaged rijn; ///  /// Initialize algo with key, block size, key size, padding mode and cipher mode to be known. ///  /// ASCII key to be used for encryption or decryption /// block size to use for AES algorithm. 128, 192 or 256 bits /// key length to use for AES algorithm. 128, 192, or 256 bits ///  ///  public AnotherAES(ssortingng key, int blockSize, int keySize, PaddingMode paddingMode, CipherMode cipherMode) { rijn = new RijndaelManaged(); rijn.Key = Encoding.UTF8.GetBytes(key); rijn.BlockSize = blockSize; rijn.KeySize = keySize; rijn.Padding = paddingMode; rijn.Mode = cipherMode; } ///  /// Initialize algo just with key /// Defaults for RijndaelManaged class: /// Block Size: 256 bits (32 bytes) /// Key Size: 128 bits (16 bytes) /// Padding Mode: PKCS7 /// Cipher Mode: CBC ///  ///  public AnotherAES(ssortingng key) { rijn = new RijndaelManaged(); byte[] keyArray = Encoding.UTF8.GetBytes(key); rijn.Key = keyArray; } ///  /// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx /// Encrypt a ssortingng using RijndaelManaged encryptor. ///  /// ssortingng to be encrypted /// initialization vector to be used by crypto algorithm ///  public byte[] Encrypt(ssortingng plainText, byte[] IV) { if (rijn == null) throw new ArgumentNullException("Provider not initialized"); // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText cannot be null or empty"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV cannot be null or empty"); byte[] encrypted; // Create a decrytor to perform the stream transform. using (ICryptoTransform encryptor = rijn.CreateEncryptor(rijn.Key, IV)) { // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; }//end EncryptStringToBytes ///  /// Based on https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx ///  /// bytes to be decrypted back to plaintext /// initialization vector used to encrypt the bytes ///  public ssortingng Decrypt(byte[] cipherText, byte[] IV) { if (rijn == null) throw new ArgumentNullException("Provider not initialized"); // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText cannot be null or empty"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV cannot be null or empty"); // Declare the string used to hold the decrypted text. string plaintext = null; // Create a decrytor to perform the stream transform. using (ICryptoTransform decryptor = rijn.CreateDecryptor(rijn.Key, IV)) { // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; }//end DecryptStringFromBytes ///  /// Generates a unique encryption vector using RijndaelManaged.GenerateIV() method ///  ///  public byte[] GenerateEncryptionVector() { if (rijn == null) throw new ArgumentNullException("Provider not initialized"); //Generate a Vector rijn.GenerateIV(); return rijn.IV; }//end GenerateEncryptionVector ///  /// Based on https://stackoverflow.com/a/1344255 /// Generate a unique ssortingng given number of bytes required. /// This ssortingng can be used as IV. IV byte size should be equal to cipher-block byte size. /// Allows seeing IV in plaintext so it can be passed along a url or some message. ///  ///  ///  public static ssortingng GetUniqueSsortingng(int numBytes) { char[] chars = new char[62]; chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); byte[] data = new byte[1]; using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) { data = new byte[numBytes]; crypto.GetBytes(data); } SsortingngBuilder result = new SsortingngBuilder(numBytes); foreach (byte b in data) { result.Append(chars[b % (chars.Length)]); } return result.ToSsortingng(); }//end GetUniqueKey() ///  /// Converts a ssortingng to byte array. Useful when converting back hex ssortingng which was originally formed from bytes. ///  ///  ///  public static byte[] SsortingngToByteArray(Ssortingng hex) { int NumberChars = hex.Length; byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; }//end StringToByteArray ///  /// Dispose RijndaelManaged object initialized in the constructor ///  public void Dispose() { if (rijn != null) rijn.Dispose(); }//end Dispose() }//end class 

et..

Here is the test sample:

 class Program { ssortingng key; static void Main(ssortingng[] args) { Program p = new Program(); //get 16 byte key (just demo - typically you will have a predetermined key) p.key = AnotherAES.GetUniqueSsortingng(16); ssortingng plainText = "Hello World!"; //encrypt ssortingng hex = p.Encrypt(plainText); //decrypt ssortingng roundTrip = p.Decrypt(hex); Console.WriteLine("Round Trip: {0}", roundTrip); } ssortingng Encrypt(ssortingng plainText) { Console.WriteLine("\nSending (encrypt side)..."); Console.WriteLine("Plain Text: {0}", plainText); Console.WriteLine("Key: {0}", key); ssortingng hex = ssortingng.Empty; ssortingng ivSsortingng = AnotherAES.GetUniqueSsortingng(16); Console.WriteLine("IV: {0}", ivSsortingng); using (AnotherAES aes = new AnotherAES(key)) { //encrypting side byte[] IV = Encoding.UTF8.GetBytes(ivSsortingng); //get encrypted bytes (IV bytes prepended to cipher bytes) byte[] encryptedBytes = aes.Encrypt(plainText, IV); byte[] encryptedBytesWithIV = IV.Concat(encryptedBytes).ToArray(); //get hex ssortingng to send with url //this hex has both IV and ciphertext hex = BitConverter.ToSsortingng(encryptedBytesWithIV).Replace("-", ""); Console.WriteLine("sending hex: {0}", hex); } return hex; } ssortingng Decrypt(ssortingng hex) { Console.WriteLine("\nReceiving (decrypt side)..."); Console.WriteLine("received hex: {0}", hex); ssortingng roundTrip = ssortingng.Empty; Console.WriteLine("Key " + key); using (AnotherAES aes = new AnotherAES(key)) { //get bytes from url byte[] encryptedBytesWithIV = AnotherAES.SsortingngToByteArray(hex); byte[] IV = encryptedBytesWithIV.Take(16).ToArray(); Console.WriteLine("IV: {0}", System.Text.Encoding.Default.GetSsortingng(IV)); byte[] cipher = encryptedBytesWithIV.Skip(16).ToArray(); roundTrip = aes.Decrypt(cipher, IV); } return roundTrip; } } 

entrer la description de l'image ici

I think this is the worlds simplest one !

 ssortingng encrypted = "Text".Aggregate("", (c, a) => c + (char) (a + 2)); 

Tester

  Console.WriteLine(("Hello").Aggregate("", (c, a) => c + (char) (a + 1))); //Output is Ifmmp Console.WriteLine(("Ifmmp").Aggregate("", (c, a) => c + (char)(a - 1))); //Output is Hello