2013-03-11 5 views
5

스트림 암호화/암호 해독을위한 코드 블록을 작성했습니다. 코드가 로컬 컴퓨터에서 작동합니다. 내가 웹에 암호 해독 기능을 내 코드를 게시 할 때 여기에 "나쁜 데이터"예외 가 내 Encrypton하고 암호 해독 예외가에 발생합니다EncryptedXml DecryptDocument 메서드가 "잘못된 데이터"예외를 throw합니다.

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 페이지,

는 X.509 인증서로 XML 암호화를 사용하려면 다음과 발언이, 당신은 마이크로 소프트가 강화되어 있어야합니다 Cryptographic Provider가 설치되어 있고 X.509 인증서가 Enhanced Provider를 사용해야합니다. Microsoft Enhanced Cryptographic Provider가 설치되어 있지 않거나 X.509 인증서가 Enhanced Provider를 사용하지 않는 경우 XML 문서의 암호를 해독하면 "알 수없는 오류"가있는 CryptographicException이 throw됩니다.

"Microsoft Enhanced Cryptographic Provider"및 "X.509 certificate"에 대해 알고 있습니까? 내 문제는이 문제와 관련 될 수 있습니까?

+0

웹에있는 KeyName의 값은 무엇입니까? – Smaug

+0

나는 내 컴퓨터에서 똑같은 기능을 시도했지만 시뮬레이션 할 수 없었다. pls는 KeyName 값을 공유합니다 – Smaug

+0

KeyName = "rsaKey"; – srcnaks

답변

1

암호화 프로토콜을 재발 명하지 마십시오. 이 잘못 표시됩니다. 예를 들어 CSPs에 저장된 RSA 키를 잘못 처리하여 모든 컴퓨터에 마술처럼 나타낼 것으로 예상하십시오.

전송할 때 데이터를 암호화하려면 SSL/TLS를 사용하십시오. 닷넷은 SslStream으로 즉시 제공합니다. WCF의 경우 How to: Configure an IIS-hosted WCF service with SSL을 참조하십시오.

+0

답장을 보내 주셔서 감사합니다. 귀하의 권장 사항을 구현할 예정이지만 여전히 SSL 외에 추가 암호화를 구현해야합니다. 그래서 그 문제를 해결해야합니다. 내 문제에 대한 권장 사항이 있습니까? – srcnaks

3

다른 PC에서 해독하려고 할 때 암호 해독 기능이 "잘못된 데이터"예외를 throw하는 이유는 CspParameters가 암호화가 실행 된 PC의 세션에 연결되어 있기 때문입니다.

다른 PC에서 암호 해독을 사용하려면 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; 
    } 
} 

는 RijndaelManagedEncryption 클래스에 대한보고 here 되세요.

관련 문제