|
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
|
|
|
|
|
hi
i do not have a big experience in C++ developement and i have used this implementation under VC++ 6.0 in order to encrypt , decrypt any string with any length. i have encoutered a problem and would like to know if you have any suggestion about it:
when i copy the Decrypted data to a temporary char table and decrypt the temporary char table , the result is not correct:
this is an example of string :
char * szDataIn1 = "Hello World Hello World Hello World Hello World Hello World Hello World Hello World";
below how i encrypt:
size_t llen = strlen(szDataIn1);//83
size_t llen2 = g_getLong(llen+1);//88 , make the buffer length MOD 8 = 0
char* sout = new char[llen2];// encrypted data
char* sin = new char[llen2]; // copy of szDataIn1
memset(sin,0,llen2);
memset(sout,0,llen2);
strcpy(sin,szDataIn1);// same result when using strncpy + strlen(szDataIn1)+1 as third arg
oFS.Encrypt((unsigned char*) sin,(unsigned char*)sout,llen2,1);
char* sout2 = new char[llen2];
memset (sout2,0,llen2);
// it will work if you comment the following line and call oFS.Decrypt((unsigned char*) sout,(unsigned char*) sout2,llen2,1)
memcpy(sout2,sout,strlen(sout));
memset(sout,0,llen2);
oFS.Decrypt((unsigned char*) sout2,(unsigned char*) sout,llen2,1);
cout<<sout<<endl;
i need to make a copy in a temprary table because i need to implement a com object and to convert from BSTR to char
thnak you in advance for any suggestion.
|
|
|
|
|
Hey Luc,
I believe your problem is that you use strlen(sout).
sout is not a null-terminated string.
instead of using
memcpy(sout2,sout,strlen(sout));
try to use
memcpy(sout2,sout,llen2);
for the same reason
memset(sout,0,llen2);
is useless.
Also i think you have a problem with your paddind.
try something like this (untested):
strcp(data,input);
len=strlen(data);
pad = 8-(len%8);
pad = pad?pad:8;
memset(data+len,pad,pad);
len+=pad;
Encrypt(data,cipher,len);
Decrypt(cipher,data,len)
pad=data[len-1];
memset(data+len-pad,pad,0);
/NL
nirl at realcommerce dot co dot il
|
|
|
|
|
Would a CString interface be a good idea? That way your users would not have to worry over padding their data.
So like this:
CString Encrypt(const char *);
A good idea yes? How could this be done?
|
|
|
|
|
I've added a CString interface to the original project.
You will need to add the functions to the class definition.
public:
CString Encrypt(CString in, int iMode=ECB);
CString Decrypt(CString hex, int iMode=ECB);
private:
char *Char2Hex(const unsigned char ch, char* szHex);
unsigned char Hex2Char(const char* szHex);
NOTE: There is a "similar overload functions" problem for the old
encrypt if you dont pass a mode. I dont have time or
need to fix it now
===================================
Add to blowfish.h
===================================
inline char *CBlowFish::Char2Hex(const unsigned char ch, char* szHex)
{
unsigned char byte[2];
byte[0] = ch/16;
byte[1] = ch%16;
for(int i=0; i<2; i++)
{
if(byte[i] >= 0 && byte[i] <= 9)
szHex[i] = '0' + byte[i];
else
szHex[i] = 'A' + byte[i] - 10;
}
szHex[2] = 0;
return szHex;
}
inline unsigned char CBlowFish::Hex2Char(const char* szHex)
{
char rch = 0;
for(int i=0; i<2; i++)
{
if(*(szHex + i) >='0' && *(szHex + i) <= '9')
rch = (rch << 4) + (*(szHex + i) - '0');
else if(*(szHex + i) >='A' && *(szHex + i) <= 'F')
rch = (rch << 4) + (*(szHex + i) - 'A' + 10);
else
break;
}
return rch;
}
===================================
Add to blowfish.cpp
===================================
CString CBlowFish::Encrypt(CString in, int iMode) {
CByteArray cbaData;
DWORD len,pad;
BYTE *data;
CString cipher;
char hex[3];
len = in.GetLength();
pad = 8-(len%8);
cbaData.SetSize(len+9);
data = cbaData.GetData();
CopyMemory(data,(LPCTSTR)in,len);
pad = pad?pad:8;
FillMemory((void *)(data+len),pad,(BYTE)pad);
len+=pad;
Encrypt((unsigned char *)data, len, iMode);
for ( int i=0; i < len; i++ ) {
cipher += (CString)Char2Hex((const unsigned char)data[i],hex);
}
return cipher;
}
CString CBlowFish::Decrypt(CString hex, int iMode) {
CByteArray cbaData;
BYTE *data;
DWORD len, pad;
len=hex.GetLength()/2;
cbaData.SetSize(len+1);
data=cbaData.GetData();
for ( int i=0; i < len; i++ ) {
data[i]=Hex2Char((LPCTSTR)hex.Mid(i*2,2));
}
Decrypt(data,len,iMode);
pad = data[len-1];
FillMemory((void *)(data+len-pad),pad,0);
return (CString)data;
}
best regards
/NL
nirL at realcommerce dot co dot il
|
|
|
|
|