2013-07-09 2 views
1

В случае, когда мне нужно расшифровать тексты с помощью разных клавиш , мне также нужно развить действительные ключи в коде.Почему ключ TripleDES.Create() не подходит для этого алгоритма?

Я использую эту строку для генерации ключа.

var key = Encoding.UTF8.GetString(TripleDES.Create().Key); 

но не может использовать этот ключ в этом методе. он говорит: «Указанный ключ не является допустимым размером для этого алгоритма»

как я могу исправить эту ситуацию?

public class CryptoHelper 
{ 
    public string Encrypt(string toEncrypt, string key) 
    { 
     var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); 
     var keyArray = Encoding.UTF8.GetBytes(key); 

     var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; 

     var cTransform = tdes.CreateEncryptor(); 
     var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
     tdes.Clear(); 

     return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    } 

    public string Decrypt(string cipherString, string key) 
    { 
     var toEncryptArray = Convert.FromBase64String(cipherString.Replace(' ', '+')); 
     var keyArray = Encoding.UTF8.GetBytes(key); 
     var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; 

     var cTransform = tdes.CreateDecryptor(); 
     var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
     tdes.Clear(); 

     return Encoding.UTF8.GetString(resultArray); 
    } 
} 
+2

Нет гарантии, что байты, сгенерированные для ключа, могут быть безопасно округлены в строку, действуя так, как если бы они были правильной последовательностью UTF-8. Вы, кажется, уже поняли, что ** данные ** не могут быть округлены без использования кодировки, которая сохраняет все байты, такие как Base 64, - почему вы предполагаете, что ключ может? –

+1

@Jodrell - если вы декодируете последовательность байтов, которые не являются UTF-8 как UTF-8, вы можете получить заменяющие символы. Когда вы перекодируете строку, содержащую заменяющие символы, результирующий вывод может быть другой длины, потому что символы замены кодируются по-другому, чем они заменяются. –

+0

@Damien_The_Unbeliever, как вы можете видеть из моего ответа, вы находитесь на месте. – Jodrell

ответ

5

Если написать небольшой тест, ваша проблема становится очевидным,

var failures = ParallelEnumerable.Range(0, 10000).Count(i => 
    { 
     var keyBefore = TripleDES.Create().Key; 
     var keyAfter = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(keyBefore)); 
     return !keyBefore.SequenceEqual(keyAfter); 
    }); 

В ходе тестирования, каждый пытался туда и обратно не может. Это подтверждает комментарий Дэмиена.

Там нет никакой гарантии, что байты, полученные для ключа могут быть безопасно круглодонным споткнулись в строку, действуя так, как будто они допустимая UTF-8 последовательности.

keyAfter (почти) всегда несколько расширенный, иногда удвоенный по длине. На самом деле, я не могу воспользоваться ключом, который является круглым trippable, это может иметь какое-то отношение к предотвращению слабых клавиш.


Однако, если я пытаюсь

var failures = ParallelEnumerable.Range(0, 10000).Count(i => 
    { 
     var keyBefore = TripleDES.Create().Key; 
     var keyAfter = Convert.FromBase64String(Convert.ToBase64String(keyBefore)); 
     return !keyBefore.SequenceEqual(keyAfter); 
    }); 

failures всегда равна 0, как и ожидалось. Итак, есть простое решение.

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