【发布时间】:2014-07-03 11:10:29
【问题描述】:
由于某些原因,我必须使用两种方式手动加密 WCF 消息,并且我不能使用 WCF 的默认内置安全机制。
没有加密,一切正常,但加密后,我在 WCF XML 消息中看到一些非法字符。
如果我用正则表达式删除那些非法字符,一切都会再次正常,即使是加密。
问题:
我的加密出了什么问题?
加密:
public override ArraySegment<Byte> WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
{
Int32 messageLength;
Byte[] messageBytes;
using (MemoryStream unEncryptedXmlStream = new MemoryStream())
{
using (XmlWriter writer = XmlWriter.Create(unEncryptedXmlStream))
{
message.WriteMessage(writer);
}
using (Rijndael crypObj = Rijndael.Create())
{
crypObj.IV = UTF8Encoding.Default.GetBytes("1234567890123456");
crypObj.Key = UTF8Encoding.Default.GetBytes("1234567890123456");
using (MemoryStream encryptedStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(encryptedStream, crypObj.CreateEncryptor(), CryptoStreamMode.Write))
{
unEncryptedXmlStream.Position = 0;
cryptoStream.Write(unEncryptedXmlStream.ToArray(), 0, (Int32)unEncryptedXmlStream.Length);
cryptoStream.FlushFinalBlock();
messageBytes = encryptedStream.ToArray();
messageLength = (Int32)encryptedStream.Position;
}
}
}
}
Int32 totalLength = messageLength + messageOffset;
Byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
ArraySegment<Byte> byteArray = new ArraySegment<Byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
解密:
public override Message ReadMessage(Stream stream, Int32 maxSizeOfHeaders, String contentType)
{
Stream encryptedXmlStream = stream;
XElement reader = null;
encryptedXmlStream.Position = 0;
using (Rijndael crypObj = Rijndael.Create())
{
crypObj.IV = UTF8Encoding.Default.GetBytes("1234567890123456");
crypObj.Key = UTF8Encoding.Default.GetBytes("1234567890123456");
using (CryptoStream cryptoStream = new CryptoStream(encryptedXmlStream, crypObj.CreateDecryptor(), CryptoStreamMode.Read))
{
Byte[] buffer = new Byte[(Int32)encryptedXmlStream.Length];
cryptoStream.Read(buffer, 0, (Int32)encryptedXmlStream.Length);
//reader = XElement.Parse(Encoding.UTF8.GetString(buffer)); // exception
reader = XElement.Parse(CleanInvalidXmlChars(Encoding.UTF8.GetString(buffer))); // everything works fine again, even with encryption & decryption
}
}
String action = reader.Descendants()
.First(element => element.Name.LocalName == "Action").Value;
return Message.CreateMessage(MessageVersion, action, reader.Descendants()
.First(element => element.Name.LocalName == "Body").Elements().Single().CreateReader());
}
删除非法字符:
private static String CleanInvalidXmlChars(String input)
{
String pattern = @"[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]";
return Regex.Replace(input, pattern, "");
}
易于调试和测试控制台应用程序:
https://drive.google.com/file/d/0B8_dFKbcEQ47b2VnSG0zcTZiRlk/edit?usp=sharing
要下载,请按 Ctrl+S
提前致谢
【问题讨论】: