Blog : Block Cipher Modes of Operation
Block Cipher Modes of Operation
Fold
Table of Contents
Background
Tiny Encryption Algorithm
Source Code
Block Cipher Modes of Operation
Background
One of the projects assigned to me during Network Security (Fall 2008) Class was to implement Block Cipher Modes of Operation.
According to Wikipedia, modes of operation enable the repeated and secure use of a block cipher under a single key. A block cipher by itself allows encryption only of a single data block of the cipher's block length. When targeting a variable-length message, the data must first be partitioned into separate cipher blocks. Typically, the last block must also be extended to match the cipher's block length using a suitable padding scheme. A mode of operation describes the process of encrypting each of these blocks, and generally uses randomization based on an additional input value, often called an initialization vector, to allow doing so safely.
Thus based on the above description, each block in this project was of 64 bits in length or 8 UTF-8 encoded ASCII characters. In cases where input message had to be a multiple of block size, '/' was used followed by required number of '@' as padding characters towards the end of a message if needed. Although, while reconstructing the original message at the receiver end, any padding used while sending it across was removed.
Tiny Encryption Algorithm
Tiny encryption algorithm (TEA) was proposed by David Wheeler and Roger Needham in 1994. It is under public domain and suffers from no patent restrictions. Following is a simple ANSI-C source code for TEA.
#include
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
It takes 64 bits block data and a 128 bits long key. This implementation of TEA was used in this project for performing the basic encryption.
Source Code
• Cipher Block Chaining Module
• Cipher Feedback Mode Module
• Counter Mode Module
• Message Authentication Code Module
• start.rb - Entry Point of Program
Instructions:
1. Create a directory called "modes" and put all module files (CBC.rb, CFB.rb, CTR.rb and MAC.rb) in that directory.
2. Place the file "start.rb" where "modes" directory is and use command line to run the program.
3. Specific instructions corresponding to each mode are provided in the following sections.
Block Cipher Modes of Operation
• Cipher Block Chaining
• k-Bit Cipher Feedback Mode
• Counter Mode
• Message Authentication Codes
CBC mode of operation was invented by IBM in 1976. In the cipher-block chaining (CBC) mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block is dependent on all plaintext blocks processed up to that point. Also, to make each message unique, an initialization vector must be used in the first block.
CBC has been the most commonly used mode of operation. Its main drawbacks are that encryption is sequential (i.e., it cannot be parallelized), and that the message must be padded to a multiple of the cipher block size. Note that a one-bit change in a plaintext affects all following ciphertext blocks. A plaintext can be recovered from just two adjacent blocks of ciphertext. As a consequence, decryption can be parallelized, and a one-bit change to the ciphertext causes complete corruption of the corresponding block of plaintext, and inverts the corresponding bit in the following block of plain-text.
How to run the program in CBC Mode
%CBC Sample:
ruby start.rb mode=1 eblock=3
ruby start.rb mode=1 eblock=0
The above shows 2 sample commands to test CBC mode of this project. mode=1 species that "Cipher Block Chaining" is in use. eblock=3 species that a snooper has modified block 3 of the encrypted message before it is decrypted by the receiver. eblock=0 means no block has been modied. We assume that block numbers start from 1. We flip the bits in the error block after encryption has been performed and before starting decryption process.
The code prompts the user to provide IV (Initialization Vector), PassPhrase and Input message.
%Example Program Prompt:
Enter IV: 882653
Enter PassPhrase: GoGators
Input Message: Man I think this project is too simple. Waiting for next Project.
The project uses padding wherever necessary and also converts PassPhrase and Initialization Vector into 128 bits. The program performs both encryption and decryption in the same pass. The only reason why "eblock" is there is to see the effect of chaining on the following blocks in the message during decryption. Program uses previously provided IV and PassPhrase for decryption, and does not prompt again.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BLOG
Php file encryption methods. Does something simple exist?
It's seems that there isn't any pleasant way to encrypt a file in php.
The built in methods of php, mcrypt, aren't very portable as most servers don't support them.
Command line encryption tools are like ugly hacks.
There's encryption for strings which is nice, but if we want to encrypt a file it doesn't help very much especially for someone else to unencrypt it.
Other encryption tools require public keys, key rings, private keys, blood sample... These seem much too complicated for just encrypting a file.
It seems that we should just have a simple function for PHP that could work like so:
$crypt = new Crypt();
$crypt->encryptFile("Password1245!", 'secret_file.txt', 'encrypted_file.txt');
$crypt->decryptFile("Password1245!", 'encrypted_file.txt', 'original_file.txt');
Any one have any ideas? I'm pulling out hair!
EDIT: Another thing I should add, for the end user to be able to decrypt the file with ease.
Basically I'm trying to find something that can replace a password protected zip file
Take a look at the PEAR encryption packages. They don't all rely on mcrypt - for exampleCrypt_Blowfish.
If you don't mind having the mcrypt extension installed, this code should do it:
function Encrypt($string, $key)
{
if (extension_loaded('mcrypt') === true)
{
return base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, substr($key, 0, mcrypt_get_key_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB)), trim($string), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
return false;
}
function Decrypt($string, $key)
{
if (extension_loaded('mcrypt') === true)
{
return trim(mcrypt_decrypt(MCRYPT_BLOWFISH, substr($key, 0, mcrypt_get_key_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB)), base64_decode($string), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
return false;
}
function Encrypt_File($source, $destination, $key)
{
if (extension_loaded('mcrypt') === true)
{
if (is_file($source) === true)
{
$source = file_get_contents($source);
if (file_put_contents($destination, Encrypt($source, $key), LOCK_EX) !== false)
{
return true;
}
}
}
return false;
}
function Decrypt_File($source, $destination, $key)
{
if (extension_loaded('mcrypt') === true)
{
if (is_file($source) === true)
{
$source = file_get_contents($source);
if (file_put_contents($destination, Decrypt($source, $key), LOCK_EX) !== false)
{
return true;
}
}
}
return false;
}
what about simple xor?
function Crypt($source, $key)
{
$rv='';
for($i=0;$i {
$rv.=chr(ord($source[$i]) ^ ord($key[$i%strlen($key)]));
}
return $rv;
}
=> Crypt(Crypt('aaa','key'),'key') returns 'aaa'.
EDIT: of course, you should use
file_put_contents(Crypt(file_get_contents('file'), 'key'));
for file read+write :]
Yossarian's Crypt() function fixed:
function _Crypt($source, $key)
{
$result = '';
for($i = 0; $i < strlen($source); $i++)
{
$result .= chr(ord($source[$i]) ^ ord($key[$i % strlen($key)]));
}
return $result;
}
_Crypt('aaa', 'key'); //
_Crypt(_Crypt('aaa', 'key'), 'key'); // aaa