I want to create new WCF service and client. The 2 parties will communicate using 2-way SSL.
I want to use the SSL only for the authentication phase. After this authentication, the encryption is not necessary. Can I configure my service (and client) to use SSL only for authentication and leave the connection unencrypted (performance issue)?
Why would you want to leave the connection unencrypted after authentication?
The username and password will be passed via the network one way or another so you should consider encrypting the connection all the time to avoid leaking that information.
Edit:
If you are using a certificate it has to be encrypted all the time, since I know you can't do authentication with a certificate and then get back to simple HTTP.
WCF need to authenticate the client for every request (if it wasn't like that client could get a certificate for a moment then delete it and use your WCF service like nothing happened because authentication will not be needed anymore which is abnormal in your situation).
If you want to perform authentication with a client certificate (what I presume you mean with "2-way" SSL), you could use a cipher suite with NULL encryption, e.g. TLS_RSA_WITH_NULL_SHA.
Otherwise, if your authentication scheme is part of the application layer on top of SSL/TLS, you should certainly consider using encryption.
Note that using TLS_RSA_WITH_NULL_SHA will still proceed with the RSA key exchange in the handshake (even if no shared encryption key is actually used in the end). The SSL/TLS handshake is the most computationally intensive part of using SSL/TLS. The actual encryption shouldn't impact the performance nearly as much, so you might as well leave it on.
Related
I asked a question here a while back on how to hide my http request calls and make them more secure in my application. I did not want people to use fiddler 2 to see the call and set up an auto responder. Everyone told me to go SSL and calls will be hidden and information kept safe.
I bought and installed an SSL Certificate and got everything set up. I booted up fiddler 2 and ran a test application that connect to an https web service as well as connected to an https php script.
Fiddler 2 was able to not only detect both requests, but decrypt them as well! I was able to see all information going back and fourth, which brings me to my question.
What is the point of having SSL if it made zero difference to security. With or without SSL I can see all information going back and fourth and STILL set up an auto responder.
Is there something in .NET I am missing to better hide my calls going over SSL?
EDIT
I am adding a new part to this question due to some of the responses I have received. What if an app connects to a web service to login. The app sends the web service a username and a password. The web service then sends data back to the app saying good login data or bad. Even if going over SSL the person using fiddler 2 could just set up an auto responder and the application is then "cracked". I understand how it could be useful to see the data in debugging, but my question is what exactly should one do to make sure the SSL is connecting to the one it was requesting. Basically saying there cannot be a middle man.
This is covered here: http://www.fiddlerbook.com/fiddler/help/httpsdecryption.asp
Fiddler2 relies on a "man-in-the-middle" approach to HTTPS interception. To your web browser, Fiddler2 claims to be the secure web server, and to the web server, Fiddler2 mimics the web browser. In order to pretend to be the web server, Fiddler2 dynamically generates a HTTPS certificate.
Essentially, you manually trust whatever certificate Fiddler provides, the same will be true if you manually accept certificate from random person that does not match domain name.
EDIT:
There are ways to prevent Fiddler/man-in-the-middle attack - i.e. in custom application, using SSL, one can require particular certificates to be used for communication. In case of browsers, they have UI to notify user of certificate mismatch, but eventually allow such communication.
As a publicly available sample for explicit certificates, you can try to use Azure services (i.e. with PowerShell tools for Azure) and sniff traffic with Fiddler. It fails due to explicit cert requirement.
You could set up your web-service to require a Client-side certification for SSL authentication, as well as the server side. This way Fiddler wouldn't be able to connect to your service. Only your application, which has the required certificate would be able to connect.
Of course, then you have the problem of how to protect the certificate within the app, but you've got that problem now with your username & password, anyway. Someone who really wants to crack your app could have a go with Reflector, or even do a memory search for the private key associated with the client-side cert.
There's no real way to make this 100% bullet proof. It's the same problem the movie industry has with securing DVD content. If you've got software capable of decrypting the DVD and playing back the content, then someone can do a memory dump while that software is in action and find the decryption key.
The point of SSL/TLS in general is so that the occasional eavesdropper with Wireshark isn't able to see your payloads. Fiddler/Burp means that you interacted with the system. Yes, it is a very simple interaction, but it does require (one) of the systems to be compromised.
If you want to enhance the security by rendering these MITM programs useless at such a basic level, you would require client certificate authentication (2-way SSL) and pin both the server and client certificates (e.g. require that only the particular certificate is valid for the comms). You would also encrypt the payloads transferred on the wire with the public keys of each party, and ensure that the private keys only reside on the systems they belong to. This way even if one party (Bob) is compromised the attacker can only see what is sent to Bob, and not what Bob sent to Alice.
You would then take the encrypted payloads and sign the data with a verifiable certificate to ensure the data has not been tampered with (there is a lot of debate on whether to encrypt first or sign first, btw).
On top of that, you can hash the signature using several passes of something like sha2 to ensure the signature is 'as-sent' (although this is largely an obscure step).
This would get you about as far in the security way as achievable reasonably when you do not control (one) of the communicating systems.
As others mentioned, if an attacker controls the system, they control the RAM and can modify all method calls in memory.
I know that their are questions and articles about WCF deployment, but i don't find one that actually solves my issue.
So i have a WCF service that is going to be used over tcp. If i set the security to transport, then i am obligated to use for usercredentials certificate or Windows. I don't want to use a certificate but i can't be sure that the service will always be hosted in a windows domain. So it leaves me with certificate security. I know that i can create a certificate with makecert, but what must i do when i want to deploy the service onto a server? Do i only need a certificate for the service or also the client that connects needs one?
Also if use message security, i need to have a certificate for the service.
EDIT,
In intranet scenarios, is it ok to use self signed certificates?
I didn't know myself, was just looking here:
WCF easiest security mode to implement
one of the best comments I think, in regards do just checking user/pass on both sides of the wire:
Such solution will not be secure. You talking about symmetric encryption where all clients and server has to share same key. Once any client get compromissed (and key is stolen or shared with anybody else) the security is gone. User name and password has nothing to do with encryption. – Ladislav Mrnka
You may be able to do it, but it might overlook the bigger question: why choose this route in the first place?
Here's some code for plaintext passwords if you really want to go down that route....
http://webservices20.blogspot.com/2008/11/how-to-use-clear-usernamepassword-with.html
I am developing web services using the servicestack.net library.
In my scenario, the web services will be called from a WPF application. I need the ability to authenticate that only an approved client app is calling my service.
Is this as simple as hardcoding a "username" and "password" in the client application? This certainly does not seem like the proper approach. Is there a better way?
EDIT
In addition, on the client end, Users themselves will be able to login with a username/password and initiate requests to the service(not sure if this effects anything, so I thought I would mention it),
For more background information about Authentication in ServiceStack see this question.
Normally you would authenticate users not clients which you seem to be doing in addition. But if you're trying to lock down services so their only accessible via a specific set of clients you should look into employing some PKI into your client and server.
Basically something along the lines of: the client sends an additional token at login with an encrypted version of the user:password together with a private key embedded in the app. The server has the client public key and so would do un extra validation step on Login to unencrypt the user:pass token and compare it with the validated user credentials.
If a PKI solution is too heavy, an alternate strategy without using encryption could be for clients to ship with a secret Guid which when they login which will send an MD5 hash version of the Guid and the current time, as well as the unhashed version of the time. If the time is within a specified threshold and the MD5 hash is valid then their using an authenticated client.
I did wcf username/password authentication to my SOA application. Security model is Message, and the key is a x509 certificate encrypted RSA 4096 bits. Every client has the same key in config file
<certificate encodedValue="VeryVeryBigRsaKey />
I am curious if for example one application user, having the VeryVeryBigRsaKey can sniff the packets of other users, that share the same key (VeryVeryBigRsaKey). If yes i think is a very serious issue, and i have to change the security model to TransportWithMessageCredential.
EDIT:
I generated my key using pluralsight self cert, and exported it into a *.cer file with Base 64 encoding. And opened generated *.cer with notepad, and that gave me the rsa key (VeryVeryBigRsaKey) :)
I think you mean you use the UserName credential type and the < certificate > is used to identify the server so that client can trust it gets the message from the correct server.
if another user wants to sniff the package, he needs the server certificate that can only be owned by the real server.
Therefore, your concern is no reason.
The configuration you refer to is I think in the endpoint identity element. If so, this represents the identity of the service, which the client stack will check before communicating with the server. It therefore has to be the same on every client.
The keys used to secure message traffic are derived from the client credentials. Your fears based on this certificate identity are groundless.
I'm sure there is a security bug in WCF but this isn't it.
The certificate is used to
a) verify the server
b) encrypt a client-generated symmetric key and send it to the server
Another client can not break in to this.
I have N- Tier application Which consist of three parts:
1. Client (WPF)
2. WebService (Java web service) (Business logic)
3. Database (Oracle)
I store my password in md5 in oracle database but send password from from client to web service in not encrypted state just like a simple string. Which technic I have to use to secure password in network?
I would really recommend using SSL unless you want to go through caring about a lot of security concerns. Kerberos solve those pretty nicely as well but it is not that straightforward to use.
I've get some insights about secure authentication problems by reading Designing an Authentication System:
a Dialogue in Four Scenes (it is about designing Kerberos, but a lot applies to all authentication systems in general).
I think SSL is your friend as suggested by others. But whatever you do, I would not send the MD5 hash over the network. Part of the point of hashing (with MD5 or else) is to avoid storing a value that can be used 'as such' to authenticate a user. If any attacker gets access to the DB, he only sees the hashed password, but would still need to use the original password - which he can't decrypt from the hash - to access the web service. If your web service, instead of asking for the original pwd and hashing it itself before comparing it with the value stored in the DB, decides to let the client do the hashing, the aforementioned attacker needs only to send the compromised hash to be authenticated.
If you're worried about the requests being intercepted then you could use SSL to communicate between the client and the WS. Even if you encode the real password inside the client before sending it to the webservice, if the encoded form is somehow disclosed it could be used 'as is' to formulate a request to the webservice from any HTTP client. Alternatively you could encrypt the message content itself using an algorithm stored solely in the client so you can ensure that all WS requests come only from your client.
You could send password MD5 from client to web service. Even better, salted MD5 (and in DB you should keep also salted MD5). Then just compare what is received from client with what is in DB.