436 votes

Cryptage & décrypter une chaîne en c#

Ce qui est la plus moderne (meilleure) façon de satisfaire ce qui suit en c# ?

MAIS avec un minimum de tracas des sels, clés, déblayage avec byte [], etc..

Été googler et confus à ce que je suis constatation (vous pouvez voir la liste des semblable SO Qs pour voir cela est une question trompeuse à poser).

924voto

CraigTP Points 18514

Comme d'autres personnes l'ont dit, la Cryptographie n'est pas simple, il est donc préférable d'éviter de "rouler votre propre" algorithme de chiffrement.

Vous pouvez, cependant, "rouler propre" classe wrapper autour de quelque chose comme le haut- RijndaelManaged de la cryptographie classe.

Rijndael est l'algorithmique nom de l' Advanced Encryption Standard, de sorte que vous êtes certainement à l'aide d'un algorithme qui pourrait être considéré comme "meilleure pratique".

L' RijndaelManaged classe, en effet, normalement vous obliger à "bricolons" avec des tableaux d'octets, les sels, les clés, l'initialisation des vecteurs etc. mais c'est précisément le genre de détail qui peut être un peu disparaît à l'intérieur de votre classe "wrapper".

La classe suivante est celle que j'ai écrit il y a un moment pour effectuer exactement le genre de chose que vous êtes après, un simple appel de méthode unique pour permettre à certains basée sur une chaîne en clair pour être chiffrés avec une chaîne de mot de passe, avec la chaîne cryptée également être représenté par une chaîne. Bien sûr, il y a une méthode équivalente pour décrypter la chaîne cryptée avec le même mot de passe.

Notez qu'il y a un peu compromis ici en raison de la simplification dans la façon de générer le sel/IV de la valeur (en gros, votre en utilisant exactement les mêmes sel/IV à chaque fois) et dans un monde idéal (c'est à dire le monde plus sûr) que vous souhaitez utiliser différents de sel pour chaque chaîne que vous avez voulu chiffrer et stocker le sel avec le cryptés.

La "force" de l'utilisation de ce (malgré les compromis pour des raisons de simplicité) vient de l'utilisation de l' RijndaelManaged classe pour effectuer le chiffrement pour vous, avec l'aide de la PasswordDeriveBytes fonction de l' System.Security.Cryptography d'espace de noms qui permettra de générer votre clé de chiffrement à l'aide d'un standard et sécurisée de l'algorithme (en particulier, PBKDF1), basé sur la chaîne de mot de passe que vous fournissez.

Sans savoir exactement à vos exigences, il est difficile de dire si c'est suffisamment sécurisé pour vos besoins, mais si vous êtes juste après une seule ligne de l'appel de méthode à rapidement chiffrer une chaîne, je pense que cela suffira.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace EncryptStringSample
{
    public static class StringCipher
    {
        // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
        // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
        // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
        private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");

        // This constant is used to determine the keysize of the encryption algorithm.
        private const int keysize = 256;

        public static string Encrypt(string plainText, string passPhrase)
        {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using (RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                            {
                                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                                cryptoStream.FlushFinalBlock();
                                byte[] cipherTextBytes = memoryStream.ToArray();
                                return Convert.ToBase64String(cipherTextBytes);
                            }
                        }
                    }
                }
            }
        }

        public static string Decrypt(string cipherText, string passPhrase)
        {
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            using(PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using(RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using(ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                    {
                        using(MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                        {
                            using(CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                                int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                            }
                        }
                    }
                }
            }
        }
    }
}

La classe ci-dessus peut servir tout simplement avec un code semblable au suivant:

using System;
using System.Linq;

namespace EncryptStringSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a password to use:");
            string password = Console.ReadLine();
            Console.WriteLine("Please enter a string to encrypt:");
            string plaintext = Console.ReadLine();
            Console.WriteLine("");

            Console.WriteLine("Your encrypted string is:");
            string encryptedstring = StringCipher.Encrypt(plaintext, password);
            Console.WriteLine(encryptedstring);
            Console.WriteLine("");

            Console.WriteLine("Your decrypted string is:");
            string decryptedstring = StringCipher.Decrypt(encryptedstring, password);
            Console.WriteLine(decryptedstring);
            Console.WriteLine("");

            Console.ReadLine();
        }
    }
}

(Vous pouvez télécharger un simple VS2010 exemple de solution ici).

31voto

ja72 Points 9417

Essayez cette classe :

et l’utiliser comme ceci :

21voto

Ulises Points 4893

Si vous avez besoin de stocker un mot de passe dans la mémoire et voudrais l'avoir crypté, vous devez utiliser SecureString:

http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx

Pour plus d'utilisations générales, je voudrais utiliser un FIPS approuvé algorithme tel que Advanced Encryption Standard, anciennement connu sous le Rijndael. Voir cette page pour un exemple de mise en œuvre:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

13voto

SLaks Points 391154

Vous pouvez rechercher la `` classe, qui crypte les données à l’aide des informations d’identification de l’utilisateur.

-2voto

Mike Calvert Points 85

La façon la plus simple que j'ai vu faire de chiffrement est par le biais de RSA

Consultez le MSDN: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx

Il n'impliquent l'utilisation d'octets, mais quand il descend à lui que vous ne voulez le chiffrement et le déchiffrement être difficiles à comprendre, autrement, il sera facile de pirater.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X