为什么此加密邮件已损坏?

时间:2012-06-19 06:05:23

标签: c# .net wcf encryption

我在安全网站问了this问题,那里的人建议我应该在这里发帖。

一些背景知识。我们拥有专有设备,可通过专有操作系统和其他在Windows操作系统上运行c#dll的设备运行。 两者都通过TCP连接联系我们的服务器,对于我们的服务器,两种类型的请求是相同的。 TCP服务器通过http绑定将部分请求传输到自托管WCF服务。 请求已加密,如链接中所示(如C#dll加密它们)。

我正在尝试切断TCP服务器并直接向WCF服务发送请求。

我的问题是看起来WCF服务收到请求字符串错误,并且无法解密它。

似乎服务器端还有额外的\ t \ n接收字符串。除此之外它看起来一样。

这是服务器端的解密代码:

            byte[] byteChiperText = Encoding.Default.GetBytes(input);

            if (k.Length != 16)
            {
                throw new Exception("Wrong key size exception");
            }
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.Zeros;
            des.Key = k;
            ICryptoTransform ic = des.CreateDecryptor();
            MemoryStream ms = new MemoryStream(byteChiperText);
            CryptoStream cStream = new CryptoStream(ms,
                 ic,
                 CryptoStreamMode.Read);
            StreamReader sReader = new StreamReader(cStream);
            byte[] data = new byte[byteChiperText.Length];
            int len = sReader.BaseStream.Read(data, 0, data.Length);
            output = Encoding.Default.GetString(data, 0, len);

            cStream.Close();

2 个答案:

答案 0 :(得分:6)

这一切看起来很糟糕:

byte[] byteChiperText = Encoding.Default.GetBytes(input);

您将加密数据视为使用平台默认编码进行编码的文本。这是丢失数据的好方法。加密数据不是文本。它是任意的二进制数据,应该这样对待。

相反,您应该使用base64将加密数据编码为文本(Convert.ToBase64String),然后稍后将其反转(Convert.FromBase64String)以返回到原始密文。当然,这是假设您需要以文本形式开始。如果您可以首先将其作为byte[]传递,那就更好了。

另请注意,您获取文本的方法有点奇怪 - 您正在创建StreamReader,然后仅使用基本流。最好使用:

// You should be using "using" statements for all your streams, by the way...
using (TextReader reader = new StreamReader(cStream))
{
    output = reader.ReadToEnd();
}

请注意,这将使用UTF-8而不是平台默认编码 - 但这是良好的事物,只要您在加密代码中进行相应的更改即可。使用平台默认编码几乎总是一个错误 - 它可能不支持所有Unicode,并且因机器而异。

答案 1 :(得分:2)

问题可能出在Encoding.Default,因为:

  

不同的计算机可以使用不同的编码作为默认编码。

您应该使用给定的标准编码(UTF-8,UTF-16,..)。