我问了this安全网站上的问题,那里的人建议我应该把它张贴在这里。
一些背景。我们拥有在专有操作系统上运行 c 的专有设备,以及在 Windows 操作系统上运行 c# dll 的其他设备。 两者都通过 TCP 连接联系我们的服务器,对于我们的服务器来说,两种类型的请求是相同的。 TCP 服务器通过 http 绑定(bind)将部分请求传输到自托管 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();
最佳答案
好吧,这看起来很糟糕:
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,并且因机器而异。
关于c# - 为什么这个加密的消息损坏了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11095272/