【问题标题】:Illegal Hex Chars in XML after encryption & decryption加密和解密后 XML 中的非法十六进制字符
【发布时间】: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

提前致谢

【问题讨论】:

    标签: c# .net xml wcf security


    【解决方案1】:

    撇开您的安全方法不谈,核心问题是您无法在 XML 文档中拥有所需的所有字符。要解决此问题,您应该在写入 XML (example) 之前使用 Base64 对加密文本进行编码。不要使用任何正则表达式,因为这会更改密码文本,这意味着您将无法解密它。

    发件人

    • 加密消息 (string -> byte[])
    • Base64 编码 (byte[] -> string)
    • 写入 xml

    接收者

    • 从 xml 读取 (string)
    • 从 Base64 解码 (string -> byte[])
    • 解密 (byte[] -> string)

    【讨论】:

      猜你喜欢
      • 2015-01-01
      • 1970-01-01
      • 2015-10-28
      • 2022-09-28
      • 2017-05-07
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      相关资源
      最近更新 更多