Network traffic Encryption without Certificates - c#

I'm tasked with encryption of the network communication of our program and I've been thrown a wrench. I was going to use SslStream but my CTO would like to stay away from managing certificates. So I was wondering is there any other Stream that will encrypt data, or a way to dynamically generate certificates?

You could encrypt your data using a standard encryption algoithm (RSA, AES, PGP, etc.) as long as you control both endpoints. If not, you will need to use something like certificates since clients won't be able to otherwise decrypt. I'm not sure why your CTO would avoid certs, but nonetheless...
See this article for a good start: http://msdn.microsoft.com/en-us/library/0ss79b2x.aspx
Also note that WCF supports MANY means of communication encryption, many of which do not require certs.
WCF netTCPBinding - Is transport encryption enough?
Note finally that you cannot encrypt the message headers if you don't talk directly to the other party (ie: if there's anyone in the middle), since the middle part won't be able to decipher/route your message.

Related

How to create a stateful encrypted connection between two C# applications?

I am currently looking for the best way to establish a stateful and encrypted connection between a C# client and server application. First, I thought about using IPsec, but as it works on a low level (OSI: Internet Layer), I would be very hard to implement, if you want the functionality inside your program and don't want to rely on the OS.
What technologies would you recommend for this purpose? Is there some functionality already built into .NET (4.5)? It does not neccessarily have to be stateful, working with some kind of heartbeat would be a valid option, too.
You'll want to use a standard protocol such as SSL rather than trying to make your own. First the implementation will be much easier because the .NET framework will support it, and the transport protocol that runs underneath it is stateful (e.g. TCP). Second developing a cryptographic protocol that is secure is very difficult, and SSL has already been implemented so why reinvent the wheel?
SSL works by using PKI (Public Key Infrastructure) to generate a shared symmetric key. The handshake consists of a number of steps. First the client sends a request for a secure session, then the server responds with it's certificate, the client verifies the certificate by crawling up the ladder through the certificate authorities (e.g. Verisign, Thawte, GeoTrust etc...) or if it already trusts the server it can just accept the certificate that is self signed.... and once it finds the certificate is trustworthy it generates a symmetric key and picks an algorithm (e.g. AES, 3DES, RC4, IDEA etc...). The client then encrypts the key and algorithm being used with the public key, then the client sends that value to the server and a secure session can proceed using symmetric encryption which is much faster.
SSL itself is can be used in a stateful manner because it actually works over the transport layer in the OSI Model, HTTPS on the other hand is not a stateful protocol by design. HTTPS is HTTP over SSL so the two technically don't really have anything to do with each other, except that in HTTPS SSL is used to secure the application data that is being requested. With HTTPS as with HTTP once a request is made to the server it basically forgets about you (not exactly how it happens but for all intents and purposes you can think of it this way). I myself would prefer the use of HTTPS if you can get around having to have a stateful protocol. The main reason for doing so is so that I wouldn't have to write the code and possibly have a mistake in the implementation of SSL. All you have to do is build a WCF or REST based service that runs on IIS and get a certificate for your server.
That being said, if you still want to create your own SSL server that doesn't use HTTP on the application level you can use the TcpListener and TcpClient classes along with the SslStream class provided as part of .NET to create your own. MSDN has a good example of how to create an SSL server and client: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream%28v=vs.110%29.aspx
Side Notes
Securing the transport of your data does not secure your app, do not make the mistake of thinking you get automatic security
If you choose to make your own server and client you can use either openssl to generate your certificate or you can use makecert which is part of .NET to make your certificate.
Just form a regular TCP connection between the applications, and write up a simple packet protocol (EG, 4 bytes indicate packet size, followed by packet data)
Except the data within this base-level packet is encrypted through System.Cryptography.AesManaged
If you have trouble encrypting the packets using AesManaged, try using The Encryptamajig - if that doesn't help, post further questions and we'll give you further specific help.
-- You can either have both sides know the password ahead of time (EG, tell the person at the other end the password in person), or quickly pass it unencrypted at the start of the connection (or, rather, encrypted with a default known password)
Not necessarily the best method but it should do the job.
Why not just the regular HTTPS? HTTP is just one level above TCP but it is far easier to work with and firewalls tend to be generally easy on HTTP/HTTPS ports namely 80 and 443. Of course, plain HTTP is not suitable for you but can you not use HTTPS instead of coming up with your own encrypted communication mechanism? In the client side (C#), all .NET classes such as HttpClient supports HTTPS very well. I quote Ayende in support of my suggestion to go with HTTP :)

C# Relay on SslStream for Encryption

Can i relay on SslStream to encrypt all my sent&received data so i don't have to hash the data or add any other encryption algorithm ?
From MSDN:
Provides a stream used for client-server communication that uses the
Secure Socket Layer (SSL) security protocol to authenticate the server
and optionally the client.
So, on the surface, SSL's function is to provide an encrypted tunnel between client and server. When properly implemented, SSL is considered to be "secure enough" for most operations. This means that you should not need an additional layer of security. However, it also depends upon your application.
I would also like to address another part of your question. "So I don't have to hash the data" - if you hash the data, you are not encrypting it. You are performing a one-way operation that essentially destroys the original data when you send it. Hashes are typically used to see if two or more pieces of data are the same; they cannot be used for symmetric encryption/decryption.

Can I treat CryptoStream as a replacement for SslStream?

I need to send data between SilverLight applications. I've got requirement that says that data should be transmitted using secure protocol such as SSL/TLS. Data is sent using TCP sockets due to performance reasons. Unfortunately SilverLight doesn't support SslStream. If I want to transmit data over SSL/TLS I need to buy third party library e.g. SecureBlackbox. I don't want to be dependent on third party libraries when it comes to handling transport layer.
However, SilverLight has CryptoStream class. I'm thinking of exchanging the key for symmetric encryption using WCF over SSL (SilverLight supports that) and then encrypt the data with AES using CryptoStream.
Is this solution safe? Can it be compared to using SSL/TLS in terms of security? Is there some obvious security hole that I'm missing?
I guess the main problems with the AES approach is key management and key verification. I'm sure you know that SSL uses a 'handshake', which uses a CA chain (Certificate Authority) to verify the validity of the SSL certificate. This all happens before an AES key is generated for the SSL session. So, by not using SSL, you miss this important step.
This means that you take on the responsibility for verifying that the keys are secure and exchanged in a secure manner.

Flash & C# encryption

I am creating a TCP connect with Flash to a C# daemon.
Now I have come to the part of encryption... I know that Flash is decompilable and so not safe to store private keys on.
I need 2 way encryption because of the messages that have to be send back to the Flash client.
I have been thinking and googling, but cannot find a proper solution yet.
Anybody got an idea??
You'd usually use a hybrid encryption.
Client opens a session on the server, acquiring public key for an asymmetric encryption.
Client generates a key for a symmetric encryption, and sends this key to the server, encrypted with the public key previously acquired.
The rest of the communication is encrypted using a symmetric encryption with they key now known to both client and server.
greetz
back2dos
back2dos' solution will work (and be the easiest) if your connection is SSL/TLS.
If you are forced to use regular sockets (e.g., the server does not have an SSL certificate), then you'll need to do the same by hand. In this case, you'll need to use a Diffie-Hellman key exchange, which enables the creation of a shared secret that is not actually sent over the wire.
Again, if possible, use back2dos' solution. It's a lot easier.

Is it possible to enforce web service calls from known client only?

Scenario:
A publically available Web Service that I have full control over.
But I only want this specific desktop application (my published application) to have access to the Web Service.
I could store a secret password in the desktop client, but that would be easy to crack.
Is there any known implementation that enforces this?
PKI, assymmetric keys?
If the public will have access to copies of this Desktop App, any good reverser will be able to crack it and "imitate" its transactions with the server. It doens't matter how secure is your cryptography, everything you app needs to encrypt/decrypt data is included in the binaries, so the cracker only needs to dig it out of it.
The objective of cryptography is to protect data while it is being transfered, from "middle-man" hackers, but if you have access to anyone of the peers, you can easily crack it.
Your server must never trust what comes from the client side.
[edit resuming]
Despite you cannot 100% guarantee a supposed client to your server is or isn't your App or some "emulator" made by thirdies, you can complicate things to them. Its a common practice in game anti-cheats to sometimes, randomly, make the client App a trick question like "whats the hash of your main.exe from offset A to offset B?" or "from now on packet type 0x07 swaps with packet type 0x5f". Once a fake is detected, server enter in a "silly mode", act malfunctional, and blacklist their IP/account to this mode for several hours so they cannot have sure of what their program is doing wrong.
If you detect someone is building an emulator, make them start all over again: jumble the packet type tables, cryptography tables, change some packet formats and force your clients to update. You won't see crackers bothering you for a while... LOL
WS-Security provides for X509 encryption.
Part of that implementation includes the possibility of only giving specific clients the generated public key. That way, only your selected clients can connect to the service.
The easiest way is message security using client and server certificates. The best way is to import the client certs in your server machines and hard code the client cert thumbprint in the app.config file. The other way is negotiation of certs which I haven't tried before.
If you are using IIS to host the service then client certificates using SSL is another option.
MSDN link on WCF Security.

Categories