2008-09-23 5 views
4

J'essaie de stocker un mot de passe dans un fichier que je souhaite récupérer pour plus tard. Le hachage n'est pas une option car j'ai besoin du mot de passe pour me connecter à un serveur distant pour plus tard.La sortie de cryptage est toujours différente même avec la même clé

Le code suivant fonctionne bien, mais il crée une sortie différente chaque fois même si la clé est la même. C'est mauvais car lorsque l'application s'arrête et redémarre je ne pourrai plus récupérer mon mot de passe. Comment puis-je stocker des mots de passe dans un fichier et les récupérer plus tard?

public class EncyptDecrypt { 

    static System.Security.Cryptography.TripleDESCryptoServiceProvider keyProv = new System.Security.Cryptography.TripleDESCryptoServiceProvider(); 

    public static System.Security.Cryptography.TripleDESCryptoServiceProvider KeyProvider { 
     get { 
      keyProv.Key = new byte[] { /* redacted with prejudice */ }; 
      return keyProv; 
     } 
    } 

    public static string Encrypt(string text, SymmetricAlgorithm key) { 

     if (text.Equals(string.Empty)) return text; 

     // Create a memory stream. 
     MemoryStream ms = new MemoryStream(); 

     // Create a CryptoStream using the memory stream and the 
     // CSP DES key. 
     CryptoStream encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write); 

     // Create a StreamWriter to write a string 
     // to the stream. 
     StreamWriter sw = new StreamWriter(encStream); 

     // Write the plaintext to the stream. 
     sw.WriteLine(text); 

     // Close the StreamWriter and CryptoStream. 
     sw.Close(); 
     encStream.Close(); 

     // Get an array of bytes that represents 
     // the memory stream. 
     byte[] buffer = ms.ToArray(); 

     // Close the memory stream. 
     ms.Close(); 

     // Return the encrypted byte array. 
     return System.Convert.ToBase64String(buffer); 
    } 

    // Decrypt the byte array. 
    public static string Decrypt(string cypherText, SymmetricAlgorithm key) { 

     if (cypherText.Equals(string.Empty)) return cypherText; 

     string val; 

     try { 
      // Create a memory stream to the passed buffer. 
      MemoryStream ms = new MemoryStream(System.Convert.FromBase64String(cypherText)); 

      // Create a CryptoStream using the memory stream and the 
      // CSP DES key. 
      CryptoStream encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read); 

      // Create a StreamReader for reading the stream. 
      StreamReader sr = new StreamReader(encStream); 

      // Read the stream as a string. 
      val = sr.ReadLine(); 

      // Close the streams. 
      sr.Close(); 
      encStream.Close(); 
      ms.Close(); 
     } 
     catch (System.Exception) { 

      return string.Empty; 
     } 

     return val; 
    } 
} 

Répondre

8

Je crois que ce qui se passe est que le fournisseur de chiffrement génère aléatoirement une IV. Précisez ceci et il ne devrait plus différer. Edit: Vous pouvez le faire dans votre 'keyProvider' en définissant la propriété IV.

+0

À titre de note, un IV est un élément de données supplémentaire qui accompagne votre clé. Cette information est publique et ne doit pas être cachée et n'ajoute rien à la sécurité si elle l'est. Il est utilisé pour rendre la cryptanalyse plus difficile. –

+0

La mise en œuvre peut-elle aussi être complétée avec des données aléatoires? Je ne sais pas assez pour dire si c'est le cas ou non, juste assez pour dire que dans certains modes de chiffrement par bloc c'est approprié. –

+0

Il sera complété avec des zéros avant le cryptage, IIRC. Et même ainsi, vous ne verriez que des données différentes dans le dernier octets. Bien sûr, le demandeur n'a pas précisé/comment/différentes les données étaient, alors qui sait. –

3

Selon les docs de CreateEncryptor:

Si la propriété actuelle IV est une référence null (Nothing en Visual Basic), la méthode GenerateIV est appelée à créer une nouvelle IV aléatoire.

Cela rendra le texte chiffré différent à chaque fois.

Note: une façon de contourner cela est discuté here où je suggère que vous pouvez préfixer le texte en clair avec un mac ... puis le premier bloc de cryptogramme est effectivement la IV, mais il est tout

reproductible
2

Vous devez spécifier un IV (vecteur d'initialisation), même si vous en générez un aléatoire. Si vous utilisez un IV aléatoire, vous devez le stocker avec le texte chiffré afin de pouvoir l'utiliser plus tard lors du déchiffrement, ou vous pouvez déduire un IV à partir d'autres données (par exemple, si vous cryptez un mot de passe, l'identifiant).

Questions connexes