Encrypt/Decrypt a string

Here’s my go at it. Similar to yours, except it does padding with zeroes at the end - seems to do the job well for arbitrary string legths.

StringEncryptor.h:


#ifndef __STRINGENCRYPTOR_H__
#define __STRINGENCRYPTOR_H__

#include "juce.h"

//==============================================================================

/**
  A simple class for encrypting and decrypting string data types 
  
  Example: 
  @code
  StringEncryptor se ("This is my key");
  String enc = se.encryptString (String ("Password"));
  AlertWindow::showMessageBox (AlertWindow::InfoIcon, "Blowfish encrypt", enc);
  String temp = String (T("[")) + se.decryptString (enc) + String T("]") ;
  AlertWindow::showMessageBox (AlertWindow::InfoIcon, "Blowfish decrypt", temp);
  @endcode
*/
class StringEncryptor: public BlowFish 
{
public:
	/**
		Initialise the encryptor with a key string, which will be used for 
		encryption and decryption as well. 

		@param	strKey	Encryption key
	*/
	StringEncryptor(const String& strKey);

	/**
		Default destructor. 
	*/
	~StringEncryptor() {};

	/**
		Encrypt any non-empty string. The resulting string will be padded to the
		nearest 16-character length.

		@param	str	The string to encrypt
	*/
	const String encryptString (const String& str);

	/**
		Decrypt a previously encrypted string. Returns an empty string is the parameter 
		doesn't look like an encrypted string.

		@param	str	The encrypted string we want to convert back
	*/
	const String decryptString (const String& str);
};

#endif   // __STRINGENCRYPTOR_H__

StringEncryptor.cpp:


#include "StringEncryptor.h"

StringEncryptor::StringEncryptor(const String& strKey)
: BlowFish ((uint8 *)((const char *)strKey), strKey.length()) 
{
}

const String StringEncryptor::encryptString (const String& str)
{
	if (!str.length()) 
		return String::empty;

	int iBlocksize = ((str.length()+7) / 8) * 8;
	MemoryBlock mb (iBlocksize, true);
	mb.copyFrom ((const char *)str, 0, str.length());
	for (int n=0; n<iBlocksize/8; n++) {
		encrypt ((uint32&)mb[n*8], (uint32&)mb[n*8+4]);
	}
	String strEncrypted = String::empty;
	for (int i = 0; i<iBlocksize; i++) {
		strEncrypted << String::formatted (T("%02x"), (unsigned char)mb[i]);
	}
	return strEncrypted;
}

const String StringEncryptor::decryptString (const String& str)
{
	// If encrypted string is empty or it the length is not 
	// multiples of 16, something is wrong
	if (!str.length() || (str.length() % 16))
		return String::empty;

	int iBlocksize = str.length() / 2;

	// Make sure there's a \0 at the end of the string converted from mb
	MemoryBlock mb (iBlocksize+1, true);
	
	for (int i = 0; i<str.length()/2; i++) {
		mb[i] = (char)(str.substring (i*2, i*2+2).getHexValue32());
	}
	for (int n=0; n<iBlocksize/8; n++) {
		decrypt ((uint32&)mb[n*8], (uint32&)mb[n*8+4]);
	}

	return String::createStringFromData (mb.getData(), iBlocksize+1);
}
1 Like