Les autres réponses ici fonctionnent bien, mais AES est un algorithme de cryptage plus sûr et plus récent. Il s'agit d'une classe que j'ai obtenue il y a quelques années pour effectuer le cryptage AES et que j'ai modifiée au fil du temps pour la rendre plus conviviale pour les applications Web (par exemple, j'ai construit des méthodes de cryptage/décryptage qui fonctionnent avec des chaînes conviviales pour les URL). Il possède également les méthodes qui fonctionnent avec les tableaux d'octets.
REMARQUE : vous devez utiliser des valeurs différentes dans les tableaux Key (32 octets) et Vector (16 octets) ! Vous ne voudriez pas que quelqu'un découvre 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 (doivent être <= 255) dans les tableaux Key et Vector (j'ai laissé une valeur invalide dans le tableau Vector pour être sûr que vous le fassiez...). Vous pouvez utiliser https://www.random.org/bytes/ pour générer facilement un nouveau jeu :
Son utilisation est simple : il suffit d'instancier la classe et d'appeler (généralement) EncryptToString(string StringToEncrypt) et DecryptString(string StringToDecrypt) comme méthodes. Rien de plus facile (ou de plus sûr) une fois que vous avez mis en place cette classe.
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 string suitable for passing in a URL.
public string EncryptToString(string TextValue)
{
return ByteArrToString(Encrypt(TextValue));
}
/// Encrypt some text and return an encrypted byte array.
public byte[] Encrypt(string 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 string DecryptString(string EncryptedString)
{
return Decrypt(StrToByteArray(EncryptedString));
}
/// Decryption when working with byte arrays.
public string 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.GetString(decryptedBytes);
}
/// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string 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 string of numbers (three per - must pad numbers less than 100).
public byte[] StrToByteArray(string str)
{
if (str.Length == 0)
throw new Exception("Invalid string value in StrToByteArray");
byte val;
byte[] byteArr = new byte[str.Length / 3];
int i = 0;
int j = 0;
do
{
val = byte.Parse(str.Substring(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;
}
}
3 votes
Salut Mark -- pas de problème. Je me suis senti mal de devoir refuser la réponse de richdiet, car j'ai effectivement utilisé sa solution et elle a très bien fonctionné. Cependant, j'ai continué à revenir ici pour lire les autres réponses, et la tienne est vraiment meilleure. Il n'y a pas de raison de dire aux gens d'utiliser quelque chose qui, bien qu'il fonctionne, n'est pas vraiment une bonne façon de faire quelque chose quand il y a une meilleure réponse disponible.
3 votes
Épargnez-vous des heures et utilisez HttpServerUtility.UrlTokenEn/Decode pour convertir les tableaux d'octets en une chaîne compatible avec l'url.
33 votes
+1 pour ne pas essayer de rouler votre propre conception intelligente. Vous ne connaissez peut-être pas grand-chose au cryptage, mais le fait que vous le sachiez vous place à des années-lumière de la plupart des développeurs que j'ai rencontrés et qui ne connaissent pas grand-chose au cryptage mais pensent pouvoir créer leur propre solution de toute façon.
6 votes
Attention : Un grand nombre des réponses de cette question ne sont que du chiffrement non authentifié. Cela signifie que le un attaquant peut modifier les données sans que l'application s'en aperçoive. . Cela conduit également à d'autres vulnérabilités sérieuses (comme le décryptage sans clé en raison de l'oracle de remplissage). TL;DR : N'utilisez pas le code dans les réponses données si vous n'êtes pas d'accord avec cela, ou si vous ne comprenez pas ce que je viens de dire.
0 votes
Cette question comporte deux stipulations : "sécurité non critique" et "pas de dépendances externes". Pour la plupart des gens, copier et coller ces réponses va leur nuire sur le plan de la sécurité. Idéalement, vous voulez utiliser un bibliothèque open source de haut niveau pour une meilleure sécurité, avertissement : j'ai porté ce projet en c# pour qu'il existe. Si cela ne fonctionne pas, ne faites pas de concessions, authentifiez le texte chiffré, utilisez correctement l'IV, comme dans mon article sur l'authentification. Exemples modernes de chiffrement symétrique authentifié d'une chaîne de caractères C# .
37 votes
Aucune réponse à cette question ne décrit un cryptage sécurisé. Utilisez la réponse de jbtule à Cryptage et décryptage d'une chaîne de caractères à la place.
0 votes
@paxdiablo Il semble que cela concerne vraiment le C#, et non le C. Votre édition était-elle une erreur ?
0 votes
@CodesInChaos Pourquoi avez-vous fermé puis rouvert ?
2 votes
@KyleStrand Je ne me souviens pas. Mais je suppose que j'ai essayé de le fermer en tant que doublon de stackoverflow.com/questions/202011/encrypter-et-decrypter-une-chaîne de caractères au lieu de stackoverflow.com/questions/10168240/ mais n'a pas pu voter pour fermer deux fois. Cela correspond certainement au fait que j'ai fermé la seconde en tant que doublon de la première à ce moment-là.
1 votes
Il y a une méta-discussion en cours sur cette question. .