2013-03-11 8 views
5

Ho scritto un blocco di codice per Encrypt/Decrypt Streams. Il codice funziona nel mio computer locale. Ma quando pubblico il mio codice sul web Le funzioni decrittografia getta "Bad Data" eccezione Ecco la mia Encrypton e decrittografia funzionaIl metodo EncryptedXml DecryptDocument genera l'eccezione "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); 
    } 
} 

l'eccezione viene generata su "exml.DecryptDocument();" linea.

Avete qualche idea sul problema e sulla soluzione?

Edit:

in MSDN pagina, c'è un'osservazione che è la seguente

Per utilizzare la crittografia XML con certificati X.509, è necessario che il Microsoft Enhanced Provider di crittografia installato e il certificato X.509 deve utilizzare il provider avanzato. Se non si dispone del provider di crittografia avanzato o del certificato X.509 non viene utilizzato il provider avanzato, verrà generato un errore sconosciuto di con un "errore sconosciuto" quando si decodifica un documento XML .

Avete qualche idea su "Microsoft Enhanced Cryptographic Provider" e "X.509 certificate"? E il mio problema può essere collegato a questo?

+0

qual è il valore del tuo KeyName nel Web? – Smaug

+0

Ho provato lo stesso nella mia macchina anche io non potevo simulare. pls condivide il valore KeyName – Smaug

+0

KeyName = "rsaKey"; – srcnaks

risposta

1

Non reinventare i protocolli di crittografia. Ti sarà sbagliato. Caso in questione, maltrattare la chiave RSA memorizzata nello CSPs e aspettarsi che vengano visualizzate magicamente su qualsiasi macchina.

Per crittografare i dati nel trasferimento, utilizzare SSL/TLS. .Net lo offre immediatamente con SslStream. Per WCF vedere How to: Configure an IIS-hosted WCF service with SSL.

+0

Grazie per la risposta, implementerò la tua raccomandazione, ma ho ancora bisogno di implementare ulteriore crittografia oltre allo ssl. Quindi devo risolvere il problema. Avete qualche raccomandazione per il mio problema? – srcnaks

3

Il motivo per cui la funzione di decrittografia genera un'eccezione "Dati non validi" quando si tenta di decrittografare su un altro PC è che CspParameters è collegato alla sessione sul PC su cui è stata eseguita la crittografia.

L'oggetto cspParams dovrà essere incorporato e crittografato nell'XML per abilitare Decryption su un altro PC. Fortunatamente esiste la proprietà EncryptionProperty che possiamo usare per questo.

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

Date un'occhiata here per la classe RijndaelManagedEncryption.

Problemi correlati