|
Introduction
Blowfish is an encryption algorithm that can be used as a replacement for the DES or IDEA algorithms. It is a symmetric (i.e. uses the same secret key for both encryption and decryption) block cipher (encrypts data in 8-byte blocks) that uses a variable-length key, from 32 (4 bytes) bits to 448 bits (56 bytes). Blowfish was designed in 1993 by Bruce Schneier as an alternative to existing encryption algorithms. Designed with 32-bit instruction processors in mind, it is significantly faster than DES. Since its origin, it has been analyzed considerably. Blowfish is unpatented, license-free, and available free for all uses. The algorithm consists of two parts: a key-expansion part and a data-encryption part. Key expansion converts a variable key of at least 4 and at most 56 bytes into several subkey arrays totalling 4168 bytes. Blowfish has 16 rounds. Each round consists of a key-dependent permutation, and a key and data-dependent substitution. All operations are XORs and additions on 32-bit words. The only additional operations are four indexed array data lookups per round. Blowfish uses a large number of subkeys. These keys must be precomputed before any data encryption or decryption.
A more detailed article describing the Blowfish algorithm can be found at http://www.schneier.com/blowfish.html
The C++ implementation presented in this article was tested against the test vectors provided by Eric Young at http://www.counterpane.com/vectors.txt. The results were identical with one exception which in my opinion could be a typing error in the referenced Internet file.
Implementation
The public user interface of the CBlowfish class is given bellow: class CBlowFish
{
public:
CBlowFish(unsigned char* ucKey, size_t n, const SBlock& roChain = SBlock(0UL,0UL));
void ResetChain();
void Encrypt(unsigned char* buf, size_t n, int iMode=ECB);
void Decrypt(unsigned char* buf, size_t n, int iMode=ECB);
void Encrypt(const unsigned char* in, unsigned char* out,
size_t n, int iMode=ECB);
void Decrypt(const unsigned char* in, unsigned char* out,
size_t n, int iMode=ECB);
};
In the constructor, a user-supplied key material of specified size is used to generate the subkey arrays. Also the chain block is initialized with the specified value.
The function ResetChain() is used to reset the chaining block before starting a new encryption or decryption operation.
The first variant of the Encrypt() function is used for in place encryption of a block of data of the specified size applying the specified operation mode. The block size should be a multiple of 8. This function can operate in the following modes: ECB, CBC or CFB. In ECB mode, chaining is not used. If the same block is encrypted twice with the same key, the resulting ciphertext blocks are the same. In CBC mode a ciphertext block is obtained by first XOR-ing the plaintext block with the previous ciphertext block, and encrypting the resulting value. In CFB mode a ciphertext block is obtained by encrypting the previous ciphertext block and XOR-ing the resulting value with the plaintext. The operation mode is specified in the iMode parameter with ECB being the default value. For the second variant of the Encrypt() function the encryption result is delivered in an output buffer.
The Decrypt() functions are the reverse of the Encrypt() functions presented above.
Usage Examples
The use of CBlowfish class is very easy. In the first code snippet example a key of 8 bytes in size is applied to an 8 byte block. The initial chain block is a null block. The block "aaaabbbb" is encrypted and then decrypted back. try
{
char szHex[17];
CBlowFish oBlowFish((unsigned char*)"abcdefgh", 8);
char szDataIn[] = "aaaabbbb";
char szDataOut[17] = "\0\0\0\0\0\0\0\0";
oBlowFish.Encrypt((unsigned char*)szDataIn, (unsigned char*)szDataOut, 8);
CharStr2HexStr((unsigned char*)szDataIn, szHex, 8);
cout << szHex << endl;
CharStr2HexStr((unsigned char*)szDataOut, szHex, 8);
cout << szHex << endl;
memset(szDataIn, 0, 8);
oBlowFish.Decrypt((unsigned char*)szDataOut, (unsigned char*)szDataIn, 8);
CharStr2HexStr((unsigned char*)szDataIn, szHex, 8);
cout << szHex << endl;
}
catch(exception& roException)
{
cout << roException.what() << endl;
}
In the next code snippet example a key of 16 bytes in size is applied to a larger block of data of 48 bytes size (the block of data size should be a multiple of the block size which is always 8 bytes). The initial chain block is a null block. The block "ababababccccccccababababccccccccababababcccccccc" is encrypted and then decrypted back in all the operation modes (ECB, CBC and CFB). Notice that for the chaining operating modes the chain block has to be reset before decrypting back. try
{
CBlowFish oBlowFish((unsigned char*)"1234567890123456", 16);
char szDataIn1[49] = "ababababccccccccababababccccccccababababcccccccc";
char szDataIn[49];
char szDataOut[49];
memset(szDataIn, 0, 49);
memset(szDataOut, 0, 49);
strcpy(szDataIn, szDataIn1);
memset(szDataOut, 0, 49);
oBlowFish.Encrypt((unsigned char*)szDataIn,
(unsigned char*)szDataOut, 48, CBlowFish::ECB);
memset(szDataIn, 0, 49);
oBlowFish.Decrypt((unsigned char*)szDataOut,
(unsigned char*)szDataIn, 48, CBlowFish::ECB);
oBlowFish.ResetChain();
strcpy(szDataIn, szDataIn1);
memset(szDataOut, 0, 49);
oBlowFish.Encrypt((unsigned char*)szDataIn,
(unsigned char*)szDataOut, 48, CBlowFish::CBC);
memset(szDataIn, 0, 49);
oBlowFish.ResetChain();
oBlowFish.Decrypt((unsigned char*)szDataOut,
(unsigned char*)szDataIn, 48, CBlowFish::CBC);
oBlowFish.ResetChain();
strcpy(szDataIn, szDataIn1);
memset(szDataOut, 0, 49);
oBlowFish.Encrypt((unsigned char*)szDataIn,
(unsigned char*)szDataOut, 48, CBlowFish::CFB);
memset(szDataIn, 0, 49);
oBlowFish.ResetChain();
oBlowFish.Decrypt((unsigned char*)szDataOut,
(unsigned char*)szDataIn, 48, CBlowFish::CFB);
cout << endl;
}
catch(exception& roException)
{
cout << "Exception: "
<< roException.what() << endl;
}
I am interested in any opinions and new ideas about this implementation. The project Blowfish.zip attached to this article includes the source code of the presented CBlowfish class and some test code.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 108 (Total in Forum: 108) (Refresh) | FirstPrevNext |
|
|
 |
