12,945,945 members (37,383 online)
Tip/Trick
alternative version

#### Stats

7K views
4 bookmarked
Posted 22 Apr 2012

# Self Driven Cryptographic Operations

, 22 Apr 2012 CPOL
 Rate this:
Input drives action to perform : Encryption or Decryption - Implementation of user defined encryption signature with standard cryptographic algorithms

## Introduction

It's convenient to have a Crypto library/method in such a way that the input(file or string for crypto operation) drives the cryptographic action to perform(encryption or decryption). This can be done by adding a user defined encryption signature to the data encrypted using standard encryption algorithms. Let's use TripeDES encryption algorithm(available on .Net Platform) and try to implement our concept.

## Using the code

The whole concept can be summarized as:

1. Check if we can find encryption signature on the input.

2. If we find encryption signature, go ahead and decrypt it.

3. If we do not find encryption signature go ahead and encrypt it.

Let's define an encryption signature first.

``` byte[] ENCRYPTION_SIGNATURE = {
85, 66, 67, 127, 128, 248, 92, 152, 15, 252, 175, 38, 158, 218, 22, 141
};   ```

#### Decide on Encrypt or Decrypt operation

Check if input converted to byte array has encryption signature.

1. In order to check this we need to get block of data from input with same size as encryption    signature.

2. Then compare the block we have read with encryption signature.

3. If they are equal means,input is the candidate for Decryption operation, else it's for    Encryption operation.

The above steps can be written as below:

```//b is the input converted to byte array.

byte[] encryptionSignature = new byte[ENCRYPTION_SIGNATURE.Length];
System.Buffer.BlockCopy(b, 0, encryptionSignature, 0, ENCRYPTION_SIGNATURE.Length);
bool _isEncrypted = encryptionSignature.SequenceEqual(ENCRYPTION_SIGNATURE);```

#### If our input is encrypted, then we will go ahead and decrypt it. So the steps for decryption are

1. Convert string input or file input to byte array.

2. Remove Encryption Signature.

3. Hash password phrase(converted to bytes)  using MD5. This would be the Key for TripleDES object

4. Create TripleDESCryptoServiceProvider and set up it by

i. assign key obtained from step 3

ii. assign cipher mode and padding.

5. Try to decrypt it.

6. Return decrypted byte array.

7. Now you can process the result if you want it as a string or write it as a file as per your input type(string or file)

#### If our input is not encrypted yet, then we will go ahead and encrypt it. So the steps for encryption are

1. Convert string input or file input to byte array.

2. Hash password phrase(converted to bytes)  using MD5. This would be the Key for TripleDES object

3. Create TripleDESCryptoServiceProvider and set up it by

i. assign key obtained from step 3

ii. assign cipher mode and padding.

4. Try to encrypt it.

6. Return encrypted byte array.

7. Now you can process the result if you want it as a string or write it as a file as per your input type(string or file)

#### Complete DES Class

Let's write complete concept using a class

