我很难实施blowfish encryption algorythm。
有人可以向我解释, 如果这是加密发生的功能:
void encrypt (uint32_t & L, uint32_t & R) {
for (int i=0 ; i<16 ; i += 2) {
L ^= P[i];
R ^= f(L);
R ^= P[i+1];
L ^= f(R);
}
L ^= P[16];
R ^= P[17];
swap (L, R);
}
那么这样的函数会如何:
/**
*
* @param string text this is the text to be encrypted
* @return string this is encrypted text
*/
string EncryptBlowfish(string text){
//something happens here
}
答案 0 :(得分:1)
通常,您应该查看现有的加密库接口和Blowfish的理论描述,以便更好地了解这些实现之前是如何完成的,包括接口的设计。要设计一个良好的界面,你需要为你的代码提供一些不错的用例,如果没有那个独特的数据样本,你应该回到已经普遍的智慧。
例如,查看关于blowfish的crypto++页面(并向下滚动到页面末尾以跳过流和过滤器,其中显示了可以为单个字节提供的加密器的使用情况)。
将该示例向前推进,您的代码可以如下所示:
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 - 它们是最好在别处创建和管理,坚持单一责任原则。
您还应该努力将字节数组或指针作为低级加密器方法的接口,因为这是算法的运行方式,理想情况下是从字符串到字节数组的序列化(和应该卸载到一个单独的接口。 (例如,考虑对大端和小端架构之间的“字符串”的假设,或对填充的要求。)
良好的通用OOP设计一方面是一系列加密“部件”,每个部件都有一个或多或少的单一责任(序列化,填充,链接模式,密钥初始化,密钥安排等),另一方面是好的设计允许轻松创建更大的责任链构造,通过简单地观察代码来描述意图。
将完整的循环回到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)