玄铁剑

成功的途径:抄,创造,研究,发明...
posts - 128, comments - 42, trackbacks - 0, articles - 174

Introduction

In this article, I will show you how to exchange data securely with a Web Service without HTTPS/SSL but without compromising the same protection level of HTTPS/SSL. It will also give you a real life example on the implementation and limitation of the important encryption types as well as Digital Signature that are available in .NET Framework.

Advantages

  1. No Installation and configuration is required in IIS or in the Client.
  2. No Deployment issue (Nothing to embed/ship) in the client.
  3. No Additional Library is required.
  4. Less easier to implement comparing alternates.

Requirements

If you are not familiar with Symmetric, Asymmetric Encryption and Digital Signature. I strongly suggest you read the following articles of cp before you move forward, there are also many reference available in the Web on this topic:

I have created the solution in Visual Studio 2005 and .NET 2.0 but it can be easily ported to Visual Studio 2003 and .NET 1.1.

Background

Symmetric VS Asymmetric

I assume that you already know the difference between the Symmetric and Asymmetric encryption. In short, in Symmetric encryption both the parties (the server and client) use the same key to encrypt and decrypt the data. On the other hand, in Asymmetric encryption a pair of key (known as Public/Private Key) is used to encrypt/decrypt. If the data is encrypted with the Private Key the only way to decrypt it is the Public Key and the vice versa.

Digital Signature

Digital Signature is also a part of the Public/Private Key implementation. The private key is used to sign the data and public key is used to verify that data has not been tampered. However, Digital signature does not retain the secrecy of the data, which means the data always remain plain (Not encrypted).

Alternate Solutions

  1. Share Common Secret Key: The easiest way to implement it to share a common secret key before the Client and Service start communicating.
  2. MS WSE Library: I found it difficult to implement. Maybe it will look easier to you.

The Solution

Initial Proof of Concept

After going thorough few details of the above mentioned articles and of course, MSDN I came up with the following message exchange between the client and server, which looks pretty, rock solid to me.

The Client The Server The Hacker

1.

Client creates random Public/Private Key Pair and sends the Server the Public Part

The Server in turns creates a random Public/Private Key Pair and returns Public Part to Client.
 

The Hacker can only view both parties Public key.
 

2.

The Client encrypts the target data with received Server Public Key and sends it back to Server.

The Server receives the encrypted data decrypts it with the previously generated Server Private Key.

Server Process the Data.

Server encrypts the process result with the previously received Client Public Key and returns back to Client.
 

The hacker only has the Server Public key. So it is not possible for the hacker to decrypt the data, as it requires the server private key to decrypt.


Again, the Hacker only has the Client Public key and thus it is not possible for the Hacker to decrypt the process result.
 

3.

The Client receives the encrypted process result and decrypts it with the previously generated Client Private Key.
 

 

 

4.

The Client returns to regular processing
 

The Server Goes to sleep.
 

The Hacker Cries.
 

.NET Platform

In .NET platform, there are different algorithms available for both Symmetric and Asymmetric. I am not going to explain the details of these algorithms as it is beyond the scope of this article. The characteristics are:

Symmetric Algorithms

  • DES: 64 bit encryption - Good.
  • RC2: 128 bit encryption - Better.
  • Rijndael: 256 bit also known as AES and the most secure algorithm – The Best.
  • TripleDES: 192 bit encryption – Much better.

Asymmetric Algorithms

  • DSA: Does not support Encryption/Decryption. Only allows Digital Signature (So skipping from discussing).
  • RSA: Supports both Encryption/Decryption and Digital Signature. But it cannot encrypt/decrypt data more than 117 byte. If you want to encrypt more than 117 byte, it will throw you a Cryptographic Exception with a message that Key not valid for use in specified state. There are many references available in web, which explains this limitation.

Implementation

As mentioned above the only asymmetric algorithm that supports Encryption/Decryption is RSA, but it has the limitation of data length. Moreover, in Web Service it is regular case that we are exchanging data more than 117 bytes with those bulky xml tags. We can surly use other mechanism such as compression, use other medium such as JSON instead of XML to reduce the data size, but none of these ensures that the data size will be always less  than 117 byte. Here comes the Symmetric Key into the scene. Let me revise the previous proof of concept.

Revised Solution

The Client The Server The Hacker

1.

Client creates random Public/Private Key Pair and sends the Server the Public Part.
 

The Server in turns creates a random Public/Private Key Pair and returns Public Part to client.
 

The Hacker can only view both parties Public Key.
 

2.

Client Creates a random symmetric key, encrypts it with the previously received Server Public Key, and sends it to Server.
 

The Server receives the client symmetric key decrypts it with the previously generated Server Private Key.
 

Now the Server Creates a Random Symmetric Key encrypts it with the Client Public Key and returns it back to the Client.
 

Same thing happens for the Hacker as in the initial proof of concept. The Hacker cannot decrypt the data, as it requires the Server Private key.
 
Again, the Hacker only has the Client Public Key and thus it is not possible for the Hacker to decrypt the Server Symmetric Key.
 

3.

Client Receives the encrypted Symmetric Key of Server. It decrypts it with previously generated Client Private Key.