```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Kuthuparakkal.Crypto.Util
{

public class DES
{

byte[] ENCRYPTION_SIGNATURE = {
85, 66, 67, 127, 128, 248, 92, 152, 15, 252, 175, 38, 158, 218, 22, 141
};

private List<exception> _errorList ;
public List<exception> ErrorList
{
get { return _errorList; }
}

{

}

public DES()
{
_errorList = new List<exception>();
}

public string Crypto(string Input, string password)
{
try
{
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
bool encrypt = false;
byte[] ToProcessDecrypt = new byte[1024];
byte[] ToProcessEncrypt = new byte[1024];
try
{
ToProcessDecrypt = Convert.FromBase64String(Input);
encrypt = true;
}
catch { }

try
{
ToProcessEncrypt = UTF8.GetBytes(Input);
}
catch { }

bool decision = encrypt && IsEncrypted(ToProcessDecrypt);

if (!decision)
{
return Convert.ToBase64String(encrypted);

}
else
{
return UTF8.GetString(Decr);
}
}
catch(Exception ex)
{
return null;
}

}

public bool Crypto(string FilePath, string SavePath, string password)
{
bool success = true;
try
{
bool IsEncry = IsEncrypted(ToProcess);

if (IsEncry)
{
SaveFile(SavePath, decrypted);
}
else
{
SaveFile(SavePath, encrypted);
}
}
catch (Exception ex)
{
success = false;
}

return success;
}

private byte[] Encrypt(byte[] DataToEncrypt, string Passphrase)
{
byte[] Results;

System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below

MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

// Step 3. Setup the encoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;

// Step 4. Attempt to encrypt the input
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
catch (Exception ex)
{
throw ex;
}
finally
{
// Clear the TripleDes and Hashprovider services of any sensitive information
TDESAlgorithm.Clear();
HashProvider.Clear();
}

// Step 5. Write Encryption Signature and return

return WriteEncryptionSignature(Results);
}

private byte[] Decrypt(byte[] DataToDecrypt, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below

MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

// Step 3. Setup the decoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;

// Step 4. Strip off Encryption Signature
byte[] DataToDecryptNew =  StripEncryptionSignature(DataToDecrypt);

// Step 5. Attempt to decrypt the input
try
{
ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecryptNew, 0, DataToDecryptNew.Length);
}
catch (Exception ex)
{
throw ex;
}
finally
{
// Clear the TripleDes and Hashprovider services of any sensitive information
TDESAlgorithm.Clear();
HashProvider.Clear();
}

// Step 6. Return the decrypted byte array
return Results;
}

private byte[] WriteEncryptionSignature(byte[] b)
{
byte[] c = new byte[ENCRYPTION_SIGNATURE.Length + b.Length];
try
{
System.Buffer.BlockCopy(ENCRYPTION_SIGNATURE, 0, c, 0, ENCRYPTION_SIGNATURE.Length);
System.Buffer.BlockCopy(b, 0, c, ENCRYPTION_SIGNATURE.Length, b.Length);
}
catch(Exception ex)
{
}
return c;
}

private byte[] StripEncryptionSignature(byte[] b)
{
byte[] encryptedData = new byte[b.Length - ENCRYPTION_SIGNATURE.Length];
try
{
System.Buffer.BlockCopy(b, ENCRYPTION_SIGNATURE.Length, encryptedData, 0, b.Length - ENCRYPTION_SIGNATURE.Length);
}
catch (Exception ex)
{
}
return encryptedData;
}

private bool IsEncrypted(byte[] b)
{
}

{
byte[] encryptionSignature = new byte[ENCRYPTION_SIGNATURE.Length];
try
{
System.Buffer.BlockCopy(b, 0, encryptionSignature, 0, ENCRYPTION_SIGNATURE.Length);
}
catch (Exception ex)
{
}
return encryptionSignature;
}

private void SaveFile(string filepath, byte[] bytes)
{
// Write the byte array to the other FileStream.
using (FileStream fsNew = new FileStream(filepath, FileMode.Create, FileAccess.Write))
{
try
{
fsNew.Write(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
}
}
}

{
try
{
using (FileStream fsSource = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{

// Read the source file into a byte array.
byte[] bytes = new byte[fsSource.Length];
{

// Break when the end of the file is reached.
if (n == 0)
break;

}
return bytes;
}
}
catch(Exception ex)
{
return (byte[])null;
}
}
}
}
</exception></exception></exception>```

#### Test/usage DES

Let's now see how to use/test the DES class

String as input

1. Instantiate a new DES object.

2. Call method Crypto with input as string and passphrase, this would resturn decrypted    string.

3.  Verify the decryption by calling the method Crypto with decrypted string obtained from     step2 and use the same passphrase.

4. DES object has  a property ErrorList, this would help you find any error/exception    occured during the Crypto operation

File as input

1. Instantiate a new DES object.

2. Call method Crypto with first parameter as path to file for operation, and second for    saving the result and third parameter as passphrase, this would resturn    success/failure(bool) of operation performed

3.  Verify the decryption by calling the method Crypto appropriately.

4. DES object has  a property ErrorList, this would help you find any error/exception     occured during the Crypto operation.

```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Kuthuparakkal.Crypto.Util;

namespace Kuthuparakkal.Crypto.Test
{
class Program
{
static void Main(string[] args)
{

DES des1 = new DES();

#region String as input
Console.WriteLine(s1);//Encrypted original string
Console.WriteLine(s2);//Decrypted original string
//Print if you have any errors in operation
foreach (Exception ex in des1.ErrorList)
{
Console.WriteLine(ex.Message);
}

#endregion

#region File as input

DES des2 = new DES();
string pathSource = @"C:\Test\something.exe";
string pathNew = @"C:\Test\something_encrypted.exe";
string pathDecrypted = @"C:\Test\something_decrypted.exe";
bool suc = des2.Crypto(pathSource, pathNew, "myverynewpassword");

//Print operation result
Console.WriteLine("Operation Result : " + (suc?"Success": "Failed"));

//Print if you have any errors in operation
foreach (Exception ex in des2.ErrorList)
{
Console.WriteLine(ex.Message);
}

DES des3 = new DES();

//Print operation result
Console.WriteLine("Operation Result : " + (suc ? "Success" : "Failed"));

//Print if you have any errors in operation
foreach (Exception ex in des3.ErrorList)
{
Console.WriteLine(ex.Message);
}

#endregion

}
}
}```
Points of Interest

I have consumed the library and created a windows application to protect my sensitive files.

## History

Added more detail description on methods and operations.

## Share

No Biography provided

## You may also be interested in...

 First Prev Next
 My vote of 1 1337Architect23-Aug-14 21:45 1337Architect 23-Aug-14 21:45
 Re: My vote of 1 Kuthuparakkal24-Aug-14 1:50 Kuthuparakkal 24-Aug-14 1:50
 Re: My vote of 1 1337Architect24-Aug-14 7:56 1337Architect 24-Aug-14 7:56
 Last Visit: 31-Dec-99 18:00     Last Update: 23-May-17 16:54 Refresh 1