我在安全网站问了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();
答案 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)