2015-08-03 3 views
0

Я не undrestand, почему этот код возвращает ошибку:метод CryptographicEngine.Decrypt возвращает ошибку в C# UWP приложение

Data error (cyclic redundancy check). (Exception from HRESULT: 0x80070017) 

, потому что эквивалентный код из Silverlight платформы не поднимать exception.This является Код UWP C# ниже:

public static async Task<Stream> Decrypt(Stream source, 
      IBuffer easKey,IBuffer IV, byte[] masterKey) 
     { 
      try 
      { 

       SymmetricKeyAlgorithmProvider aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7); 
       if ((source.Length % aes.BlockLength) != 0) 
       { 
        var temp = new MemoryStream(); 
        temp.SetLength(source.Length + (aes.BlockLength - source.Length % aes.BlockLength)); 
        source.CopyTo(temp); 
        source = temp; 
       } 

       CryptographicKey symmKey = aes.CreateSymmetricKey(easKey); 
       var sarray = ((MemoryStream)source).ToArray(); 
       IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey,sarray.AsBuffer(), IV); 
       byte[] result; 
       CryptographicBuffer.CopyToByteArray(resultBuffer, out result); 

       return new MemoryStream(result); 


      } 
      catch (Exception e) 
      { 
       await new MessageDialog(e.StackTrace, e.Message).ShowAsync(); 
      } 
      return null; 

     } 
+1

Если вы дешифруете данные, я не понимаю, почему вам нужно проверить, что длина данных кратна длине блока - соответствующая функция шифрования должна применяться для заполнения, поэтому текст шифрования всегда будет * размер блока. – vcsjones

ответ

0

vcsjones ударил важный момент в комментарии по вашему вопросу. Если вы проверяете длину данных как кратное длине блока, а это не так, вы должны выбросить исключение, чтобы данные были плохими. Потому что ничто, зашифрованное с помощью AES, не приведет к чему-либо, отличающемуся от даже кратного длины блока. Даже пустая строка создает 1-блочный шифрованный текст.

Сказав это, у вас есть алгоритм шифрования, который готов расшифровать блоки с помощью дополнения PKCS7. А с другой стороны, если вы получаете короткий блок, вы копируете его в MemoryStream, который является правильной длиной. Я предполагаю, что последние байты - это нули. Таким образом, этот блок не является допустимым текстовым блоком шифрования.

PKCS7 padding добавляет X количество байтов, чтобы получить четное кратное размеру блока, и каждый из этих байтов - это то же самое число. Поэтому, если у вас размер блока 16 байт (128 бит), а ваш последний блок содержит только 10 байт реальной информации, вы должны иметь последние 6 байтов, заполненных как 0x06 0x06 0x06 0x06 0x06 0x06.

Критическое здесь, однако, заключается в том, что это дополнение дополняется простым текстом перед шифрованием. Вы не можете просто добавить дополнение к концу частичного блока шифрованного текста и иметь возможность расшифровать его. Характер этих сильных алгоритмов шифрования заключается в том, что конечное значение любого заданного бита в блоке является функцией буквально каждого другого бита в блоке. Поэтому, если вы потеряли часть этого блока, вы потеряли весь блок безвозвратно.

Теперь, если вам действительно нужно расшифровать столько сообщений, сколько сможете, выбросьте частичный блок (вы никогда его не расшифруете, как я уже упоминал выше). Замените его полным блоком 0x10 (повторяется 16 раз). Это говорит алгоритму, что у вас было ровно X количество блоков обычного текста, а на PKCS7 вы добавили ровно весь блок PKCS7-совместимого дополнения. Это позволит вам расшифровать все, кроме частичного блока сообщения.

Редактирование, чтобы сказать, что вы должны зашифровать блок дополнений с использованием того же ключа и привязать его к шифрованному тексту, чтобы иметь возможность расшифровать все, кроме частичного блока. Но это не самый простой способ. На вашем месте я просто изменил бы свои настройки расшифровки на padding = None. Снова выбросьте частичный блок, а остальные должны расшифровать без проблем, пока он не поврежден.

+0

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