Как правило, вам следует просмотреть существующие интерфейсы библиотек шифрования и теоретическое описание Blowfish, чтобы лучше понять, как эти реализации были реализованы ранее, включая дизайн интерфейса. Чтобы спроектировать хороший интерфейс, вам нужно найти приличное количество вариантов использования для вашего кода, и в отсутствие этого образца данных, уникального для вашего случая, вы должны вернуться к уже общепринятой мудрости.
Например, взгляните на страницу crypto++ для blowfish (и прокрутите страницу до конца). чтобы пропустить потоки и фильтры, где показано использование шифровальщика, который может передавать отдельные байты).
Продолжая этот пример, ваш код может выглядеть так:
class StatefulBlowfish {
private:
BlowfishKey key_;
BlowfishIv iv_;
public:
void EncryptCBC(string text, /*out*/ byte*){
for (int i=0; I < text.size(); i++) {
// process and xor an individual ‘(byte)text[i]’ the
// necessary number of rounds. Consider padding.
}
...
}
Но такой класс не очень общий и имеет много фиксированных частей, которые могут затруднить его тестирование, использование и поддержку. Еще одна важная вещь, которую следует учитывать, заключается в том, что интерфейс, который вы должны разработать, не ограничивается использованием строки для шифрования, как вы предлагаете в вопросе, а скорее должен учитывать режим цепочки, ключ и iv - они лучше всего создавать и управлять в другом месте, чтобы придерживаться принципа единой ответственности.
Вы также должны стремиться иметь массивы или указатели на массивы байтов в качестве интерфейса ваших низкоуровневых методов шифрования, потому что именно так работает алгоритм, и в идеале сериализация из строки в массив байтов (и наоборот) должна быть выгружены на отдельный интерфейс. (Рассмотрите, например, предположения о «строке» между архитектурами с прямым порядком байтов и прямым порядком байтов или требования к заполнению.)
Хороший общий ООП-проект — это, с одной стороны, набор «частей» шифрования, каждая из которых несет более или менее единственную ответственность (сериализация, заполнение, режим цепочки, инициализация ключа, расписание ключей и т. д.), а с другой стороны, хороший дизайн допускает простое создание более крупной конструкции цепочки ответственности, которая описывает намерение, просто наблюдая за кодом.
Возвращаясь к cryptopp, изменив стандартный пример кода для большей ясности, посмотрите, как все обрабатывается по отдельности:
// a key is created, to be separately initialised with a PRNG
// or from a secure source, hardware TRNG, etc.
SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH);
...
// an iv is created, similarly to be separately initialised with a PRNG
byte iv[Blowfish::BLOCKSIZE];
...
// Wrap blowfish low-level implementation in a CBC chaining mode
// and initialise it with the key and iv
CBC_Mode<Blowfish>::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
...
// have a separate padding wrapper
... new StreamTransformationFilter(e, /*out*/ cipher)
person
mockinterface
schedule
24.03.2014
key_schedule
предоставленной вами ссылки, вы увидите, где происходит шифрование. Функцияencrypt
работает с двумя последовательными словами в блоке. - person Zac Howland   schedule 23.03.2014