5

I recently used a Python script to encrypt a string. But could not decrypt it in C++ using Crypto++. I just compared generated encrypted strings and found they are not the same. Anybody can help?

Here is my Python code:

key  = "0123456789abcdef"
data = "ccccccccccccccccdddddddddddddddd"
iv = "aaaaaaaaaaaaaaaa"
encryptor = AES.new(key, AES.MODE_CBC, iv)
enc = encryptor.encrypt(data)
print enc

Here is my C++ code:

std::string key = "0123456789abcdef";
std::string iv  = "aaaaaaaaaaaaaaaa";


std::string plaintext = "ccccccccccccccccdddddddddddddddd";
std::string ciphertext;
std::string decryptedtext;

std::cout << "Plain Text (" << plaintext.size() << " bytes)" << std::endl;
std::cout << plaintext;
std::cout << std::endl << std::endl;

CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, (byte *)iv.c_str() );

CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) );
stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1 );
stfEncryptor.MessageEnd();

std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl;

for( int i = 0; i < ciphertext.size(); i++ ) {

    std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
}

CryptoPP::AES::Decryption aesDecryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, (byte *)iv.c_str() );

CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();

std::cout << "Decrypted Text: " << std::endl;
std::cout << decryptedtext;
std::cout << std::endl << std::endl;
bluish
  • 26,356
  • 27
  • 122
  • 180
user562549
  • 181
  • 3
  • 12
  • 1
    can you also show the output from both programs? – Philip Potter Jan 08 '11 at 08:43
  • 1
    This is the Python's output in hex format:8e6be65a111ee7a34c105e8cf2147d57796352a03f24971983c1af2990e5f70 and This is the C++'s output in hex: 8e6be65a111ee7a34c105e8cf2147d57796352a03f24971983c1af2990e5f70368a81d8c3a611795d7974b9c31bdd19 – user562549 Jan 16 '11 at 13:47

1 Answers1

4

By default, Crypto++ employs PKCS5 padding to the plaintext strings. This adds padding to the end of the string to make sure the string is a multiple of the block size which, for AES, is 16 bytes. If the plaintext is already a multiple of 16, Crypto++ adds another 16 bytes of padding to the plaintext and then encrypts the whole thing. PyCrypto doesn't add this extra padding, leaving it up to the user to ensure the correct block size. Note that when you decrypt the Crypto++-encrypted cipher text, the extra padding is automatically removed.

bluish
  • 26,356
  • 27
  • 122
  • 180
sizzzzlerz
  • 4,277
  • 3
  • 27
  • 35
  • Thanks. But is this possible to deactive this padding process in Crypto++ to make it compatible with pycrypto? Because as U know I want to encrypt the string with pycrypto and decrypt it in Crypto++. – user562549 Jan 28 '11 at 14:36
  • Yes, when you instantiate the StreamTransformationFilter, there is an argument in the constructor that is defaulted to apply the padding. Instead of leaving it to the default value, include the argument with the appropriate value to omit padding. Have a look at the documentation for this class on the crypto++ web site. That said, however, you must add your own padding to the string if the length is not a multiple of the block size. Your example above just so happens to meet this requirement so it would work but, in the general case, it won't. – sizzzzlerz Jan 28 '11 at 14:45