Live Journal about blowfish |

What is a Brute Force Attack?

Encryption

To understand what a brute force attack is, we must first understand the technology that is designed to attack. This technology that I speak of is data encryption. Data Encryption is used to protect code and other information from prying eyes by changing the data based upon keys, which are essentially complicated, lengthy passwords. To obtain access to the data it is necessary to have the key, otherwise the information is rendered useless.

Motive

It is in the interest of some parties, such as hackers, law enforcement, intelligence agencies, etc, to break this encryption and gain access to the data contained within. Brute force attacks are one method used to discover the key needed to unlock the data. It is by far the most rudimentary cracking process, involving trying every combination possible. Imagine forgetting a friend’s phone number and starting at 100 – 0000. And since guessing the right number gets exponentially harder every time a new number set is introduced it could take years to do even for the fastest dialer. In the same way computer systems, hardware or software, attempting to crack a key are limited by power, heat and other variables, as described in the laws of thermodynamics, making extremely long keys impractical to crack.

Entropy

However, a lot of attacks are inherently easier as some may have already noticed from the example above. If you really were to forget a phone number you would know based upon certain outside variables such as country, state, county, city, etc, that many choices can be eliminated. Many numbers can be considered either completely impossible or at the very least, very improbable. As you get more exact with your friend’s lost number the less random choices you would need to make to guess the correctly. This once daunting number starts to seem a little tamer. Certain outside factors such as pressure and temperature can affect a computer systems ability to choose numbers in a random way. This slight leveling of Einstein’s playing field, made possible by the study of entropy, enables brute force attacks to crack keys that seem to be statistically impossible.

Breakdown

Ultimately, using the right encryption combined with the technology available today, brute force attacks are on the loosing team. They are simply unable to tackle the insurmountable mountain of number combinations made available by modern encryption technology. Even advanced hardware designed specifically for the task ultimately will fail when matched with against current encryption methods. So, don’t forget your key inside one of these monsters, the lock smith won’t be much help.


The Encryption routine

The encryption routine takes two parameters – the file descriptors of input file and the output file to which the encrypted data is to be saved. It is always a good idea to zero-fill your buffers using the memset or bzero commands before using the buffers with data. This is especially important if you plan to reuse the buffers. In the program below, the input data is being encrypted in blocks of 1K each.

The steps for encryption are as follows :-

  1. Create a cipher context
  2. Initialize the cipher context with the values of Key and IV
  3. Call EVP_EncryptUpdate to encrypt successive blocks of 1k eack
  4. Call EVP_EncryptFinal to encrypt “leftover” data
  5. Finally call EVP_CIPHER_CTX_cleanup to discard all the sensitive information from memory

You may be wondering what “leftover” data is? As mentioned earlier, Blowfish encrypts information in blocks of 64-bit each. Sometimes we may not have 64 bits to make up a block. This may happen if the buffer size in the program below or the file/input data size is not a integral multiple of 8 bytes(64-bits).So accordingly the data is padded and then the partial block is encrypted using EVP_EncryptFinal. The length of the encoded data block is stored in the variable tlen and added to the final length.

int
encrypt (int infd, int outfd)
{
        unsigned char outbuf[OP_SIZE];
        int olen, tlen, n;
        char inbuff[IP_SIZE];
        EVP_CIPHER_CTX ctx;
        EVP_CIPHER_CTX_init (& ctx);
        EVP_EncryptInit (& ctx, EVP_bf_cbc (), key, iv);

        for (;;)
          {
                 bzero (& inbuff, IP_SIZE);

                 if ((n = read (infd, inbuff, IP_SIZE)) == -1)
                   {
                           perror ("read error");
                           break;
                   }
                 else if (n == 0)
                         break;

                 if (EVP_EncryptUpdate (& ctx, outbuf, & olen, inbuff, n) != 1)
                   {
                           printf ("error in encrypt update\n");
                           return 0;
                   }

                 if (EVP_EncryptFinal (& ctx, outbuf + olen, & tlen) != 1)
                   {
                           printf ("error in encrypt final\n");
                           return 0;
                   }
                 olen += tlen;
                 if ((n = write (outfd, outbuf, olen)) == -1)
                         perror ("write error");
          }
        EVP_CIPHER_CTX_cleanup (& ctx);
        return 1;
}