Client Encrypts the target data with the previously generated Client Symmetric key and sends to Server.
 





Server Receives the Encrypted data, Server decrypts it with the previously received Client Symmetric key.

Server Process the Data.

Server encrypts the process result with the previously generated Server Symmetric Key and returns back to Client.
 





The Hacker does not have the Client Symmetric Key and so it is not possible to decrypt the data.
 
 
 
Again, the Hacker does not have the Server Symmetric Key and thus it is not possible for the hacker to decrypt the process result.
 

4.

The Client receives the encrypted process result and decrypts it with the previously received Server Symmetric Key.
 


 

 

5.

The Client returns to regular processing.
 

Server goes to sleep.
 

The Dumb Hacker cries and but the intelligent hacker might be thinking, “Hey there is something to hack”.
 

In this revised version an extra step just been introduced -the step 2, where both the parties exchanging Symmetric key (Lets call it session key from now on) instead of the actual data like in the initial concept. Now you might be thinking does not the RSA length limitation applies when encrypting the session key. The Answer is no, it does not, even we are exchange the most secure Rijndael key(256 bit) , the data length becomes 44 byte (256/8) which we can easily encrypted/decrypted with RSA. The only weakness of the above solution is, if the intelligent hacker can somehow discover the session key of the both parties, but which I assume is very difficult to discover based upon the encrypted data.

Where is the Digital Signature?

You might be thinking this article starts with Digital Signature, but still no flavor of it. Let me tell you, although the digital signature is not required but you can implement it to make the solution more secure and ensure that even the intelligent hacker can revive both the parties session key but there will be no way the hacker can tamper the data. Here is the final solution.

The Final Solution

The Client The Server The Hacker

1.

Client creates random Public/Private Key Pair and sends the Server the Public Part.

The Server in turns creates a random Public/Private Key Pair and returns Public Part to client.

The Hacker can only view both parties Public Key.

2.

Client Creates a random Session key, encrypts it with the previously received Server Public Key, Digitally Signs it with the Client Private Key and sends it to Server.

The Server receives the client session key, Checks it integrity with the Client Public Key, if the Key has not been tampered, it decrypts the Client Session Key with the previously generated Server Private Key.

Now the Server Creates a Random Session Key encrypts it with the Client Public Key, Digitally Signs it with the Server Private Key and returns it back to the Client.

Same thing happens for the Hacker as in the previous two solutions. The Hacker cannot decrypt the data, as it requires the Server Private key, moreover the Hacker founds the data is now Digitally Signed.

Again, the Hacker only has the Client Public Key and thus it is not possible for the Hacker to decrypt the Server Session.

3.

Client Receives the encrypted Session Key of Server. It verifies it with the Server Public Key, if not tampered, it decrypts it with previously generated Client Private Key.

Client Encrypts the target data with the previously generated Client Session Key, Digitally Signs it and sends to Server.




Server Receives the Encrypted data, Server verifies it with Client Public Key, if not tampered it decrypts the data with the previously received Client Session Key.

Server Process the Data.

Server encrypts the process result with the previously generated Server Session Key, Digitally Signs it with the Server Private Key and returns it back to Client





The Hacker does not have the Client Session Key and thus it is not possible to decrypt the data, also founds the data is Digitally Signed.



Again, the Hacker does not have the Server Session Key and so it is not possible for the hacker to decrypt the process result.

4.

The Client receives the encrypted process result, verifies it with Server Public Key and decrypts it with the previously received Server Session Key.


 

5.

The Client returns to regular processing.

Server goes to sleep.

Both the Hacker cries now.

In the final solution, the digital signature has been introduced to ensure the data has not been tampered between the communications.

The Source Code

The attached source contains the implementation of the final solutions, RSA’s limitation of large data encryption, a bit performance benchmarking and few numbers of handy classes which you can use in your own solution.

Disadvantages

  • The Solution is not 100% secure. But its is pretty good to use in production environment.
  • Much more coding, as you will not get the benefit of Strongly Typed Objects that generated web service proxy provides. You have to write some kind of wrapper (Like the ServiceWrapper.cs in the Client) to get the benefit of Strongly Typed Object.
  • The Service will not be stateless, as it needs to use session, cache etc to identify the client.
  • Performance will not be optimal, as it requires two more calls to initialize the secure communication also the encryption/decryption/verification has extra overhead.

About kazimanzurrashid


Kazi Manzur Rashid is a die-hard fan of Microsoft Technology. He has delivered many diversified solution in his professional career which includes SpywareKill - first ever anti-Spyware tool in Microsoft .NET technology, PrepaidATM the largest ATM Card network currently acquired by GlobalATM, LicenseLeader - Licensing Framework for .NET Components and many more. He is currently working in Pageflakes Ltd - A Leading Player in Personalized Web Desktop. His former role includes the Tech Lead of Velocity Global Resource offshore development team.

He lives in Dhaka, Bangladesh.

You can reach him here:
Email: KaziManzurRashid at GMail dot com
Blog: http://geekswithblogs.net/rashid/
只有注册用户登录后才能发表评论。