2017-10-01 3 views
0

Je veux stocker une chaîne cryptée dans une base de données SQL en tant que tableau d'octets et je ne peux pas comprendre ce que je fais mal. Le code est le suivant:Cryptage et décryptage d'une chaîne à l'aide d'Aes Encryption - C#

private void loginBtn_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      string password = passwordBox.Text.ToString(); 

      using (Aes algorithm = Aes.Create()) 
      { 
       byte[] encryptedPassword = EncryptString(password, algorithm.Key, algorithm.IV); 

       string roundTrip = DecryptString(encryptedPassword, algorithm.Key, algorithm.IV); 

       MessageBox.Show("Encrypted Password: " + encryptedPassword.ToString() + '\n' + "Round Trip: " + roundTrip.ToString()); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

Et le code utilisé pour le « EncryptString » et « DecryptString » est celui de Microsoft's Aes Class Reference (l'exemple situé à la fin de la page).

J'ai exécuté mon code et tout cela me donne dans une boîte de message est le suivant:

Encrypted Password: System.Byte[]

Round Trip: (empty space)

static byte[] EncryptString(string str, byte[] key, byte[] IV) 
    { 
     if (str == null || str.Length <= 0) 
      throw new ArgumentNullException("string"); 
     if (key == null || key.Length <= 0) 
      throw new ArgumentNullException("key"); 
     if (IV == null || IV.Length <= 0) 
      throw new ArgumentNullException("IV"); 

     byte[] encrypted; 

     using (Aes algorithm = Aes.Create()) 
     { 
      algorithm.Key = key; 
      algorithm.IV = IV; 

      ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV); 

      using (MemoryStream msEncrypt = new MemoryStream()) 
      { 
       using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
       { 
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
        { 
         swEncrypt.Write(str); 
        } 
        encrypted = msEncrypt.ToArray(); 
       } 
      } 
     } 

     return encrypted; 
    } 

    static string DecryptString(byte[] cipher, byte[] key, byte[] IV) 
    { 
     if (cipher == null || cipher.Length <= 0) 
      throw new ArgumentNullException("cipher"); 
     if (key == null || key.Length <= 0) 
      throw new ArgumentNullException("key"); 
     if (IV == null || IV.Length <= 0) 
      throw new ArgumentNullException("IV"); 

     string decrypted; 

     using (Aes algorithm = Aes.Create()) 
     { 
      algorithm.Key = key; 
      algorithm.IV = IV; 

      ICryptoTransform decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV); 

      using (MemoryStream msDecrypt = new MemoryStream()) 
      { 
       using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
       { 
        using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
        { 
         decrypted = srDecrypt.ReadToEnd(); 
        } 
       } 
      } 
     } 

     return decrypted; 
    } 

Quelqu'un peut-il me aider à résoudre ce, s'il vous plaît?

P.S. La zone de texte a le mot de passe Char setted à *

+0

Fonctionne bien pour moi. Postez votre code de cryptage/décryptage réel s'il vous plaît. –

+0

Ce programme fonctionne correctement pour moi aussi - avec 'string password =" ABCD "', roundTrip alco contient "ABCD". Qu'avez-vous essayé comme mot de passe? Avez-vous modifié les méthodes 'EncryptString' et' DecryptString' de l'exemple de Microsoft? –

+0

Vous verrez mieux si vous changez votre ligne de message à MessageBox.Show ("Mot de passe crypté:" + Encoding.ASCII.GetString (encryptedPassword) + '\ n' + "Round Trip:" + roundTrip); ou quelque chose comme (peut-être UTF au lieu de ACII, dépend de votre jeu de caractères). –

Répondre

1

Dans la méthode DecryptString, vous avez oublié de passer le paramètre cipher au constructeur de msDecrypt flux de mémoire comme une entrée, la méthode ainsi déchiffre en fait flux d'entrée vide, donc le résultat est vide aussi.

Ligne

using (MemoryStream msDecrypt = new MemoryStream()) 

devrait en fait être:

using (MemoryStream msDecrypt = new MemoryStream(cipher)) 

et tout fonctionne bien.

+0

Je viens de trouver la même chose! Ça va m'apprendre à continuer à lire :-) –

+0

Merci beaucoup. Maintenant, je sais que je dois accorder plus d'attention aux exemples de code. Tu l'as réparé, je ne peux pas croire que ça se cache si bien. Maintenant, j'ai un autre petit problème. Si j'utilise Encoding.ASCII.GetBytes (ici 64 caractères); comme clé et Encoding.ASCII.GetBytes (ici 32 caractères); comme IV, il me donne l'erreur: "La clé spécifiée n'est pas une taille valide pour cet algorithme.". Savez-vous comment dois-je faire cela? J'ai essayé de modifier le BlockSize de l'algorithme Aes mais cela ne fonctionnera pas, au lieu de cela, il me donne le même message d'erreur. Merci encore! –

+0

Il existe seulement 3 variantes d'AES: AES-128, AES-192 et AES-256. Donc ** la taille de la clé ** doit être de 128 bits (16 octets), de 192 bits (24 octets) ou de 256 bits (32 octets). Vous pouvez obtenir des tailles de clé valides à partir de la propriété [LegalKeySizes] (https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.symmetricalgorithm.legalkeysizes?view=netframework-4.7). De plus, toutes les variantes AES requièrent ** taille de bloc ** de 128 bits (16 octets) comme vous pouvez le voir dans [LegalBlockSizes] (https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography .symmetricalgorithm.legalblocksizes? view = netframework-4.7) propriété. –