2016-11-03 3 views
0

AKTUALISIERT: Das Problem war ich! Ich habe einen Fehler gemacht, sonst sind beide Cods (unten und der bei PS sind richtig) Aber immer noch dank der tollen Antwort von @Luke Park, dass ich etwas Neues gelernt habe.So verschlüsseln Sie Zeichenfolgen, die nicht 64 Zeichen haben dürfen

Ich bin nicht mit Verschlüsselungs-/Entschlüsselungs-Algorithmen vertraut, dafür ist das Netz suchen und fand diese Klasse:

Encrypting & Decrypting a String in C#

der Code: (I fügen Sie einen Try/Catch in Decrypt Verfahren für den Fall, das Passwort falsch war, es wird return "";)

using System; 
using System.Text; 
using System.Security.Cryptography; 
using System.IO; 
using System.Linq; 

namespace EncryptStringSample 
{ 
    public static class StringCipher 
    { 
     // This constant is used to determine the keysize of the encryption algorithm in bits. 
     // We divide this by 8 within the code below to get the equivalent number of bytes. 
     private const int Keysize = 256; 

     // This constant determines the number of iterations for the password bytes generation function. 
     private const int DerivationIterations = 1000; 

     public static string Encrypt(string plainText, string passPhrase) 
     { 
      // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text 
      // so that the same Salt and IV values can be used when decrypting. 
      var saltStringBytes = Generate256BitsOfRandomEntropy(); 
      var ivStringBytes = Generate256BitsOfRandomEntropy(); 
      var plainTextBytes = Encoding.UTF8.GetBytes(plainText); 
      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream()) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) 
          { 
           cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
           cryptoStream.FlushFinalBlock(); 
           // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes. 
           var cipherTextBytes = saltStringBytes; 
           cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray(); 
           cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray(); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Convert.ToBase64String(cipherTextBytes); 
          } 
         } 
        } 
       } 
      } 
     } 

    public static string Decrypt(string cipherText, string passPhrase) 
    { 
     // Get the complete stream of bytes that represent: 
     // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText] 
     var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText); 
     // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes. 
     var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize/8).ToArray(); 
     // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes. 
     var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize/8).Take(Keysize/8).ToArray(); 
     // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string. 
     var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize/8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize/8) * 2)).ToArray(); 
     try 
     { 
      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream(cipherTextBytes)) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) 
          { 
           var plainTextBytes = new byte[cipherTextBytes.Length]; 
           var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
          } 
         } 
        } 
       } 
      } 
     } 
     catch (Exception) 
     { 
      return ""; 
     } 
    } 

     private static byte[] Generate256BitsOfRandomEntropy() 
     { 
      var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits. 
      using (var rngCsp = new RNGCryptoServiceProvider()) 
      { 
       // Fill the array with cryptographically secure random bytes. 
       rngCsp.GetBytes(randomBytes); 
      } 
      return randomBytes; 
     } 
    } 
} 

ich diese Klasse in meiner Anwendung wie folgt verwendet:

und ich mag diese Klasse, weil es mir verschiedene Verschlüsselungsergebnisse gibt, wenn ich die letzte Zeile mit den gleichen Daten wiederhole.

Aber jetzt fand ich heraus, ob eine Zeichenfolge keine Zeichen haben andere als Base64-Zeichen wäre es diese Ausnahme steigen: „Der Eingang ist keine gültige Base-64-Zeichenfolge als es enthält eine nicht-Basis 64 Zeichen“ Ich suche im Internet und habe viele Antworten auf dieses Problem gefunden. Wie diese:

The input is not a valid Base-64 string as it contains a non-base 64 character

How can I solver an "base64 invalid characters" error?

In all diesen Fragen, war es, Antworten die gleiche:

entfernen Nicht-base64 Zeichen aus der Zeichenfolge !!!

Aber was, wenn ich oder meine Anwendung Benutzer möchte eine Zeichenfolge wie folgt einzufügen: "A @ S # $ D?" Oder oder .... sein "CanYouGu3 $$ Me?" verschlüsselt?

Meine Frage:

A1. Gibt es eine Möglichkeit, das obige Klassenproblem zu lösen (das ich oben erwähne), ohne irgendwelche Zeichen zu ersetzen oder zu entfernen, die Benutzer zum Verschlüsseln einfügen können?

A2. Wenn es keine Lösung gibt, Was sind die anderen besten Möglichkeiten? Welche Methode kann ich verwenden? Sie kann jede Zeichenfolge mit beliebigen Zeichen darin verschlüsseln/entschlüsseln.

PS: Dieser Code ist auch ein guter und hat keine Probleme mit bestehenden nicht-Base64-Zeichen (weil es auch mit dieser Methode Encoding.UTF8.GetBytes alle Ausnahmen verhindern): https://codereview.stackexchange.com/questions/14892/simplified-secure-encryption-of-a-string

Vielen Dank für Ihre Zeit

Antwort

3

Konvertieren Sie Ihre Eingabezeichenfolge in ein Bytearray und konvertieren Sie diese in base64. Jetzt ist Ihre Eingabe-Zeichenfolge gültig base64 und kann weiterhin verschlüsselt werden.

byte[] data = Encoding.UTF8.GetBytes(inputString); 
string b64 = Convert.ToBase64String(data); 

Vielleicht möchten Sie etwas Zeit investieren, um zu verstehen, warum base64 benötigt wird. Verschlüsselungsalgorithmen arbeiten über Byte-Arrays, Rohdaten, nicht über Strings.

+0

Vielen Dank für Ihre Antwort. Ich habe einen weiteren Fehler gemacht! und ich habe es behoben! Nun, oben Code (das in meinem Startup-Post) funktioniert ohne Probleme. (In der Tat war der ursprüngliche Code korrekt, aber in meiner Änderung habe ich einen Fehler gemacht! Jetzt habe ich behoben) – MRK

+0

@MRK Glücklich zu helfen. –

Verwandte Themen