2010-06-10 4 views
6

Je suis tout à fait nouveau dans la programmation. J'ai écrit le code ci-dessous afin d'inviter l'utilisateur pour un mot de passe pour crypter un fichier, Mais cela fonctionne seulement lorsque la longueur du mot de passe est 8 Pour accepter un nombre illimité de caractères pour le mot de passe?Cryptage en utilisant rijndael

string pass = textBox2.Text.ToString(); 
      string password = @"" + pass + ""; 
      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] key = UE.GetBytes(password); 


      FileStream fsCrypt = new FileStream(@"c:\\users\\new", FileMode.Create); 
      name = fsCrypt.Name; 
      RijndaelManaged RMCrypto = new RijndaelManaged(); 

      CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write); 

      FileStream fsIn = new FileStream(filename, FileMode.Open); 

      int data; 
      while ((data = fsIn.ReadByte()) != -1) 
       cs.WriteByte((byte)data); 
+0

Je suis un peu perplexe par la ligne: mot de passe chaîne = @ « » + passe + « »; qu'est-ce que vous essayez d'atteindre en joignant une chaîne emtpy sur chaque extrémité d'une chaîne, résultant en une chaîne identique. –

Répondre

1

Le fait de dériver directement une clé de votre mot de passe avec Encoding.GetBytes() ne fonctionnera que si le résultat de GetBytes() est un KeySize légal.

Plus important encore, cela rend une clé très faible, d'autant plus que vous avez opté pour le codage Unicode. Le motif d'octets dans votre clé pour "foobar" est 66 00 6F 00 6F 00 62 00 61 00 72 00. Voyez-vous tous les 00 octets?

La méthode officielle est d'utiliser la classe Rfc2898DeriveBytes. Aussi, ce n'est probablement pas une bonne idée d'utiliser la clé comme IV, je ne suis pas entièrement sûr de cela.

Voir aussi this SO question.

+0

Merci de le mentionner, oui vous avez raison, il est allé être un faible. – Mohammad

+0

Réutiliser la clé comme IV est en effet une mauvaise idée. J'ai écrit à ce sujet ici: http://crazyscot.livejournal.com/304065.html – crazyscot

+0

@crazyscot: Oui, merci pour les liens. Mais notez que c'est un peu acceptable pour chiffrer des chaînes courtes tout en évitant les frais généraux de transport de sel et IV. Mais il devrait être clairement marqué et compris comme faible. –

2

Vous avez besoin d'une fonction qui va obtenir une longueur de clé valide pour Rijndael de votre mot de passe, et au moment, votre utilisation UnicodeEncoding.GetBytes va seulement donner cela pour certaines longueurs discrètes de mot de passe, vous J'ai découvert.

Vous devriez utiliser une autre fonction pour obtenir une clé de votre mot de passe - peut-être prendre le tableau d'octets que vous avez généré, et exécuter une fonction de hachage cryptographique comme SHA1 sur elle. SHA1 vous donnera une longueur de 128 bits, comme le font actuellement vos mots de passe à 8 caractères, mais quelle que soit la longueur du mot de passe.

+0

Laissez-moi voir si j'ai bien compris? Vous voulez dire que je devrais prendre une valeur de hachage du mot de passe (ce qui est à coup sûr assez long), puis passer cela comme la clé? – Mohammad

+0

@user ####: Oui. –

0

Découvrez PasswordDeriveBytes

http://msdn.microsoft.com/en-us/library/system.security.cryptography.passwordderivebytes(v=VS.100).aspx

Vous aurez besoin d'une valeur de sel fixe ainsi que le passé, ce qui empêche les gens qui travaillent sur les mots de passe de l'algorithme.

Il est utilisé comme celui-ci pour TripleDES et devrait être facile à modifier pour Rijndael:

// Create a TripleDESCryptoServiceProvider object. 
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 

// Create a PasswordDeriveBytes object and then create 
// a TripleDES key from the password and salt. 
PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt); 


// Create the key and set it to the Key property 
// of the TripleDESCryptoServiceProvider object. 
tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV); 
Questions connexes