Thursday, December 17, 2009

Cryptography Library in .Net

During the development of Application framework, I created a library that would help to perform cryptography functions in the application. Here I am providing brief overview of cryptography and code that performs cryptography functions.

Encryption is a technique by which plain text information is converted in data stream (cipher text) which looks like meaningless.
Decryption is the process of converting the cipher text (encrypted data stream) to readable plain text.

.Net Cryptography supports symmetric encryption, asymmetric encryption and hashing to convert plain text into cipher text.


Symmetric Encryption

These cryptography algorithms use the same key for encryption and decryption. Algorithms that operate on 1 bit or 1 byte of plaintext at a time are called stream ciphers whereas
algorithms that operate on blocks of bits at a time are called block ciphers.

Where to use Symmetric Encryption
These algorithms should be used to encrypt the messages within one application because same key is used for encryption and decryption. Using symmetric encryption with third party applications is not recommended as you need to share the encryption key.

Important Symmetric Encryption Algorithms

Data Encryption Standard:

DES is a block cipher which uses 56-bit fixed length key to generate cipher text. Any 56 bit value can be a key.
Due to short length of the key this algorithm is vulnerable to brute-force attack.

TripleDES:


Triple DES improves the DES algorithm by applying DES three times using three different keys by which effective key length becomes 168 bits.

Advanced Encryption Standard (AES) aka Rijndael:


This is block cipher and supports key lengths of 128, 192 and 256 bits. It is recommended to uses 256 bits key.

What is Initialization Vector
To ensure that encryption of the same string and with the same key is different everytime we perform the encryption, the output (cipher block) of previous block is appended to the next block to perform the encryption. But for the first block initialization vector is used. It is important to use the random IV everytime we perform the encryption operation.


 

Hashing

This is one way hash function which takes the variable length string and converts that to the fixed length binary sequence. Using the hash value you can't retrieve the original value. This is only one way conversion; however you can always compare the two hash values to check whether those are same or not.

Where to use Hashing
Hashing should be used where you need to protect the information and doesnot want the original text. For example: User's Passowrd.
User's Password can be hashed and stored in the database and during the login calculate the hash of the password entered by the user. We compare the hash value just calculated with the value stored in the database, if both matches that means user has entered the valid password.

Hashing Algorithms

MD5:
This algorithm produces 128 bit hash value.

SHA1:
This algorithm produces 160 bit hash value. Always use SHA because it produces larger hash value as compared to MD5.

Salt Value
One problem with hashing is that if two user's selected the same password then the hash value will also be same. One way to ensure that the hash of two same strings will never be same is to add the salt value (unique value) to the original text before hashing. The salt value can be generated using RNGCryptoServiceProvider. You require this salt value during comparison. You have two options either to store the salt as the part of the hash value so that later it can be extracted from the hash value or store the salt value as separate. The attached code appends the salt value as part of the hash itself.


 

Difference between Hashing and HMAC

During development of Security Framework of Rest Services, I figured out that why hashing alone is not sufficient and we need to perform the HMAC. Here is the difference between two.

Hashing: It produces standard 20 byte fixed length hash (using SHA1). Now if we send the request to the service along with the hash value of the Request Parameters for tamper proofing, the service will also compute the hash value of all the request parameters to check whether the information has been tampered or not. Things look fine but actually here is one problem. Some Attacker changes the request parameters, recalculates the hash of the changed request parameters and then sends the request using the new request parameters and new hash value. Now service recalculates the hash value from the request parameters and found the hash value to be correct (because the hash value is itself replaced with the new one.). So hashing in this scenario will not work for tamper proofing.
Hashing should be used only within one layer of the application or between layers where communication between the layers is encrypted and highly secured like storing password because the hash is calculated in the business layer and stored in the database. The communication between the business layer and database is generally behind the firewall and secured.

So in the above scenario, we have to use HMAC in which a secret key is shared between the two parties and using that secret key the HMAC is calculated. What HMAC does is, it takes the hash of the shared key + message, prepends the key to that hash, and then re-hashes the result. This makes it cryptographically sound and thus used for digital signing.

HMAC = hash (sharedkey + hash (sharedkey + message))

Forms Authentication Ticket, Roles Cookie uses HMac for tamper proofing.


 

Performing Encryption/Digital Signing in ASP.Net

.Net has machine key settings in the machine.config file by which forms authentication ticket, roles cookie are encrypted and signed.

The default values for the machinekey are

<pages enableViewStateMac="true" viewStateEncryptionMode="Auto" ... />


 

<machineKey validationKey="AutoGenerate,IsolateApps"

decryptionKey="AutoGenerate,IsolateApps"

validation="SHA1" decryption="Auto" />


 

When you configure ViewState, the <pages> element is used in conjunction with the <machineKey> element.

The <machineKey> attributes are

  • validationKey: This key specifies the HMAC key which is used for making viewstate tamper proof, signing the forms authentication ticket, signing Roles cookie.
  • decryptionKey: This specifies the key that will be used to encrypt or decrypt the data. This key is used to encrypt data of forms authentication ticket, roles cookie.
  • decryption: This specifies the symmetric algorithm that will be used for encryption and decryption. The values can be AES, 3DES, DES
  • validation: This specifies the algorithm used to generate HMAC for making viewstate tamper proof, signing forms authentication ticket. The various values can be SHA1, MD5, AES and 3DES. The values AES and 3DES are used in ASP.Net 1.1 because the decryption was only introduced in 2.0

Always use SHA1 because this produces larger hash as compared to MD5.

Forms authentication defaults to SHA1 for tamper proofing (if <forms protection="validation" or "All").
When <forms protection="All"> or <forms protection = "Encryption">, then forms authentication hashes the forms authentication ticket by using either MD5 or HMACSHA1


 

Performing Cryptography Operations:

In every application there are scenarios where we need to encrypt/ decrypt, hash or digital sign the information. The attached code provides the library for performing these operations. Brief overview of the library is explained below:

As mentioned Microsoft uses machineKey to encrypt/ decrypt, digitally sign the authentication cookie, roles cookie so it is better to use same keys for crypto operation which we perform in the application.

The first step would be to generate the decryption and validation keys. We should keep in mind that our applications will be deployed in web farm environment or not. It is always better to specify the specific values of decryption and validation keys so that in future web farm deployment will be easier. Attached code contains the Console Project which describes the way to generate decryption and validation keys.

MachineKey Wrapper: Code contains machine Key wrapper that reads machineKey settings from the config file.

Encryption/ Decryption: The code contains various operations for performing encryption and decryption including encryption and decryption of XML documents/ elements. These methods use decryption and decryptionKey element of the machineKey settings.

Hashing: Code contains methods for creating the hash and then comparing the hash value. Salt is randomly generated and stored as part of hash value. These methods use only the validation attribute of machineKey settings.

Note: The validationKey attribute is used is not used for hashing, this value is used for HMAC which is different from hashing as explained above.

Digital Signing (HMAC): Code contains various methods for creating and comparing the signature. The validation Key mentioned in the machineKey settings of web.config file is the secret key which HMAC uses for generating signature.

Cryptography Library in .Net

References:

http://msdn.microsoft.com/en-us/library/ms998288.aspx

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.aspx

http://www.4guysfromrolla.com/webtech/LearnMore/Security.asp

http://msdn.microsoft.com/en-us/library/5e9ft273%28VS.100%29.aspx

http://dev.ionous.net/2009/03/hmac-vs-raw-sha-1.html

No comments:

Post a Comment