|
|
My data size is only can read by unsigned long. When I use this blowfish encryption/decryption, I found that my program can't run. I want to write a new blowfish encryption with unsigned long. Anyone can help me?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, i'm very new to C++ but I really need to use blowfish in C++.
I've downloaded the sample code, opened it in MS VC++ 6.0, but it will not compile.
I get the following errors:
fatal error C1083: Cannot open include file: 'exception': No such file or directory fatal error C1083: Cannot open include file: 'streambuf': No such file or directory
Can someone please help me?
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hello,
I need to decrypt a string using java, that was encrypted using this code project Blowfish implementation. I am not sure what to use on the java side. From the different samples available on the web I can gather that I have to use Password based encryption/decryption and JCE. But all these java samples, when tried, give out a different cipher text for the same plain text/pass phrase combination that I used with this code project Blowfish implementation. I am not sure what is the difference is. Any clues? Thanks
K. Ramesh
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
hi rameshk01,
did you solved this problem? i noticed that encrypting with c++ generate a strage hex code
try with this link http://webnet77.com/cgi-bin/helpers/blowfish.pl
if you find some solution write to me synco@tiscalinet.it
thanks
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,all!
I have the same trouble.
when I encrypted the "Blowfish" in MFC ,get the result : 7狑?7?x__鍄獭G榖?Z_?鎿?c?[湋?Lu感.
How can the java side decrypt the "7狑?7?x__鍄獭G榖?Z_?鎿?c?[湋?Lu感" to "Blowfish" ?
Who can help me ?
今天没有时间,以后再写吧。
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi All,
I am trying to use this code implementation for encrypting and decrypting some data that i am storing in a file. The total number of bytes in the plain text is 2824 but the size of the cipher text is only 1535. And i have noticed that the problem occurs only at some particular places where there is a space or a semicolon. After decryption , the result is only partial and the whole plain text is not retrieved. Any pointers on what I am doing wrong here? All help is highly appreciated.
Thanks a lot in advance
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
Hi Firstly would this code work in C++.NET or no ? At the moment i tried this over borland and it gives me error of undefined exception function. I guess borland doesnt use #inlcude . How can i correct this problem ?
And lastly how to test this application. Is it console based or do i hv to add extra code to encode n decode...for GUI or console... Please help me out in this. Thanks
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
hello, i want to implement the code in a MFC application, but when i try to compile it, i get always the same error: error C2512: 'CBlowFish' : no appropriate default constructor available
what's wrong there? i'm using VS 2005 if this is necessary.
thank you a lot, tsx
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Probably the problem is, that you will have to support an initialisation when you create an instance, so that the (right) constructor will be called:
CBlowFish BlowFish( (unsigned char*)"Password", 8 );
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I encrypted text using password "aaaa" and decrypted it with password "aaa".
char buf[] = "Test it!"; CBlowFish bf((unsigned char*)"aaaa", 4); bf.Encrypt((unsigned char*)buf, strlen(buf));
CBlowFish bf2((unsigned char*)"aaa", 3); bf2.Decrypt((unsigned char*)buf, strlen(buf));
How is that possible? Is it feature of blowfish? Is there any possibility to resolve this?
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
After inspecting the code, I saw that when using the inputted key to modify the algorithm's internal key structure...it needs to do it in 4-byte increments. When your key doesn't round perfectly what it ends up doing is wrapping around back to the front to fill in the last few bytes. So, 'aaaa' would work the same as 'aaa', but not the same as 'aaaaa'.
|
| Sign In·View Thread·PermaLink | 2.00/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
i got the following error when i try to compile the program
d:\blowfish\test\blowfish.cpp(607) : fatal error C1010: unexpected end of file while looking for precompiled header directive Generating Code... Error executing cl.exe.
Any suggestions? tnx...
quistiun
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Go to menu Project|Settings. Expand your project and look for blowfish.cpp in your project and click it. On the right pane, click C/C++ tab. On the Category Select 'Precompiled Headers'. Click 'Not using a precompiled header' then click Ok.
Hope this will help you.
"We don't see things how they are. We see things as we are." -Talmud
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
tnx, it works. One more thing, what does it means precompiled header? Sorry, im new in c++ programming...
quistiun
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hello.
We would like to use your sources in commercial projects. Can we use them free? Without any issures?
And is it possible to receive confirming for free using in our software?
thanks, Andrei Levin, mailto:andrei.levin@muehlbauer.de ------------------------------------------------ Muehlbauer AG, Germany; Software Development. Phone ++49 (9461) 952-574 http://www.muehlbauer.de ------------------------------------------------
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hi,
maybe, i am , because i'm very helpless.
I have used the this BlowFish implementation in a C++-Programm. My Ppoblem is: When i don't know long is the original decrypted String, which value have the third parameter of "Decrypt(const unsigned char* in, unsigned char* out, size_t n, int iMode=ECB);"? ... i have no crystal ball an i'm not an visionary
Every help is most welcome!
Thank you in advance!
cu Claus
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
you would probably be able to count the elements in the character array returned.
i once had a problem with this, so i created a function for this:
int Count(char* array) { int a = 1; for (;;a++) { if (&array[a] == 0) break; } return a; }
input the buffer, and the integer returned should be the size of the string. if there are any problems, just reply.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
hi there, currently i am working on a server/client which uses blowfish to encrypt/decrypt the message protocal. the problem i am facing is i was trying to implement code but the result doesn't looks right. encrypted 0xEA,0xC4,0x60,0x77, 0x14,0x6A,0xBC,0x23, 0x3B,0x36,0xFC,0x34, 0xA0,0xDD,0x82,0xAF, 0xD6,0x9E,0xAB,0x38, 0x05,0xB1,0xE6,0x98, 0x0D,0x2D,0x41,0x44, 0x78,0x22,0x29,0xB6, 0x76,0x62,0x4A,0x79, 0xFE,0x01,0xED,0x06, 0x51,0xE7,0x19,0xE1, 0x35,0x1E,0xAA,0x19 should be decrypted to something like this 0x00,0x74,0x6f,0x72, 0x75,0x6e,0x65,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x63, 0x68,0x65,0x6e,0x77, 0x65,0x69,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x78,0x16,0x64,0x6e, 0x00,0x00,0x00,0x00 with the encrypt key: [;'.]94-31==-%&@!^+]\0
I have no idea why its wrong. my test code is following
#include #include #include "Blowfish.h"
using namespace std;
void main() { //TESTING Blowfish try { ofstream out("out.txt", ios::trunc); char ENCRYPTKEY[] = "[;'.]94-31==-%&@!^+]"; unsigned char decrypted[] = { 0x00,0x74,0x6f,0x72,0x75,0x6e,0x65,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63, 0x68,0x65,0x6e,0x77,0x65,0x69,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x78,0x16,0x64,0x6e,0x00,0x00,0x00,0x00 };
unsigned char encrypted[] = { 0xEA,0xC4,0x60,0x77,0x14,0x6A,0xBC,0x23, 0x3B,0x36,0xFC,0x34,0xA0,0xDD,0x82,0xAF, 0xD6,0x9E,0xAB,0x38,0x05,0xB1,0xE6,0x98, 0x0D,0x2D,0x41,0x44,0x78,0x22,0x29,0xB6, 0x76,0x62,0x4A,0x79,0xFE,0x01,0xED,0x06, 0x51,0xE7,0x19,0xE1,0x35,0x1E,0xAA,0x19 }; unsigned char szDataOut[48]; CBlowFish oBlowFish((unsigned char*)ENCRYPTKEY, sizeof(ENCRYPTKEY)); //Test ECB oBlowFish.Encrypt(decrypted, (unsigned char*)szDataOut, sizeof(decrypted), CBlowFish::ECB); out <<szDataOut<<endl;
memset(szDataOut,0,sizeof(szDataOut)); oBlowFish.Decrypt(encrypted, (unsigned char*)szDataOut, sizeof(encrypted), CBlowFish::ECB); out <<szDataOut<<endl; } catch(exception& roException) { cout << "Exception: " << roException.what() << endl; } }
-- modified at 22:09 Friday 2nd September, 2005
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
I have not tested your code but looking through the documentation stated:
The function ResetChain() is used to reset the chaining block before starting a new encryption or decryption operation.
Give it a try.
CBlowFish oBlowFish((unsigned char*)ENCRYPTKEY, sizeof(ENCRYPTKEY)); //Test ECB oBlowFish.Encrypt(decrypted, (unsigned char*)szDataOut, sizeof(decrypted), CBlowFish::ECB); out <<szDataOut<<endl;
memset(szDataOut,0,sizeof(szDataOut)); oBlowFish.ResetChain(); //add this oBlowFish.Decrypt(encrypted, (unsigned char*)szDataOut, sizeof(encrypted), CBlowFish::ECB); out <<szDataOut<<endl;
"We don't see things how they are. We see things as we are." -Talmud
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|