I asked this question over Security site, and people there suggested I should have posted it here.
Some background. We have proprietary devices which run c over a proprietary OS and other devices which run a c# dll over a windows OS.
Both contact our Server via TCP connection, for our server both type of requests are the same.
The TCP server transfers part of the request to a self-hosted WCF service, through http-binding.
The requests are encrypted as shown in the link(like the C# dll encrypts them).
I am in the process of trying to cut off the TCP server and send requests straight to the WCF service.
My problem is that it seems like the WCF service receives the request string wrong, and it can’t decrypt it.
It seems like there are additional \t \n in the server side receives string. other than that it looks the same.
This is the decryption code on the server side:
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();
Well this looks broken to start with:
You’re treating encrypted data as if it’s text encoded with the platform default encoding. That’s a great way to lose data. Encrypted data isn’t text. It’s arbitrary binary data, and should be treated as such.
Instead, you should use base64 to encode the encrypted data as text (
Convert.ToBase64String) and then reverse that (Convert.FromBase64String) later on to get back to the original cypher-text. That’s assuming you need it in text form to start with, of course. If you can pass it as abyte[]in the first place, that would be even better.Also note that your approach to getting the text out is somewhat odd – you’re creating a
StreamReader, then only using the base stream. It would be better to use:Note that this will use UTF-8 rather than the platform default encoding – but that’s a good thing, so long as you make the corresponding change in the encryption code. Using the platform default encoding is almost always a mistake – it may well not support all of Unicode, and it varies from machine to machine.