I am trying to devise a security scheme for encrypting the application level data between a silverlight client, and a php webservice that I created. Since I am dealing with a public website the information I am pulling from the service is public, but the information I'm submitting to the webservice is not public. There is also a back end to the website for administration, so naturally all application data being pushed and pulled from the webservice to the silverlight administration back end must also be encrypted.
Silverlight does not support asymmetric encryption, which would work for the public website. Symmetric encryption would only work on the back end because users do not log in to the public website, so no password based keys could be derived. Still symmetri开发者_开发知识库c encryption would be great, but I cannot securely save the private key in the silverlight client. Because it would either have to be hardcoded or read from some kind of config file. None of that is considered secure. So... plan B.
My final alternative would be then to implement the Diffie-Hellman algorithm, which supports symmetric encryption by means of key agreement. However Diffie-Hellman is vulnerable to man-in-the-middle attacks. In other words, there is no guarantee that either side is sure of each others identity, making it possible for communication to be intercepted and altered without the receiving party knowing about it. It is thus recommended to use a private shared key to encrypt the key agreement handshaking, so that the identity of either party is confirmed.
This brings me back to my initial problem that resulted in me needing to use Diffie-Hellman, how can I use a private key in a silverlight client without hardcoding it either in the code or an xml file.
I'm all out of love on this one... is there any answer to this?
EDIT:
Remember that this is about a custom PHP web service that I rolled out on my own.
I found an RSA implementation i can use in Silverlight. It seems pretty safe to use this to encrypt the handshake for the DiffieHellman key agreement between the Silverlight client and PHP web service, and subsequently also use it to encrypt the symmetric key that was agreed upon (which is itself generated from the result of the key exchange by hashing it).
After this I'm pretty much guaranteed that all communication going to the web service has not been intercepted, modified and then retransmitted (MITM). However I believe it is still possible; technically, for an attacker to impersonate the silverlight client and send messages to the webservice (assuming they discover the url).
Security from unauthorized access is provided since the attacker does not know the "secret api" of my custom webservice, hence they are unable to communicate with it.
The only way to break this would be to brute force the webservice with whatever strings an attacker may suspect to be valid to try and get a response from the web service. I don't think you can brute force a variable length string. It sounds impractical.
Does anyone see a problem with this approach?
SSL/TLS suffers from the same problem that any Diffie-Hellman-based implementation you come up with would have, in that it can still be broken by a man-in-the-middle attack.
The reason TLS is secure and trusted is because the client, when receiving the server's certificate, authenticates it by checking that it is signed with another certificate from a known trusted identity - say, VeriSign. Thus far, this makes it impossible to enact a man-in-the-middle attack without having VeriSign's private key - when the interloper sends a fake certificate proclaiming to be the server, the client would easily detect that this certificate is not signed using the trusted identity's certificate, and bails out of the connection, displaying a warning to the user.
For your purposes, it's likely easiest to use TLS. To make it secure, you would generate a certificate for your server, and then embed in your client the public key for that certificate. The client can then verify that it is talking to your server, without having to expose the private key, which you don't have to distribute.
EDIT: In response to your comment on Jerry's answer, if your hosting provider doesn't allow SSL/TLS connections at all, preventing a man-in-the-middle attack will be tricky. If this is your only reason for avoiding TLS, I would suggest getting your provider to turn it on, or finding a provider that allows for it.
EDIT: In response to your edited question: even if you're now using RSA in your Silverlight client to send data to your web service, you cannot guarantee that the client itself has not been modified. It's quite possible for an attacker to dig into your client, determine the algorithm you're using to perform the encryption/handshake, and then write code to impersonate your client (or indeed, modify the client to include their code). Once they've done that, they can start analyzing your API and use it to make calls to your web service.
It's the same with SSL/TLS - the client can validate the identity of the host using the host's certificate, and as long as the host's server is secured, the client can trust the output from the host; however, there is no mechanism in which the host can 100% validate that the client is who they say they are, as the client will be run on a machine which does not have a controlled execution environment.
However - despite the above being true, and that it's possible that an attacker can compromise your system in this way, it's likely not probable -- unless you're working on a public-facing system that attracts a lot of attention/use, or a system that deals directly with money in some form, the attacker needs to make some effort before being able to send their own input to your web service.
Your best bet is to validate the input received by your web service thoroughly, and don't leave dangling APIs accessible that your regular client would never use.
The obvious solution would be to use WCF to establish an SSL or TLS connection instead of attempting to build that into the application.
I recommend starting with this JavaScript+PHP DH key Exchange protocol: http://enanocms.org/News:Article/2008/02/20/Diffie_Hellman_key_exchange_implemented
You can then re-write the javascript in silverlight. I recommend using Wireshark to dump packets then you can use Meld or whatever to diff the packets to see where your implementation is differs from the original.
Good Luck!
(Disclaimer: I totally agree with the Enano dev team, this is not a full replacement of SSL and SSL should be used whenever possible.)
精彩评论