2013-03-11 44 views
5

Tôi đã viết một khối mã cho Mã hóa/Giải mã luồng. Mã đang hoạt động trên máy cục bộ của tôi. Nhưng khi tôi xuất bản mã của tôi trên web Các chức năng giải mã ném "Bad dữ liệu" ngoại lệ Đây là Encrypton tôi và giải mã các chức năngEncryptedXml DecryptDocument method ném ngoại lệ "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); 
    } 
} 

ngoại lệ được ném vào "exml.DecryptDocument();" hàng.

Bạn có bất kỳ ý tưởng nào về sự cố và giải pháp không?

Edit:

trong MSDN trang, có nhận xét đó là như sau

Để sử dụng XML Encryption với chứng chỉ X.509, bạn phải có Microsoft nâng cao Nhà cung cấp mật mã được cài đặt và chứng chỉ X.509 phải sử dụng Nhà cung cấp nâng cao. Nếu bạn chưa cài đặt Nhà cung cấp mật mã nâng cao của Microsoft hoặc chứng chỉ X.509 không sử dụng Nhà cung cấp nâng cao, một ngoại lệ mã hóa với "Lỗi không xác định" sẽ được ném ra khi bạn giải mã tài liệu XML.

Bạn có bất kỳ ý tưởng nào về "Nhà cung cấp mật mã nâng cao của Microsoft" và "chứng chỉ X.509" không? Và vấn đề của tôi có liên quan đến vấn đề này không?

+0

Giá trị của KeyName của bạn trong web là bao nhiêu? – Smaug

+0

Tôi đã thử cùng một máy tính của tôi, tôi cũng không thể mô phỏng. xin chia sẻ giá trị KeyName – Smaug

+0

KeyName = "rsaKey"; – srcnaks

Trả lời

1

Không tạo lại các giao thức mã hóa. Bạn sẽ gặp sai. Trường hợp tại điểm, xử lý sai khóa RSA được lưu trữ trong CSPs và mong đợi chúng xuất hiện kỳ ​​diệu trên bất kỳ máy nào.

Để mã hóa dữ liệu khi truyền, hãy sử dụng SSL/TLS. .Net cung cấp nó out-of-the-box với SslStream. Đối với WCF, hãy xem How to: Configure an IIS-hosted WCF service with SSL.

+0

Cảm ơn bạn đã trả lời, tôi sẽ triển khai đề xuất của bạn nhưng tôi vẫn cần triển khai mã hóa bổ sung ngoài ssl. Vì vậy, tôi phải giải quyết vấn đề đó. Bạn có đề xuất nào cho vấn đề của tôi không? – srcnaks

3

Lý do hàm giải mã ném ngoại lệ "Dữ liệu xấu" khi cố gắng Giải mã trên máy tính khác là CspParameters được liên kết với phiên trên PC nơi Mã hóa được chạy.

Đối tượng cspParams sẽ cần được nhúng và mã hóa trong XML để bật Giải mã trên máy tính khác. May mắn thay có EncryptionProperty chúng ta có thể sử dụng cho việc này.

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; 
    } 
} 

Có giao diện here cho lớp RijndaelManagedEncryption.