|
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
<br />
<br />
#include<br />
#include<br />
#include "Blowfish.h"<br />
<br />
using namespace std;<br />
<br />
void main()<br />
{<br />
try<br />
{<br />
ofstream out("out.txt", ios::trunc);<br />
char ENCRYPTKEY[] = "[;'.]94-31==-%&@!^+]";<br />
unsigned char decrypted[] = {<br />
0x00,0x74,0x6f,0x72,0x75,0x6e,0x65,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,<br />
0x68,0x65,0x6e,0x77,0x65,0x69,0x00,0x00,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,<br />
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,<br />
0x78,0x16,0x64,0x6e,0x00,0x00,0x00,0x00<br />
};<br />
<br />
unsigned char encrypted[] = {<br />
0xEA,0xC4,0x60,0x77,0x14,0x6A,0xBC,0x23,<br />
0x3B,0x36,0xFC,0x34,0xA0,0xDD,0x82,0xAF,<br />
0xD6,0x9E,0xAB,0x38,0x05,0xB1,0xE6,0x98,<br />
0x0D,0x2D,0x41,0x44,0x78,0x22,0x29,0xB6,<br />
0x76,0x62,0x4A,0x79,0xFE,0x01,0xED,0x06,<br />
0x51,0xE7,0x19,0xE1,0x35,0x1E,0xAA,0x19<br />
};<br />
unsigned char szDataOut[48];<br />
CBlowFish oBlowFish((unsigned char*)ENCRYPTKEY, sizeof(ENCRYPTKEY));<br />
oBlowFish.Encrypt(decrypted, (unsigned char*)szDataOut, sizeof(decrypted), CBlowFish::ECB);<br />
out <<szDataOut<<endl;<br />
<br />
memset(szDataOut,0,sizeof(szDataOut));<br />
oBlowFish.Decrypt(encrypted, (unsigned char*)szDataOut, sizeof(encrypted), CBlowFish::ECB);<br />
out <<szDataOut<<endl;<br />
}<br />
catch(exception& roException)<br />
{<br />
cout << "Exception: " << roException.what() << endl;<br />
}<br />
}<br />
-- modified at 22:09 Friday 2nd September, 2005
|
|
|
|
|
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));
<b>oBlowFish.ResetChain(); //add this
oBlowFish.Decrypt(encrypted, (unsigned char*)szDataOut, sizeof(encrypted), CBlowFish::ECB);
out <
|
|
|
|
|
I have a program that has text in it. When I go to save the text to a file I want to encrypt it. Then when I open it of course if I supply the right key it should decrypt it correctly. The problem I think I am having is that when I encrypt it I'm using CString GetLength() method and then making sure that it is using up the whole 8 bytes on the end (using ECB mode). But how do u know what to pass when decrypting the same text when opening the file. The file doesn't know what to use? Thanks in advance.
Jack
|
|
|
|
|
Is there a simple std::string version like
string encrypt(string input, string key);
string decrypt(string input, string key);
Or encrypt/decrypt for abritary length byte data
I think it would be a lot easier to use. Thanks.
|
|
|
|
|
internal you would to turn the string in a char array too
|
|
|
|
|
>the block of data size should be a multiple of the block size which is always 8 bytes
Hi all,
how should I handle the situation with arbitrary buffers? I can extend the input buffer by encription, but how ca I decrease the size of the output buffer by decription, if I don't know the initail size anymore?
|
|
|
|
|
|
I added the following code to the header file:
inline unsigned long CalcCryptogramSize(unsigned long dwLen, bool bPadding = true, bool bCBC = false)
{
return ((((dwLen)/8) + (((dwLen) % 8 > 0) ? 1 : ((bPadding) ? 1 : 0)) + ((bCBC) ? 1 : 0)) * 8);
}
Edit: Sorry the reply is a month late. I hope it is of help to somebody.
|
|
|
|
|
We found the Blowfish C++ source code developed by Jim Conger on http://www.schneier.com/blowfish-download.html (C++ by Jim Conger)
web site.
We are planning to use Blowfish C++ source code in one of my applications.
According to website, it is mentioned that source code is "Unpatented and royalty-free".
We have following queries in using the Blowfish source code:
1. Do we need to get any licence in using the source code?
2. If licence is not required, can we get a certificate to use it
for "unlimited commercial purpose" (Process to get the certificate)?
Please provide information for the above queries.
|
|
|
|
|
I will try to answer you.
1. no you don't have to get any licence as the author says.
2. no. I think you can't get a such a certificate.
|
|
|
|
|
Hi, this is probably something I'm doing wrong, but if I try to encrypt and decrypt with different instances of the CBlowFish component, the decryption doesn't produce the original text.
I'm using Borland C++Builde 6.0 professional.
For example, with the following code snippet (based on the original author's code), I do get symmetric encryption/decryption.
CBlowFish* bf;
bf = new CBlowFish((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);
bf->Encrypt((unsigned char*)szDataIn,
(unsigned char*)szDataOut, 48, CBlowFish::ECB);
memset(szDataIn, 0, 49);
bf->Decrypt((unsigned char*)szDataOut,
(unsigned char*)szDataIn, 48, CBlowFish::ECB);
delete bf;
BUT, if I do the following, I don't get symmetric encryption/decryption
CBlowFish* bf;
bf = new CBlowFish((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);
bf->Encrypt((unsigned char*)szDataIn,
(unsigned char*)szDataOut, 48, CBlowFish::ECB);
CBlowFish* bf2;
bf2 = new CBlowFish((unsigned char*)"1234567890123456", 16);
memset(szDataIn, 0, 49);
bf2->Decrypt((unsigned char*)szDataOut,
(unsigned char*)szDataIn, 48, CBlowFish::ECB);
delete bf;
delete bf2;
Should I expect this to work? If not, does this mean that I can't use Blowfish to encrypt on one platform and decrypt on another?
|
|
|
|
|
Hello, I have the simmilar problem. I have to decrypt a text encrypted with
mcrypt php. The first 8 bytes are not decrypted OK. The rest is OK. Did anyone encounter the same problem?
What can I do to repare this bug? And from who this bug come? From mcrypt php or this blowhfish impl?
If you want I can send you the key and encrypted text from mcrypt and decrypted text from CBlowFish.
Thanks.
|
|
|
|
|
(1) Blowfish.cpp failed compile. Around line 318, the compiler complains the variable iVal is not used. Either this variable was defined, but the code author forgot to use the variable. Or maybe we don't even need this variable at all.
(2) In the code they throw exceptions like "throw exception("Incorrect key length")". But there is no class exception defined, and std::exception is abstract and has no constructor taking one argument. So I included <stdexcept> instead, put a using std::runtime_error after the include directives, and replace "throw exception" with "throw runtime_error".
(3) The compiler complains the memcpy is not defined, so after the include directives I put a "using std::memcpy".
(4) In the constructor, it is a good idea to declare ucKey as "const unsigned char * ucKey", that is with the const.
(5) We can implement the Encrypt and Decrypt that work in place in terms of the ones that work on an external buffer. Just call Encypt(in, in, n, iMode) to encrypt in place. However, I wrote general template functions
template <class InputIter, class OutputIter> void Encrypt(InputIter begin, Iter end, int iMode=ECB);
template <class InputIter, class OutputIter> void Decrypt(InputIter begin, Iter end, int iMode=ECB);
which are useful if we want to encrypt/decrypt std::string (as we can't assume that the implementation stores strings as an array of chars though all I know of do), and other containers.
(6) We should implement easy checking. In the test driver, we could write to an ostringstream instead of an ofstream (that is, declare out as of type ostringstream). Then get the contents of the string by calling out.str(). Place the expect results into a char[] string such as
const char * expect =
"0000000000000000 0000000000000000 4EF997456198DD78\n"
"FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 51866FD5B85ECB8A\n"
...
;
And finally
const std::string actual = out.str();
bool pass = actual == expect;
cout << "pass = " << pass << "\n\n";
ofstream outfile("out.txt", ios::trunc);
outfile << "pass = " << pass << "\n\n";
outfile << actual << "\n";
outfile << expect << "\n";
(7) In the test driver, in the line
if(byte[i] >= 0 && byte[i] <= 9)
the byte[i] >= 0 is always true because byte[i] has type unsigned char. So one can just use
if(byte[i] <= 9)
|
|
|
|
|
try to add
using namespace std;
to blowfish.h for the exceptions.
|
|
|
|
|
How come, this simple piece of code, gives me problems.I reset the Chains
but still it won't work ?!
<br />
unsigned char aucKey[32];<br />
unsigned char aucPlainText[32] = { "something_text_to_decrypt_here" };<br />
unsigned char aucMyText[32];<br />
unsigned char aucCipherText[32];<br />
<br />
cout << endl << aucPlainText;<br />
<br />
CBlowFish oBlow( (unsigned char*)"abcdefgh", 8 );<br />
<br />
oBlow.ResetChain();<br />
oBlow.Encrypt( aucPlainText, aucCipherText, 32, CBlowFish::CBC );<br />
cout << endl << "enc: " << aucCipherText;<br />
<br />
oBlow.ResetChain();<br />
oBlow.Decrypt( aucCipherText, aucMyText, 16, CBlowFish::CBC );<br />
cout << endl << "dec: " << aucMyText;<br />
<br />
oBlow.ResetChain();<br />
oBlow.Decrypt( aucCipherText+16, aucMyText, 16, CBlowFish::CBC );<br />
cout << endl << "dec: " << aucMyText;<br />
|
|
|
|
|
ok, does somebody know why wouldn't CBC mode decrypt partial data blocks ? I have noticed the same problem with CBC mode in other encryption algorythms.The problem is most likely in me, I lack the knowledge to do it right, so please someone give me a hand.
|
|
|
|
|
The code for decryption is
if(iMode == CBC) //CBC mode, using the Chain
{
SBlock chain(m_oChain);
for(; n >= 8; n -= 8)
{
BytesToBlock(buf, work);
work ^= chain;
Encrypt(work);
chain = work;
BlockToBytes(work, buf+=8);
}
}
Everytime you call Decrypt, the system sets the local variable chain to m_oChain. Looking at the code, we see that m_oChain is never changed in any function (which implies that the function ResetChain has no effect).
Thus if you call decrypt twice, the local variable chain is initialized, used to decrypt the first block which chages the variable chain. The desired behavior is to use the new value of chain to decrypt the second block. Hence the loop.
But if you call Decrypt once yourself to decrypt each block, the local variable chain gets initialized to m_oChain all over again. Thus you lose the effect of chaining, and cannot decrypt.
The same holds for encrypting (ie. you have to encrypt everything at once), and CFB mode.
One may try to change the code to set m_oChain = chain at the end.
if(iMode == CBC) //CBC mode, using the Chain
{
SBlock chain(m_oChain);
for(; n >= 8; n -= 8)
{
BytesToBlock(buf, work);
work ^= chain;
Encrypt(work);
chain = work;
BlockToBytes(work, buf+=8);
}
m_oChain = chain;
}
I think this is what the original code author may have intended. In this case, the function ResetChain makes sense.
|
|
|
|
|
Hello,
I would like to use this class with the Borland's C++. When compiling some errors occur related to the "exception" class and the ambiguity between Byte and System:Byte.
Can anyone tell me how can I do this?
Thank You and Best Regards,
Marius
|
|
|
|
|
Just replace the 'Byte' with 'System:Byte'
|
|
|
|
|
Sorry, i was wrong. I am noob. Correct solution is to change the 'Byte' to 'Char'
|
|
|
|
|
See my recent new thread about compile errors. One must replace the use of std::exception with std::runtime_error or an equivalent. As for Byte, the function is defined in BlowFish.h as an inline function at global scope. The compiler did compile my code correctly.
|
|
|
|
|
I'm a bit unsure about this:
Am I allowed to use this code in my open source project? I'm developing a mail server (www.hmailserver.com) and liked this blowfish implementation.
|
|
|
|
|
Hi !
I used this class to make a simple file encryption utility.The encryption part is working fine , and the resultant file size etc is absolutely as calculated.However , decryption was not working.While looking around my source code , and that of the author, i found some interesting stuff which i could not explain.They seem to be causing the error in my case.Please scroll down to see the code snippets and the outputs.Can anyone explain why they are , well, the way they are ??
//////////////start of snippet///////////////////////////////////////////
CBlowFish oBlowFish((unsigned char*)key, 16);<br />
char szDataIn[8];<br />
char szDataIn2[8]="\0\0\0\0";<br />
memcpy(szDataIn,block1,8);<br />
MessageBox(szDataIn);<br />
char szDataOut[17] = "\0\0\0\0\0\0\0\0";<br />
<br />
oBlowFish.Encrypt((unsigned char*)szDataIn, (unsigned char*)szDataOut, 8);<br />
memset(szDataIn2, 0, 8);<br />
<br />
<br />
<br />
<br />
oBlowFish.Decrypt((unsigned char*)szDataOut,(unsigned char*)szDataIn2, 8);<br />
<br />
MessageBox(szDataIn2);<br />
fwrite(&szDataOut,sizeof(szDataOut),1,fp3);<br />
/////////////end of snippet///////////////////////////////////////////
here , i am using fread to read 8 bytes of data into the variable block1, which i am copying to szDataIn.After encrypting the output is coming into the variable szDataOut.I am taking that as an input to decrypt the string , and saving it into szDataIn2 , which is initialised as you can see.Now ,szDataIn and szDataIn2 should be the same , but it isn't.if szDataIn is "whatever", then szDataIn2 is coming out as seen by MessageBox(szDataIn2) is "whateverwhatever".Like the outputting is concatenating to itself.What bewilders me more is how could a 16 char string be the output ,when i already initialised szDataIn2 's dimension as 8 ?The second thing is that if i change the target variable of the encryption function from szDataIn2 to szDataIn , the output is coming correctly !
Now the second snippet ( part1 ) :
here block1 is initialised as char block1[8];
CBlowFish oBlowFish((unsigned char*)key, 16);<br />
char szDataIn[8];<br />
char szDataIn2[8]="\0\0\0\0";<br />
memcpy(szDataIn,block1,8);<br />
MessageBox(szDataIn);<br />
char szDataOut[17] = "\0\0\0\0\0\0\0\0";<br />
<br />
oBlowFish.Encrypt((unsigned char*)szDataIn, (unsigned char*)szDataOut, 8);<br />
<br />
<br />
<br />
fwrite(&szDataOut,sizeof(szDataOut),1,fp3);<br />
this is a part to encrypt a 8 byte data block.which i am writing to a file as you can see.The decryption part is as follows(2nd snippet part 2 )
here block1 is initialised as char block1[17]; :
fread(&block1,sizeof(block1),1,fp2);<br />
CBlowFish oBlowFish((unsigned char*)key, 16);<br />
char szDataIn[8]="\0\0\0\0";<br />
char szDataOut[17] ;<br />
memcpy(szDataOut,block1,17);<br />
memset(szDataIn, 0, 8);<br />
oBlowFish.Decrypt((unsigned char*)szDataOut, (unsigned char*)szDataIn, 8);<br />
fwrite(&szDataIn,sizeof(szDataIn),1,fp3);
Although a MessageBox() shows me that the output for each block in the encryption snippet , is same as the data that i am reading into the variable block1, and subsequently copying to the variable szDataOut.Still , the decryption function is not giving me the original text back , which i passed onto the encryption function. Here , the output is not even near to the input.It's a lot of gibberish.the padding is not the problem , because it is not even able to read the first block.
Can anyone point out where i went wrong ?Got kinda stuck back in here
Thanks in advance.
Regards
Kane
"Some guys hack just to get themselves a girlfriend.What a pathetic reason , huh ? "
|
|
|
|
|
char szDataOut[17] = "\0\0\0\0\0\0\0\0";
...
oBlowFish.Decrypt((unsigned char*)szDataOut,(unsigned char*)szDataIn2, 8);
...
MessageBox(szDataIn2);
szDataIn2 is 17 chars long, but you decrypt 8 bytes into it. Then you print szDataIn2, which could print an infinite number of chars, assuming the string is not null terminated.
Try this instead:
char szDataIn[9];
char szDataIn2[9];
memcpy(szDataIn,block1,8);
szDataIn[8] = 0;
MessageBox(szDataIn);
char szDataOut[9];
oBlowFish.Encrypt((unsigned char*)szDataIn, (unsigned char*)szDataOut, 8);
oBlowFish.Decrypt((unsigned char*)szDataOut,(unsigned char*)szDataIn2, 8);
szDataIn2[8] = 0;
MessageBox(szDataIn2);
|
|
|
|
|
Hello all,
could you please let me know how to execute the program without using VC++ in only c++. I have done this implementation as my project earlier. But when I faced the interview, the question, I got was "WHY HAVE YOU IMPLEMENTED THIS PROGRAM, AS MicroSoft itself provides security to files, THEN WHY TO USE MS VC++. Please reply, thank you in advance.
Athar Hussain
|
|
|
|
|