File Encryption and Encrypted text embedding in an image






2.65/5 (30 votes)
Jun 14, 2003
5 min read

185891

7833
This is an encryption tool which encrypts all files and can embed the encrypted data in an image. For encryption three ciphers are used ASG, SG, RC4.
Introduction
This is an encryption S/W which encrypts all files, text, video etc. To make the data more secure, I have embedded the cipher text (encrypted text ) in the bitmap. This means that the cipher text will not be visible to any one except the person who has embedded that. This embedding is done in the .bmp format, why? Just because this file has a large size, data can be easily hided in this format. The main advantage of this technique will be that if some one (hacker) wants to get the information, first he or she has to get the cipher text and then decrypt that! In our case, the first step is quite tough!!! - to get the cipher text in proper format without this S/W. Then there is another security check of encryption, so its more secure.
The case of ordinary files is quite common, any file can be encrypted and saved in the encrypted format. There are three encryption techniques I have used. These are called,
- RC4
- Alternating Step Generator
- Shrinking Generator
First of all, here is description of all these encryption techniques.
RC4
The RC4 algorithm works in two phases, key setup and ciphering. Key setup is the first and most difficult phase of this algorithm. During a N-bit key setup (N being key length), the encryption key is used to generate an encrypting variable using two arrays, state and key, and N-number of mixing operations.
For randomizing:
For i=0 to 255 J=(j+Si+Sj) Swap Si and Sj
To create pseudo random byte for encryption key
i=(i+1)mod256
J=(j+Si)mod256
Swap Si and Sj
T=(Si+Sj)mod256
K=St
Once the encrypting variable is produced from the key setup, it enters the ciphering phase, where it is XORed with the plain text message to create and encrypted message. It can be viewed as:
In the Visual C++ code it is done as:
DWORD inplen , keylen; // Get the Size of string of key and plain text inplen=inp.GetLength(); // Remove Duplicates if exists in Key key=removeDuplicates(key); keylen=key.GetLength(); // Declaration and initialization of Variables char Sbox[2000], Sbox2[2000]; unsigned long i, j, t, x; static const CString OurUnSecuredKey = "tahir_naeem" ; static const int OurKeyLen = _tcslen(OurUnSecuredKey); i = j = t = x = 0; char temp ,k; temp ='0'; k ='0'; ZeroMemory(Sbox, sizeof(Sbox)); ZeroMemory(Sbox2, sizeof(Sbox2)); // Initialize Sbox1 with numbers from 0 to 255 for(i = 0; i < 256U; i++) { Sbox[i]=(char)i; } j = 0; // Initialize Sbox2 with Key if its is not provided use //temporary key if(keylen) { for(i = 0; i < 256U ; i++) { if(j == keylen) { j = 0; } if( key.GetLength()>(j+1)) Sbox2[i]= key.GetAt(j++); } } else { for(i = 0; i < 256U ; i++) { if(j == OurKeyLen) { j = 0; } Sbox2[i]= OurUnSecuredKey.GetAt(j++); } } j = 0 ; // To generate a random byte for(i = 0; i < 256; i++) { j = (j + (unsigned long) Sbox[i] + (unsigned long) Sbox2[i]) % 256U ; temp = Sbox[i]; Sbox[i] =Sbox[j]; Sbox[j]= temp; } i = j = 0; // Final loop for(x = 0; x < inplen; x++) { i = (i + 1U) % 256U; j = (j + (unsigned long) Sbox[i]) % 256U; // Swap the Sboxi and Sboxj temp = Sbox[i]; Sbox[i] =Sbox[j] ; Sbox[j]= temp; t = ((unsigned long) Sbox[i] + (unsigned long) Sbox[j]) % 256U ; k = Sbox[t]; // Xor the key with Plain text & store it in a string inp.SetAt(x , (inp.GetAt(x) ^ k)); } // Return the Cipher text string return inp;
Shrinking generator and Alternating step Generator uses random byte stream. These ciphers are best for hardware implementation.
A control LFSR R1 is used to control the output of a second LFSR R2.
The following steps are repeated until the desired key length is generated:
- R1 & R2 are clocked.
- If the output of R1 is 1, the output bit of R2 forms the part of the key stream
- If the output of R1 is 0, the output of R1 is discarded and clocked again
- Finally the key stream is XORed with the plain text stream and that is the final cipher text.
It works in the following steps:
- Register 1 is clocked.
- If the output of R1 is 1 then R2 is clocked, R3 is not clocked but its privies repeated.
- If the output of R1 is 0, R3 is clocked, R2 is not clocked but its previous bit is repeated
- When the desired length (equal to length of plain text stream) is generated, Key is XORed with the plain text.
The result is final cipher text.
The edit boxes of initial state and key takes values in the format "1,1,0,0,1" etc. One thing to be noted is that there must be equal length parameters of LFSR 1's Key and function and similarly for LFSR 2 and LFSR 3s.
First of all the input is taken from the user in the form of CString
object, for each polynomial and key. If check box of Shrinking generator is checked, the boxes for third LFSR input are disabled using the function tahir1.SetReadOnly(TRUE);
. It is performed as:
if(SG.GetCheck()==TRUE) { ASG=FALSE; ASG1.SetCheck(BST_UNCHECKED); tahir1.SetReadOnly(TRUE); tahir2.SetReadOnly(TRUE); } else { ASG=TRUE; ASG1.SetCheck(BST_CHECKED); tahir1.SetReadOnly(FALSE); tahir2.SetReadOnly(FALSE); } //When the button Process is pressed then its checked //that whether it is for asg or sg .It is performed as : if(ASG==TRUE) EncryptAsg(); else EncryptSg(); UpdateData(FALSE);
And the function for sg
is OnSg()
called for SG and EncryptAsg()
for ASG.
The input is checked whether it is in a valid from or not and it is performed in the functions Check( );
, testNoOfElements( );
and testFunctionLength( );
. The input, after checking whether valid, is send to the class CMyAsg
via its constructer tahirasg
. In the implementation of tahirasg
constructer ,the object of class LFSR
is created and initialized with the input. The LFSR
is used for LFSRs .In the constructer tahirasg
the function of CMyAsg flowControl2();
is called. In this function, some other functions such as convertTextToBits()
to convert in binary form the data and bitstreamMaker1()
, bitstreamMaker2()
are called to generate the key stream.
The function findCtBits()
is used to XOR the key with plain text stream.
Then the function createCTextString()
is used to convert the cipher text stream to text string form. Then the function writeFile();
is called to prompt the user to store the result in some file.
The procedure is similar in the case of Shrinking generator. The difference is when check box of Shrinking generator is checked the boxes for third LFSR input are disabled using the function tahir1.SetReadOnly(TRUE);
And the function for sg
is OnSg()
called for SG and EncryptAsg()
for ASG. flowcontrol1()
is called. In this function, the function bitstreamMaker1();
is called to generate the key stream. Then the key stream is XORed with the plain text using the function findbits();
.
Finally in both cases the output is presented to user via a dialog box.
Audio Encryption & Decryption
Audio recording module, I have got from an article in the Code Project. While the playing of wav and other audio and video files is done through the function:
mysound =MCIWndCreate(GetSafeHwnd(),AfxGetInstanceHandle(),WS_VISIBLE| MCIWNDF_SHOWNAME,FileName); MCIWndPlay(mysound);
mysound
is HWND
type's object.
Wav format:
The wav file consists of a string which has a 70 bytes header at the start. The string consists of audio information. While encryption, the header must be saved with out encryption or decryption.
Encryption & Decryption
While encrypting, the header is first extracted and stored in the file. Then the remaining portion of string is passed to the encryption or decryption function. The encryption function returns the string in the encrypted form, which is stored in the file after the 70 bytes header which was stored previously.
Image Embedding
To secure the data, the encrypted data is embedded in the bitmap format image. If the image is large there will not be any serious distortion of cipher text in the image. While encrypting, the header of image is saved first because if it is interrupted then image will not be visible.
UpdateData(true); CString ct="",tahir=""; char *temp2; char *temp1; char *temp3; int control=800; int fsize=0; CFile myfile; if(m_pt=="" && FileNamex!="") { CFile mfile; // read the text file in pointer to char in temp3 mfile.Open(FileNamex,CFile::modeRead); int fs=mfile.GetLength(); temp3=new char[fs]; mfile.Read(temp3,fs); mfile.Close(); // close file ,,no further need to open for(int d=0;d<fs;d++) // fs is file length m_pt+=temp3[d]; // store the file in CString object m_pt } if(m_pt!="" && m_k !="") { int ctl,f=0,s=0; if(FileName!="") { // Open the bitmap file to read and store it in temp1 myfile.Open(FileName,CFile::modeRead); fsize=myfile.GetLength(); temp1=new char[fsize]; myfile.Read(temp1,fsize); myfile.Close(); } else AfxMessageBox("NO IMAGE "); // Encrypt the Text and store in ct using Encrypt function ct=Encrypt(m_pt,m_k); ctl=ct.GetLength(); temp2=new char[fsize+ctl]; // save header for(int i =0 ;i<401;i++) { temp2[i]=temp1[i]; } tahir.Format("%d",ctl); temp2[401]=tahir.GetLength(); //store Text length 's String length at //401 location of the array in the integer format f=(fsize-1000)/ctl; // find the interval after which the cipher text's byte //is to be sent for(int a=0;a<tahir.GetLength();a++) temp2[a+402]=tahir[a]; for(int k=0;k<ctl&&control<fsize;k++) { for(s=0;s<f;s++) { control++; // Save the cipher text bytes after f byte interval temp2[control]=temp1[control]; } control++; temp2[control]=ct[k]; } for(int p=control;p<fsize;p++) temp2[p]=temp1[p]; // Convert all the image's bytes and cipher text's byte in //one array temp2 SaveName=myfile.GetFileName(); SaveName="Embeded.bmp"+SaveName; // Save name myfile.Open(SaveName,CFile::modeCreate|CFile::modeWrite); myfile.Write(temp2,fsize); // Write the File myfile.Close(); AfxMessageBox("Embeding Completed"); // Prompt that Embeding is complete } else { AfxMessageBox("Enter Plain text or File Name and Key"); } Retrieving the Data back UpdateData(true); CString ct="",tahir="",strz="",str; int ctl; CFile myfile; myfile.Open(FileName,CFile::modeRead); int fsize=myfile.GetLength(); int control=800,f=0; char *temp1=new char[fsize+1]; char *temp2=new char[fsize+1]; myfile.Read(temp1,fsize); // Read the Image in char * myfile.Close(); int t,r, q,s=0; t=temp1[401]; // Get the saved cipher text String's size's string size //at 401 lacation for(q=0;q<t;q++) tahir+=temp1[402+q]; r=8-t; for(int z=0;z<r;z++) strz+='0'; str=strz+tahir; ctl=atoi(str.GetBuffer(str.GetLength())); tahir.Format("%d",ctl); ctl=atoi(tahir.GetBuffer(tahir.GetLength())); // Covert the Length into int format ,as it was stored in char format f=(fsize-1000)/ctl; for(int k=0;k<ctl&& control<fsize;k++) { for(s=0;s<f;s++) { control++; // Now read the cipher text in the same format as it was //mixed with image } control++; temp2[k]=temp1[control]; } for(int a=0;a<ctl;a++) ct+=temp2[a]; // save cipher text in CString format m_pt=Encrypt(ct,m_k); // Decrypt the same cipher text back into plain //text using the key UpdateData(FALSE); AfxMessageBox(" Retrieval Completed ");