Intereting Posts
Nullable DateTime и firebase database Могу ли я удалить пустой улов с броском? указать действие сборки контента – Nuget Как проверить, открыт ли сетевой ресурс Как получить доступ к файлу сетевого сетевого диска с помощью кода C # AuthenticationToken имеет значение null Как получить собственный стек из естественных исключений, захваченных в управляемом коде Доступ к методу базового classа с объектами производного classа Выключение приложения WPF из App.xaml.cs Использование InstallUtil для установки службы Windows с параметрами запуска Почему мои обработчики событий нацелены на c? Также – Что такое c? как начать сеанс Teamviewer на основе teamviewerid в asp.net Posttorial: ASP.NET MVC, Entity Framework и видеоуроки LINQ – в том числе MIX09, PDC, TechED Как получить доступ к элементам в динамическом списке? C #: как преобразовать строку в DateTime, где строка может иметь любой стандартный формат даты и времени

Метод EncryptedXml DecryptDocument генерирует исключение «Bad Data»

Я написал блок кода для Encrypt / Decrypt Streams. Код работает на моей локальной машине. Но когда я публикую свой код в Интернете, функции дешифрования вызывают исключение «Bad Data». Вот мои функции шифрования и дешифрования

private static MemoryStream EncryptStream(XmlDocument xmlDoc, XmlElement elementToEncrypt, string password) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = password; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); RijndaelManaged sessionKey = null; try { if (xmlDoc == null) throw new ArgumentNullException("xmlDoc"); if (rsaKey == null) throw new ArgumentNullException("rsaKey"); if (elementToEncrypt == null) throw new ArgumentNullException("elementToEncrypt"); sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, rsaKey, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); edElement.KeyInfo = new KeyInfo(); KeyInfoName kin = new KeyInfoName(); kin.Value = KeyName; ek.KeyInfo.AddClause(kin); edElement.CipherData.CipherValue = encryptedElement; edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); if (sessionKey != null) { sessionKey.Clear(); } rsaKey.Clear(); MemoryStream stream = new MemoryStream(); xmlDoc.Save(stream); stream.Position = 0; Encoding encodeing = System.Text.UnicodeEncoding.Default; return stream; } catch (Exception e) { if (sessionKey != null) { sessionKey.Clear(); } rsaKey.Clear(); throw (e); } } private static MemoryStream DecryptStream(XmlDocument xmlDoc, string password) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = password; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); EncryptedXml exml = null; try { if (xmlDoc == null) throw new ArgumentNullException("xmlDoc"); if (rsaKey == null) throw new ArgumentNullException("rsaKey"); exml = new EncryptedXml(xmlDoc); exml.AddKeyNameMapping(KeyName, rsaKey); exml.DecryptDocument(); rsaKey.Clear(); MemoryStream outStream = new MemoryStream(); xmlDoc.Save(outStream); outStream.Position = 0; return outStream; } catch (Exception e) { rsaKey.Clear(); throw (e); } } 

исключение выбрано на “exml.DecryptDocument ();” линия.

Есть ли у вас какие-либо идеи о проблеме и решении?

Редактировать:

на странице MSDN есть замечание, которое выглядит следующим образом

Чтобы использовать шифрование XML с сертификатами X.509, должен быть установлен Microsoft Enhanced Cryptographic Provider, а сертификат X.509 должен использовать расширенный поставщик. Если у вас нет установленного Microsoft Enhanced Cryptographic Provider или сертификат X.509 не использует расширенный поставщик, при расшифровке XML-документа будет вызываться исключение CryptographicException с «Неизвестной ошибкой».

Есть ли у вас какие-либо идеи о «Microsoft Enhanced Cryptographic Provider» и «X.509 certificate»? И Может ли моя проблема быть связана с этим?

Причина, по которой функции дешифрования выбрасывает исключение «Bad Data» при попытке расшифровки на другом ПК, заключается в том, что CspParameters привязаны к сеансу на ПК, на котором выполнялось шифрование.

Объект cspParams должен быть встроен и зашифрован в XML, чтобы включить дешифрование на другом ПК. К счастью, EncryptionProperty можно использовать для этого.

 private static MemoryStream EncryptStream(XmlDocument xmlDoc, XmlElement elementToEncrypt, string password) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = password; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); RijndaelManaged sessionKey = null; try { if (xmlDoc == null) throw new ArgumentNullException("xmlDoc"); if (rsaKey == null) throw new ArgumentNullException("rsaKey"); if (elementToEncrypt == null) throw new ArgumentNullException("elementToEncrypt"); sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, rsaKey, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Save some more information about the key using the EncryptionProperty element. // Create a new "EncryptionProperty" XmlElement object. var property = new XmlDocument().CreateElement("EncryptionProperty", EncryptedXml.XmlEncNamespaceUrl); // Set the value of the EncryptionProperty" XmlElement object. property.InnerText = RijndaelManagedEncryption.EncryptRijndael(Convert.ToBase64String(rsaKey.ExportCspBlob(true)), "Your Salt string here"); // Create the EncryptionProperty object using the XmlElement object. var encProperty = new EncryptionProperty(property); // Add the EncryptionProperty object to the EncryptedKey object. ek.AddProperty(encProperty); edElement.KeyInfo = new KeyInfo(); KeyInfoName kin = new KeyInfoName(); kin.Value = KeyName; ek.KeyInfo.AddClause(kin); edElement.CipherData.CipherValue = encryptedElement; edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); if (sessionKey != null) { sessionKey.Clear(); } rsaKey.Clear(); MemoryStream stream = new MemoryStream(); xmlDoc.Save(stream); stream.Position = 0; Encoding encodeing = System.Text.UnicodeEncoding.Default; return stream; } catch (Exception) { if (sessionKey != null) { sessionKey.Clear(); } rsaKey.Clear(); throw; } } private static MemoryStream DecryptStream(XmlDocument xmlDoc, string password) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = password; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); var keyInfo = xmlDoc.GetElementsByTagName("EncryptionProperty")[0].InnerText; rsaKey.ImportCspBlob( Convert.FromBase64String(RijndaelManagedEncryption.DecryptRijndael(keyInfo, "Your Salt string here"))); EncryptedXml exml = null; try { if (xmlDoc == null) throw new ArgumentNullException("xmlDoc"); if (rsaKey == null) throw new ArgumentNullException("rsaKey"); exml = new EncryptedXml(xmlDoc); exml.AddKeyNameMapping(KeyName, rsaKey); exml.DecryptDocument(); rsaKey.Clear(); MemoryStream outStream = new MemoryStream(); xmlDoc.Save(outStream); outStream.Position = 0; return outStream; } catch (Exception) { rsaKey.Clear(); throw; } } 

Изучите class RijndaelManagedEncryption.

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

Для шифрования данных при передаче используйте SSL / TLS. .Net предлагает его SslStream с SslStream . Для WCF см. Как настроить службу WCF с поддержкой IIS с помощью SSL .