2013-03-11 3 views
5

Ich habe einen Codeblock für Encrypt/Decrypt Streams geschrieben. Der Code funktioniert in meinem lokalen Computer. Aber wenn ich meinen Code auf Web Die Entschlüsselungsfunktionen veröffentlichen wirft „Bad Data“ Ausnahme Hier die meine Encrypton und EntschlüsselungsfunktionenEncryptedXml DecryptDocument-Methode löst "Bad Data" -Ausnahme aus

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

die Ausnahme auf geworfen wird „exml.DecryptDocument();“ Linie.

Haben Sie eine Idee über das Problem und die Lösung?

Edit:

in MSDN Seite gibt es Bemerkung, die als

folgt zu verwenden XML-Verschlüsselung mit X.509-Zertifikaten, müssen Sie die Microsoft Verbesserte Der Cryptographic Provider muss installiert sein und das X.509 Zertifikat muss den Enhanced Provider verwenden. Wenn Sie den Microsoft Enhanced Cryptographic Provider nicht installiert haben oder das X.509 -Zertifikat den erweiterten Anbieter nicht verwendet, wird beim Entschlüsseln eines XML-Dokuments eine CryptographicException mit einem "Unbekannten Fehler" ausgelöst.

Haben Sie eine Vorstellung von "Microsoft Enhanced Cryptographic Provider" und "X.509-Zertifikat"? Und kann mein Problem damit verwandt sein?

+0

Welchen Wert hat Ihr KeyName im Web? – Smaug

+0

Ich versuchte das gleiche in meiner Maschine auch ich konnte nicht simulieren. pls teilen den KeyName-Wert – Smaug

+0

KeyName = "rsaKey"; – srcnaks

Antwort

1

Kryptografieprotokolle nicht neu erfinden. Sie werden es falsch verstehen. Ein Beispiel dafür ist, dass Sie den im CSPs gespeicherten RSA-Schlüssel falsch handhaben und erwarten, dass er auf jeder Maschine magisch erscheint.

Verwenden Sie zum Verschlüsseln von Daten bei der Übertragung SSL/TLS. .Net bietet es out-of-the-box mit SslStream. Für WCF siehe How to: Configure an IIS-hosted WCF service with SSL.

+0

Vielen Dank für Ihre Antwort, ich werde Ihre Empfehlung implementieren, aber ich muss noch zusätzliche Verschlüsselung zusätzlich zu der SSL implementieren. Also muss ich dieses Problem lösen. Haben Sie eine Empfehlung für mein Problem? – srcnaks

3

Der Grund, warum die Entschlüsselungsfunktionen beim Versuch, auf einem anderen PC zu entschlüsseln, die Ausnahme "Ungültige Daten" auslöst, ist, dass CspParameters mit der Sitzung auf dem PC verbunden ist, auf dem die Verschlüsselung ausgeführt wurde.

Das cspParams-Objekt muss in das XML eingebettet und verschlüsselt werden, um die Entschlüsselung auf einem anderen PC zu ermöglichen. Zum Glück gibt es EncryptionProperty, die wir dafür verwenden können.

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

Werfen Sie einen Blick here für die RijndaelManagedEncryption Klasse.

Verwandte Themen