2014-01-07 10 views
4

我已经为Crypto++ v5.6.2实施了一个C++包装库,并且有一个关于对称算法(例如Blowfish)和块模式(例如GCM)组合的问题。加密++对称算法和经过身份验证的块模式组合

我能够通过Blowfish/EAX加密和解密数据,但我无法通过使用Blowfish/GCM来实现同样的效果。 AES/EAX和AES/GCM都可以工作。

下面这个简单的应用程序演示了我的问题:

#include <iostream> 
#include <string> 

#include "cryptopp/blowfish.h" 
#include "cryptopp/filters.h" 
#include "cryptopp/eax.h" 
#include "cryptopp/gcm.h" 
#include "cryptopp/osrng.h" 
#include "cryptopp/hex.h" 

std::string encrypt(
    CryptoPP::AuthenticatedSymmetricCipher &encryption, 
    std::string const kPlainText, 
    CryptoPP::SecByteBlock const kKey, 
    unsigned const char * kIV) { 
    std::string cipher_text; 

    // TODO Is this the source of the problem? 
    // BlockSize always returns 0 which leads to an exception if GCM block mode is used! 
    std::cout << encryption.BlockSize() << " bytes" << std::endl; 

    encryption.SetKeyWithIV(
     kKey, 
     kKey.size(), 
     kIV 
); 

    CryptoPP::StringSink *string_sink = new CryptoPP::StringSink(cipher_text); 
    CryptoPP::BufferedTransformation *transformator = NULL; 

    // The AuthenticatedEncryptionFilter adds padding as required. 
    transformator = new CryptoPP::AuthenticatedEncryptionFilter(
     encryption, 
     string_sink); 

    bool const kPumpAll = true; 
    CryptoPP::StringSource(
     kPlainText, 
     kPumpAll, 
     transformator); 

    return cipher_text; 
} 

std::string decrypt(
    CryptoPP::AuthenticatedSymmetricCipher &decryption, 
    std::string const kCipherText, 
    CryptoPP::SecByteBlock const kKey, 
    unsigned const char * kIV) { 
    std::string recovered_plain_text; 

    decryption.SetKeyWithIV(
     kKey, 
     kKey.size(), 
     kIV); 

    CryptoPP::StringSink *string_sink = new CryptoPP::StringSink(
     recovered_plain_text); 
    CryptoPP::BufferedTransformation *transformator = NULL; 
    CryptoPP::AuthenticatedDecryptionFilter *decryption_filter = NULL; 

    decryption_filter = new CryptoPP::AuthenticatedDecryptionFilter(
     decryption, 
     string_sink); 
    transformator = new CryptoPP::Redirector(*decryption_filter); 

    bool const kPumpAll = true; 
    CryptoPP::StringSource(
     kCipherText, 
     kPumpAll, 
     transformator); 

    return recovered_plain_text; 
} 

int main() { 
    CryptoPP::AutoSeededRandomPool prng; 
    CryptoPP::SecByteBlock key(CryptoPP::Blowfish::DEFAULT_KEYLENGTH); 
    prng.GenerateBlock(key, key.size()); 

    byte iv[CryptoPP::Blowfish::BLOCKSIZE]; 
    prng.GenerateBlock(iv, sizeof(iv)); 

    // Creates templated mode objects of block ciphers. 

    // This works... 
// CryptoPP::EAX<CryptoPP::Blowfish>::Encryption encryption; 
// CryptoPP::EAX<CryptoPP::Blowfish>::Decryption decryption; 

    // This does NOT work... 
    CryptoPP::GCM<CryptoPP::Blowfish>::Encryption encryption; 
    CryptoPP::GCM<CryptoPP::Blowfish>::Decryption decryption; 

    std::string plain_text = "Block Mode Test"; 
    std::string cipher_text = encrypt(encryption, plain_text, key, iv); 
    // terminate called after throwing an instance of 'CryptoPP::InvalidArgument' 
    // what(): Blowfish/GCM: block size of underlying block cipher is not 16 

    std::cout << "cipher text: " << std::hex << cipher_text << std::endl; 
    std::cout << "recovered plain text: " << decrypt(decryption, cipher_text, key, iv) << std::endl; 
} 

一个CryptoPP::InvalidArgument异常被抛出,如果运行上面下面的文本代码:

Blowfish/GCM: block size of underlying block cipher is not 16 

但随着块运行代码的时候,而不是模式EAX,不会引发异常。所以我的问题是:

  • 是否GCM只适用于AES? GCM也可以与Blowfish或3DES一起使用吗?
  • 是否有可用的矩阵列出了对称算法与块模式的所有可能组合?
  • 或者这是Crypto ++中的错误吗?因为方法BlockSize()总是返回0但是只有在使用Blowfish(或3DES)而不是AES时才会引发异常。这似乎引起了所提到的例外。

回答

4

GCM已被设计为与一起使用的128位(= 16字节)块大小仅限于。你可以在5.1节的original paper中找到它。

Blowfish是一个64位块大小算法,所以这两个不兼容作为“开箱即用”认证的加密组合。 3DES也是如此。这个异常不是Crypto ++中的一个错误。

GCM将与其他具有128位块大小的Crypto ++对象一起使用。它们包括AESCast-256,RijndaelCameilla,MARS,SerpentTwofish。一个块大小表可在Applied Crypto++: Block Ciphers

GCM不适用于更大的块大小。例如,RijndaelAES的父级)提供192位和256位块大小(AES仅指定128位块大小)。 GCM不适用于较大的块大小。对于SHACAL-2也是如此,具有256位块大小。

Crypto ++的BlockSize()有时返回0(它与模板参数有关)。相反,使用编译时间常量,如AES::BLOCKSIZECamellia::BLOCKSIZERijndael::BLOCKSIZE。这可能被认为是一个错误。

相关问题