I will like to create a service with custom authentication. The way I will like to authenticate users is as:
Client connects to service.
Service generates a random number lets say 1234 and sends that number to client
Client then is supposed to add the numbers (Latter I will use a better hash) so the client sends 10
The Server performs the same hash algorithm and expects to receive 10
server received 10 it then authenticates the user and the user is able to start consuming the service.
I have some basic question though. If I uses security = "none" then will the messages be encrypted? In other words if I use security = "none" I know that the user will not have to be authenticated but are the messages sent to the service in plain text? How can I force the connection to be encrypted without having to authenticate the user? I will like to restrict users from sniffing packages. I don't mind them connecting to the service. If they connect to that service I will only want to let them see the messages they send but not other's people messages.
For encrypted communication with server without authenticating the user you can use Transport or Message level security.
Refet to the following articles for details:
patterns & practices Improving Web Services Security Guide
Transport Level Security
Configuring HTTP and HTTPS
Bindings and Security
And a general advise: don't invent your own authorization/authentication/encryption protocols, unless you are one of the greatest information security/crypthography experts in the world. Use the protocols already present on the market.
What have you described is not a handshake at all, since it's protected only by the fact, that an attacker does not now your hash function. Such an assumption considered quite bad basement for the cryptographic/authentication protocol.
Related
We have a desktop application that needs to send emails on behalf of our clients (institutions), to our client's clients (real people).
After investigating about creating an intermediate web service that will hold our secret key, and retrieve oauth2 tokens on demand from the desktop app, then the desktop app uses that token to make google api calls to send emails.
I've come to the bulk mail guidelines
and I'm afraid the mails would get marked as spam (as they will have different senders)
We need to make something like thunderbird but only for sending notification mails.
Is there any other way to do this? How so?
Using Gmail for this is NOT going to go well.
Instead, as you are working on behalf of institutions you will do better to pick one of two options:
Require your clients to provide credentials for their own smtp servers as part of the setup process for the application.
Run your own smtp server (which is NOT trivial, but still doable) and require your clients to include your server's address in the appropriate places in their DNS so your server shows as legitimate sender for their domain.
As the main systems administrator at a small college, I've had to do both kinds of setup for various applications.
If you go option 2, get a real server with a real IP. I've had application vendors request to add SPF records for whole AWS ranges, and I am NOT going to approve that.
I have a Client & Server application set, both written in C# but some client versions might be distributed in other languages in the future. I want to protect my applications.
I was looking for some kind of advice to stop just random people sending messages to a server and acting like a client, what kind of validation can I put in place?
My client applications I distribute will be obfuscated but is this enough? I'm just looking for some advice in this situation, is it wise for me to add some kind of encryption other than SSL, or am I just being over protective and over curious? Any input is welcomed & accepted.
It is impossible to determine if you are communicating remotely with "your client" or another piece of software that also knows how to communicate in the way that your client does.
What you can do is ensure that you are communicating with someone that is authorized to communicate with you by using client certificates for your SSL session.
The server proves who it is to the client and the client proves who it is to your server. The security then rests in whoever holds the private key to the client certificate (and the password for this key file).
The C# SslStream Class has support for this. Namely the AuthenticateAsClient method is relevant here.
In summary, if your software is only secure when communicating with a client you wrote, then your software isn't secure period. Instead, design your server in such a way that you can serve client requests securely. Using authentication is one of these ways.
You would want to do two things....one is look up certificate pinning. Your app will validate your SSL cert to thwart man in the middle attacks and it makes it hard to circumvent. The other is when making requests to the server have some type of user name / password block on the server side script before the server side does anything so the requests will simply be discarded by the server if they are from an unknown source.
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 :)
I have a WCF service accessible over the Internet. It has wsHttpBinding binding and message security mode with username credentials to authenticate clients.
The msdn says that we should use message security for the Internet scenarios, because it provides end-to-end security instead of point-to-point security as Transport security has.
What if i use transport security for the wcf service over the Internet? Is it a bad practice? Could my data be seen by malicious users?
No, it would be a good practice - trouble is: you cannot guarantee a complete chain of secure connections over an arbitrary number of intermediate hops when you're dealing with an internet connection.
All you can guarantee with transport security is the link from your client to the first hop, and the link from the last hop to your server - anything in between is beyond your control. So basically, transport security over the internet is not going to work - unless you have a strictly controlled environment where you know the client connects very directly to your servers.
Due to those technical limitations, transport security only really works in corporate / LAN environments. As soon as you have no control over the routing and the intermediary hops, you need to use message security for an end-to-end security.
Yes it is 100% secure when the clients (which most clients do) validate the server certificate.
The multiple hop scenario mentioned here is complete bogus. This is only true when the same message travels through various applications. Like for example several application brokers. If these brokers do not communicate securely then the message can be read by intermediate network sniffers.
In other words, client/server communication over the internet is 100% secure even when there are a million routers in between but it is only secure when the client validates the server certificate as the client could connect to a man-in-the-middle host that could impersonate the server with a false certificate. If the client does not validate the certificate the message could be compromised.
IMO it may not be 100%
If BlueCoat can do it, then who else can?
http://directorblue.blogspot.com/2006/07/think-your-ssl-traffic-is-secure-if.html
I am about to start on a project that will be running as a windows service listening for incoming connections and doing some things locally then sending a reply message. I understand the basic concepts with sockets and communicating over the network, however the things the service are doing could very easily abused. I would like to authenticate the person connecting, preferably against the windows local users on the machine the service is running, to see if they have windows administrative/power user rights.
I know how to do it check the rights once I have their information but I know sending the user name and password to the application over the network in the clear is a no no. I was thinking of just encrypting the password with some secret key but I know "trying to be clever" is the worst possible thing you can do in cryptography so I wanted to know what is the "correct" way to handle this situation.
My second idea was just create a shared self signed certificate between the client and the server and just use TLS for the entire connection.
I may as well post what I was thinking of doing, if it is the right thing to do say so in the comments.
Both the client and server will have a PSK at run-time the server will send a random number to the client. the client will encrypt the credentials with the PSK and the random number as the IV. It will send back the encrypted blob plus whatever commands it needs done.
I am not concerned about replay or mitm attacks. I just want to authenticate the user and not have peoples passwords blasted all over the network.
Scott,
this may be a bit overkill and a bit off topic, but have you considered using a web service interface to serve your clients (instead of using raw sockets)?
ASP .Net web service interfaces are easy to implement, and in the end, you'll end up with a very well defined interface. They also have support for authentication and secure communication.
ASP .Net Web Service Tutorial
HTTP Security and ASP.NET Web Services