I needed this function and couldn’t find it, so here’s my solution. First the class declaration:
class Crypto
{
public:
static String encrypt(String plaintext);
static String decrypt(String ciphertext);
};
Next, is the key which was generated by a real h/w random number generator:
#define KeySize 72
static uint8 cryptokey[KeySize] =
{
117,129,49,21,6,
108,245,113,110,240,
173,174,17,158,14,
116,39,120,34,242,
74,43,101,9,179,
212,218,203,145,1,
63,24,56,68,67,
253,114,195,178,213,
238,67,20,144,11,
208,115,49,234,231,
186,228,44,246,118,
213,213,75,112,126,
216,178,216,138,139,
85,200,251,16,30,
175,170
};
Finally, here’s the implementation of the encrypt and decrypt methods:
[code]
/*
- encrypts a string using the BlowFish algorithm
-
- If the string has an even number of characters,
- then the letters ‘ev’ are appended before encrypting.
- If the string has an odd number of characters,
- then the letter ‘o’ is appended before encrypting.
- This allows decrypt to determine if the original
- string had an odd number of characters or not.
- This is necessary because BlowFish encrypts pairs of ints
-
*/
String Crypto::encrypt(String plaintext)
{
BlowFish bf(cryptokey, KeySize);
int len = plaintext.length();
// make buffers an even length so we always have left and right ints
if(len % 2 == 0)
{
plaintext += "ev";
len += 2;
}
else
{
plaintext += "o";
len += 1;
}
String cyphertext = String::empty;
for(int i = 0; i < len; i += 2)
{
uint32 l = (uint32)plaintext[i];
uint32 r = (uint32)plaintext[i+1];
bf.encrypt(l, r);
cyphertext += String::formatted(T("%08x"), l) + String::formatted(T("%08x"), r);
}
return cyphertext;
}[/code]
[code]/*
- decrypts a string using the BlowFish algorithm
-
- If the original plaintext string hasd an even number of characters,
- then the letters ‘ev’ were appended before encrypting.
- If the string had an odd number of characters,
- then the letter ‘o’ was appended before encrypting.
- This allows decrypt to determine if the original
- string had an odd number of characters or not.
- This is necessary because BlowFish encrypts pairs of ints
-
*/
String Crypto::decrypt(String ciphertext)
{
BlowFish bf(cryptokey, KeySize);
int len = ciphertext.length();
String plaintext = String::empty;
for(int i = 0; i < len; i += 16)
{
String hex = ciphertext.substring(i, i+8);
uint32 l = hex.getHexValue32();
hex = ciphertext.substring(i+8, i+16);
uint32 r = hex.getHexValue32();
bf.decrypt(l, r);
//concatenate, but ignore 0s (which may arise because we padded everything to 8 bytes
if(l != 0)
plaintext += String::createStringFromData(&l, 4);
if(r != 0)
plaintext += String::createStringFromData(&r, 4);
}
// adjust plain text by removing appended ‘ev’ or 'o’
len = plaintext.length();
if(plaintext[len-1] == ‘o’)
plaintext = plaintext.substring(0, len-1);
else
plaintext = plaintext.substring(0, len-2);
return plaintext;
}[/code]