0

I need to encrypt a URL. According the specs of the URL it should be (Rijndael) encoded using CBC encryption mode, using an IV of 0., PKCS7 padding and a key length of 128-bit.

The decryption of the URL is done in a .NET environment using the RijndaelManaged class. I encrypt using OpenSSL 1.0.2a (C++ unmanaged) and use the following code (from the internet):

// ctx holds the state of the encryption algorithm so that it doesn't
// reset back to its initial state while encrypting more than 1 block.
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);

unsigned char key[] = {0x41, 0x41, 0x45, 0x43, 0x41, 0x77, 0x51, 0x46, 
                                    0x43, 0x67, 0x63, 0x49, 0x43, 0x5A, 0x6F, 0x4C };
unsigned char iv[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
assert(sizeof(key) == 16);  // AES128 key size
assert(sizeof(iv) == 16);   // IV is always the AES block size

// If data isn't a multiple of 16, the default behavior is to pad with
// n bytes of value n, where n is the number of padding bytes required
// to make data a multiple of the block size.  This is PKCS7 padding.
// The output then will be a multiple of the block size.
std::string plain("someId=007&accountNo=119955244351&user=admin&");
std::vector<unsigned char> encrypted;
size_t max_output_len = plain.length() + 16 - (plain.length() % 16);
encrypted.resize(max_output_len);

// Enc is 1 to encrypt, 0 to decrypt, or -1 (see documentation).
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);

// EVP_CipherUpdate can encrypt all your data at once, or you can do
// small chunks at a time.
int actual_size = 0;
if( !EVP_CipherUpdate(&ctx,
                &encrypted[0], &actual_size,
                reinterpret_cast<unsigned char *>(&plain[0]), plain.size()))
{
    EVP_CIPHER_CTX_cleanup(&ctx);
}

// EVP_CipherFinal_ex is what applies the padding.  If your data is
// a multiple of the block size, you'll get an extra AES block filled
// with nothing but padding.
int final_size;
EVP_CipherFinal_ex(&ctx, &encrypted[actual_size], &final_size);
actual_size += final_size;

encrypted.resize(actual_size);

for( size_t index = 0; index < encrypted.size(); ++index )
{
    std::cout << std::hex << std::setw(2) << std::setfill('0') <<
                    static_cast<unsigned int>(encrypted[index]);
}
std::cout << "\n";

EVP_CIPHER_CTX_cleanup(&ctx);

AESWrapper aesWrapper;
std::string encryptedbase64(aesWrapper.base64encode( &encrypted[0], encrypted.size()));

I've checked (obviously) the key, the iv and the algorithm aes-cbc-128 and afaik OpenSSL uses PKCS7 padding by default, but the result doesn't match!

Striking is that the padding doesn't seem to happen in EVP_CipherFinal_ex.The padding should consist of the required number of bytes to get the correct blocksize, filling each byte with that number. But it appears to be filled with random data (or maybe more encryption?)

Is there an issue with this code, that can explain why the encryption is not 'correct'? Should I focus on the incorrect padding and how to debug in that case?

Any pointers?

Frank Kaaijk
  • 293
  • 1
  • 3
  • 12

1 Answers1

0

Nevermind. I got it working. The C# application that decrypts the URL uses a SHA1 hash on the key. After I hashed my key before encrypting the URL it started working.

Frank Kaaijk
  • 293
  • 1
  • 3
  • 12