2013-08-14 3 views
2

Кто-то спросил меня, как я буду расшифровывать данную AES 256-битную зашифрованную строку, если бы знал секретный ключ. Я не очень хорошо разбираюсь в шифровании, поэтому я сел, чтобы изучить проблему.C# AES 256-битный расшифровать данный зашифрованный текст и секрет

Я нашел this example on MSDN и попытался изменить его, чтобы сделать только Расшифровать:

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

internal class AesExample 
{ 
    public static void Main() 
    { 
     var encryptedString = "U2FsdGVkX1/cHT8XuHCfpw0AV4jpaO8JfLqUeCRJqjY="; 
     var secret = "SPARKY"; 

     // I know this is not the correct way to get my input byte arrays... 
     // Just illustrating that I DO need byte arrays. 
     var encryptedBytes = Encoding.UTF8.GetBytes(encryptedString); 
     var secretBytes = Encoding.UTF8.GetBytes(secret); 

     try 
     { 
      using (var aes = new AesManaged()) 
      { 
       aes.Key = secretBytes; 

       // Decrypt the bytes to a string. 
       var decryptedString = Decrypt(encryptedBytes, aes.Key, aes.IV); 

       //Display the original data and the decrypted data. 
       Console.WriteLine("Encrypted: {0}", encryptedString); 
       Console.WriteLine("Decrypted: {0}", decryptedString); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error: {0}", e.Message); 
     } 
    } 

    private static string Decrypt(byte[] cipherText, byte[] key, byte[] iv) 
    { 
     // Declare the string used to hold 
     // the decrypted text. 
     string plaintext; 

     // Create an AesManaged object 
     // with the specified key and IV. 
     using (var aes = new AesManaged()) 
     { 
      aes.Key = key; 
      aes.IV = iv; 

      // Create a decrytor to perform the stream transform. 
      var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); 

      // Create the streams used for decryption. 
      using (var msDecrypt = new MemoryStream(cipherText)) 
      { 
       using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
       { 
        using (var srDecrypt = new StreamReader(csDecrypt)) 
        { 
         // Read the decrypted bytes from the decrypting stream 
         // and place them in a string. 
         plaintext = srDecrypt.ReadToEnd(); 
        } 
       } 
      } 
     } 

     return plaintext; 
    } 
} 

Конечно, как только я попал в следующую линию, CryptographicExcetion отбрасывается с сообщением «Указанный ключ не является допустимый размер для этого алгоритма ». ==> aes.Key = secretBytes

Кто-то предложил взять хэш SHA1 в тайне и обрезать до 20 байтов. Я попробовал это, и я начал получать новое CryptographicException с сообщением «Длина данных для дешифрования недействительна».

Итак, у меня есть несколько вопросов:

1) Является ли это даже возможно, учитывая только зашифрованный текст и секретный ключ?

2) Если да, то это некоторые базовые предположения, которые нужно было бы сделать, например CipherMode? Я читал, что режим ECB не имеет вектора инициализации. Вот почему я спрашиваю.

3) Что мне нужно сделать, чтобы поместить входы (зашифрованный текст и секретный ключ) в правильный формат Byte [] для дешифрования?

Спасибо!

+0

Не зашифрованString UTF-16? Зачем кодировать его в UTF-8? –

+0

@NaNa - Я не знаю, что кодировка точно, но изменение его на UTF16 (Encoding.Unicode в .Net) приводит к тому же «Длина данных для дешифрования недействительна» CryptographicException. –

+0

Тот, кто задал вам этот вопрос, указали, как была получена зашифрованная строка? Как и в случае с другой программой C# с AesManaged или аналогичным?Единственная причина, по которой я спрашиваю, - я столкнулся с проблемой, связанной с попыткой переноса javascript-кода на C# некоторое время назад. В javascript-коде использовалась реализация AES, которая не может быть дублирована ни с одним из стандартных классов AES в C#. –

ответ

2

Длина ключей AES составляет 128, 192 и 256 бит в зависимости от шифрования, который вы хотите использовать. Вы должны убедиться, что ваша строка соответствует длине байтов.

10

Возможно, вам понадобится дополнительная информация, чтобы сделать эту работу. Чтобы ответить на ваши конкретные вопросы:

  1. Да, за исключением того, что у вас нет секретного ключа. «SPARKY» не является действительным ключом AES, как упоминает DavidHH, хотя пароли обычно используются для вывести секретными ключами через так называемые key derivation functions. Вы можете попробовать запустить свой пароль через Rfc2898DeriveBytes (популярный KDF в .NET), чтобы получить разные ключи AES, которые могут работать, но он тоже принимает параметры, которых вы, очевидно, не имеете. Вы также можете попробовать различные SHA-хэш-дайджесты вашего пароля, хотя снова 20 байтов не являются действительным ключом AES - вам нужен ключ 16, 24 или 32 байта.
  2. Если у вас нет IV, тогда да, вам придется предположить, что шифрование использует ECB. (Но учтите, что в целом вы должны never use ECB mode.)
  3. Ваша зашифрованная строка, кажется, закодирована с использованием base64. Преобразование его в массив байтов достаточно прост в .NET с использованием Convert.FromBase64String(encryptedString);.

Это звучит весело, но вы, вероятно, просто разочаруетесь, не получая дополнительной информации.

Смежные вопросы