Actuellement, je l'écris en texte clair oups!, c'est un programme interne, donc ce n'est pas si grave, mais j'aimerais le faire correctement. Comment dois-je procéder pour le chiffrer lors de l'écriture dans le registre et comment le déchiffrer?
OurKey.SetValue("Password", textBoxPassword.Text);
Hachez-les en utilisant quelque chose comme le fournisseur SHA256 et quand vous devez contester, hachez l'entrée de l'utilisateur et voyez si les deux hachages correspondent.
byte[] data = System.Text.Encoding.ASCII.GetBytes(inputString);
data = new System.Security.Cryptography.SHA256Managed().ComputeHash(data);
String hash = System.Text.Encoding.ASCII.GetString(data);
Laisser les mots de passe réversibles est un modèle vraiment horrible.
Edit2: Je pensais que nous ne parlions que de l'authentification de première ligne. Bien sûr, il existe des cas dans lesquels vous souhaitez chiffrer les mots de passe pour d’autres éléments devant être réversibles, mais il devrait y avoir un verrou à sens unique par-dessus tout cela (à de très rares exceptions près).
J'ai mis à jour l'algorithme de hachage mais vous souhaitez conserver la meilleure puissance possible n sel privé et ajoutez-le à votre entrée avant le hachage il . Vous feriez cela à nouveau lorsque vous comparez. Cela ajoute une couche supplémentaire, ce qui rend encore plus difficile l'inversion.
Pensez également à "saler" votre hasch (pas un concept culinaire!). Fondamentalement, cela signifie ajouter du texte aléatoire au mot de passe avant de le hacher.
Pour stocker les hachages de mots de passe:
a) Générer une valeur de sel aléatoire:
byte[] salt = new byte[32];
System.Security.Cryptography.RNGCryptoServiceProvider.Create().GetBytes(salt);
b) Ajoutez le sel au mot de passe.
// Convert the plain string pwd into bytes
byte[] plainTextBytes = System.Text UnicodeEncoding.Unicode.GetBytes(plainText);
// Append salt to pwd before hashing
byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
System.Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
System.Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);
c) Hachez le mot de passe et le sel combinés:
// Create hash for the pwd+salt
System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
byte[] hash = hashAlgo.ComputeHash(combinedBytes);
d) Ajoutez le sel au hash résultant.
// Append the salt to the hash
byte[] hashPlusSalt = new byte[hash.Length + salt.Length];
System.Buffer.BlockCopy(hash, 0, hashPlusSalt, 0, hash.Length);
System.Buffer.BlockCopy(salt, 0, hashPlusSalt, hash.Length, salt.Length);
e) Stockez le résultat dans la base de données de votre magasin utilisateur.
Cette approche signifie que vous n'avez pas besoin de stocker le sel séparément, puis de recalculer le hachage à l'aide de la valeur du sel et du mot de passe en texte brut obtenu de l'utilisateur.
Modifier : La puissance de calcul brute devenant de moins en moins chère et plus rapide, la valeur du hachage - ou du hachage en salaison - a diminué. Jeff Atwood a une excellente mise à jour 2012 trop long à répéter dans son intégralité ici qui dit:
Cela (en utilisant du sel salé) donnera l'illusion de sécurité plus que toute sécurité réelle. Étant donné que vous avez besoin du sel et du choix de l'algorithme de hachage pour générer le hachage, et pour vérifier le hachage, il est peu probable qu'un attaquant en ait un mais pas l'autre. Si vous avez été compromis au point qu’un attaquant dispose de votre base de données de mots de passe, il est raisonnable de supposer qu’ils possèdent ou peuvent obtenir votre secret, votre sel caché.
La première règle de sécurité est de toujours assumer et de planifier pour le pire. Devez-vous utiliser un sel, idéalement un sel aléatoire pour chaque utilisateur? Bien sûr, c’est certainement une bonne pratique, et à tout le moins, cela vous permet de ne pas faire l’ambiguïté de deux utilisateurs qui ont le même mot de passe. Mais ces jours-ci, les sels à eux seuls ne peuvent plus vous sauver d'une personne disposée à dépenser quelques milliers de dollars en matériel de carte vidéo, et si vous pensez qu'ils le peuvent, vous êtes en difficulté.
Tom Scott a bien compris comment il ne stockait pas les mots de passe, sur Computerphile.
https://www.youtube.com/watch?v=8ZtInClXe1Q
Si vous pouvez l'éviter, n'essayez pas de stocker les mots de passe vous-même. Utilisez une plate-forme d'authentification d'utilisateur distincte, pré-établie et digne de confiance (par exemple: = OAuth, domaine Active Directory de votre société, etc.) à la place.
Si vous devez stocker des mots de passe, ne suivez pas les instructions ici. Du moins, sans consulter également des publications plus récentes et réputées, applicables à votre langue. de choix.
Il y a certainement beaucoup de gens intelligents ici, et probablement même de bons conseils. Mais il y a de fortes chances que, au moment où vous lisez ceci, toutes les réponses ici (y compris celle-ci) soient déjà obsolètes.
Cela étant dit, voici quelques conseils généraux qui, espérons-le, resteront utiles pendant un certain temps.
Traite les mots de passe exactement tels qu'ils ont été entrés par l'utilisateur au cours du processus de création. Tout ce que vous faites avec le mot de passe avant de l'envoyer au module de cryptographie va probablement juste l'affaiblir. Effectuer l'une des opérations suivantes ne fait qu'ajouter de la complexité au processus de stockage et de vérification des mots de passe, ce qui pourrait poser d'autres problèmes (voire même introduire des vulnérabilités).
Refuser la création de mots de passe qui ne peuvent pas être stockés sans modification. Renforcer ce qui précède. S'il y a une raison pour laquelle votre mécanisme de stockage de mot de passe ne peut pas gérer correctement certains caractères, espaces, chaînes ou longueurs de mot de passe, retournez une erreur et informez l'utilisateur des limitations du système afin qu'il puisse réessayer avec un mot de passe qui y correspond. Pour une meilleure expérience utilisateur, faites une liste de ces limitations accessibles à l'utilisateur dès le départ. Ne vous inquiétez même pas, ne vous inquiétez pas, cachez la liste aux attaquants - ils la comprendront assez facilement quand même.
Le plus important ...
Allez chercher une publication réputée et très récente sur les méthodes de stockage de mots de passe correspondant à la langue de votre choix. En fait, vous devriez trouver plusieurs publications récentes provenant de plusieurs sources distinctes qui sont en accord avant de choisir une méthode.
Il est extrêmement possible que tout ce que tout le monde ici (y compris moi-même) a dit ait déjà été remplacé par de meilleures technologies ou rendu non sécurisé par de nouvelles méthodes d'attaque. Allez trouver quelque chose qui n'est probablement pas.
Voici ce que vous aimeriez faire:
OurKey.SetValue("Password", StringEncryptor.EncryptString(textBoxPassword.Text));
OurKey.GetValue("Password", StringEncryptor.DecryptString(textBoxPassword.Text));
Vous pouvez le faire avec les classes suivantes. Cette classe est une classe générique est le point de terminaison du client. Il active IOC de divers algorithmes de cryptage utilisant Ninject .
public class StringEncryptor
{
private static IKernel _kernel;
static StringEncryptor()
{
_kernel = new StandardKernel(new EncryptionModule());
}
public static string EncryptString(string plainText)
{
return _kernel.Get<IStringEncryptor>().EncryptString(plainText);
}
public static string DecryptString(string encryptedText)
{
return _kernel.Get<IStringEncryptor>().DecryptString(encryptedText);
}
}
Cette classe suivante est la classe ninject qui vous permet d’injecter différents algorithmes:
public class EncryptionModule : StandardModule
{
public override void Load()
{
Bind<IStringEncryptor>().To<TripleDESStringEncryptor>();
}
}
C'est l'interface que tout algorithme doit implémenter pour chiffrer/déchiffrer des chaînes:
public interface IStringEncryptor
{
string EncryptString(string plainText);
string DecryptString(string encryptedText);
}
Ceci est une implémentation utilisant l'algorithme TripleDES:
public class TripleDESStringEncryptor : IStringEncryptor
{
private byte[] _key;
private byte[] _iv;
private TripleDESCryptoServiceProvider _provider;
public TripleDESStringEncryptor()
{
_key = System.Text.ASCIIEncoding.ASCII.GetBytes("GSYAHAGCBDUUADIADKOPAAAW");
_iv = System.Text.ASCIIEncoding.ASCII.GetBytes("USAZBGAW");
_provider = new TripleDESCryptoServiceProvider();
}
#region IStringEncryptor Members
public string EncryptString(string plainText)
{
return Transform(plainText, _provider.CreateEncryptor(_key, _iv));
}
public string DecryptString(string encryptedText)
{
return Transform(encryptedText, _provider.CreateDecryptor(_key, _iv));
}
#endregion
private string Transform(string text, ICryptoTransform transform)
{
if (text == null)
{
return null;
}
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
byte[] input = Encoding.Default.GetBytes(text);
cryptoStream.Write(input, 0, input.Length);
cryptoStream.FlushFinalBlock();
return Encoding.Default.GetString(stream.ToArray());
}
}
}
}
Vous pouvez regarder ma vidéo et télécharger le code correspondant à l'adresse suivante: http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in- nhibernateactive-record-video.html
Une option serait de stocker le hachage (SHA1, MD5) du mot de passe au lieu du mot de passe en texte clair, et chaque fois que vous voulez voir si le mot de passe est bon, comparez-le simplement à ce hachage.
Si vous avez besoin d'un stockage sécurisé (par exemple pour un mot de passe que vous utiliserez pour vous connecter à un service), le problème est plus complexe.
Si c'est juste pour l'authentification, alors il suffirait d'utiliser le hachage.
Si vous voulez pouvoir déchiffrer le mot de passe, je pense que le moyen le plus simple serait d'utiliser DPAPI (mode de magasin utilisateur) pour chiffrer/déchiffrer. Ainsi, vous n'avez pas besoin de manipuler les clés de cryptage, de les stocker quelque part ou de les coder en dur dans votre code - dans les deux cas, quelqu'un peut les découvrir en consultant le registre, les paramètres utilisateur ou en utilisant Reflector.
Sinon, utilisez les hachages SHA1 ou MD5 comme d'autres l'ont dit ici.
Comme dit ligget78, DPAPI serait un bon moyen de stocker des mots de passe. Consultez la classe ProtectedData sur MSDN pour un exemple d'utilisation.
J'ai cherché partout un bon exemple de processus de cryptage et de décryptage, mais la plupart étaient excessivement complexes.
Quoi qu'il en soit, il existe de nombreuses raisons pour lesquelles une personne peut vouloir déchiffrer certaines valeurs de texte, y compris les mots de passe. La raison pour laquelle j'ai besoin de déchiffrer le mot de passe sur le site sur lequel je travaille actuellement, c'est parce qu'ils veulent s'assurer que lorsqu'une personne est forcée de changer son mot de passe à l'expiration, nous ne la laissons pas changer avec une variante proche du même mot de passe. ils ont utilisé au cours des x derniers mois.
J'ai donc écrit un processus qui le fera de manière simplifiée. J'espère que ce code est bénéfique pour quelqu'un. Pour autant que je sache, je pourrais finir par l'utiliser à un autre moment pour une autre société/un autre site.
public string GenerateAPassKey(string passphrase)
{
// Pass Phrase can be any string
string passPhrase = passphrase;
// Salt Value can be any string(for simplicity use the same value as used for the pass phrase)
string saltValue = passphrase;
// Hash Algorithm can be "SHA1 or MD5"
string hashAlgorithm = "SHA1";
// Password Iterations can be any number
int passwordIterations = 2;
// Key Size can be 128,192 or 256
int keySize = 256;
// Convert Salt passphrase string to a Byte Array
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
// Using System.Security.Cryptography.PasswordDeriveBytes to create the Key
PasswordDeriveBytes pdb = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
//When creating a Key Byte array from the base64 string the Key must have 32 dimensions.
byte[] Key = pdb.GetBytes(keySize / 11);
String KeyString = Convert.ToBase64String(Key);
return KeyString;
}
//Save the keystring some place like your database and use it to decrypt and encrypt
//any text string or text file etc. Make sure you dont lose it though.
private static string Encrypt(string plainStr, string KeyString)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = 256;
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.ECB;
aesEncryption.Padding = PaddingMode.ISO10126;
byte[] KeyInBytes = Encoding.UTF8.GetBytes(KeyString);
aesEncryption.Key = KeyInBytes;
byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);
ICryptoTransform crypto = aesEncryption.CreateEncryptor();
byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
return Convert.ToBase64String(cipherText);
}
private static string Decrypt(string encryptedText, string KeyString)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = 256;
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.ECB;
aesEncryption.Padding = PaddingMode.ISO10126;
byte[] KeyInBytes = Encoding.UTF8.GetBytes(KeyString);
aesEncryption.Key = KeyInBytes;
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
}
String KeyString = GenerateAPassKey("PassKey");
String EncryptedPassword = Encrypt("25Characterlengthpassword!", KeyString);
String DecryptedPassword = Decrypt(EncryptedPassword, KeyString);
S'il s'agit d'un mot de passe utilisé pour l'authentification par votre application, hachez le mot de passe comme le suggèrent d'autres personnes.
Si vous stockez des mots de passe pour une ressource externe, vous voudrez souvent pouvoir demander à l'utilisateur ces informations d'identification et lui donner la possibilité de les sauvegarder de manière sécurisée. Windows fournit à cet effet l'interface utilisateur de Credentials (CredUI). Plusieurs exemples montrent comment l'utiliser dans .NET, notamment celui-ci sur MSDN .
Si vous avez besoin de plus que cela, par exemple, la sécurisation d'une chaîne de connexion (pour la connexion à une base de données), cochez ceci article , car il fournit la meilleure "option" pour cela.
La réponse de Oli est également bonne, car elle montre comment créer un hachage pour une chaîne.
..NET fournit des services de chiffrement dans la classe contenue dans l'espace de noms System.Security.Cryptography.