0

I'm using Botan library for AES encryption/decryption in C++. I cannot use the output of Botan in phpseclib with accurate results. I would appreciate if someone points me a working code for interoperability between Botan and phpseclib or any other PHP encryption library. Thanks!

Example of encryption with Botan in C++

// Key
std::auto_ptr<Botan::HashFunction> tHash ( Botan::get_hash("SHA-256")  );
std::string mykey = "test";
Botan::SecureVector<Botan::byte> tSecVector(32);
tSecVector.set(tHash->process(mykey)); //the hash is actually the key - same size
Botan::SymmetricKey key(tSecVector); 
// IV
Botan::InitializationVector iv(mRng, 16);

// Encryption & Encode
Botan::Pipe pipe(Botan::get_cipher("AES-256/CBC", key, iv, Botan::ENCRYPTION) );
pipe.process_msg(pStdStringTextToEncrypt);
Botan::Pipe pipeb64enc(new Botan::Base64_Encoder );
pipeb64enc.process_msg(pipe.read_all(0));
std::string StrBase64Encoded = pipeb64enc.read_all_as_string(0);

// Return
pReturnEncryptedText = iv.as_string() + StrBase64Encoded;

Example of decryption in php using phpseclib library:

include('Crypt/AES.php');
$aes = new Crypt_AES(CRYPT_AES_MODE_CBC); //mcrypt is used
//Decrypt request from application. [IV 32 CHARS IN HEX] [BASE64 ENCRYPTED TEXT]
$aes->setKeyLength(256);
$key = hash('sha256','test', true) ; // true to output raw binary output
$aes->setKey($key);
//Iv
$IV = hex2bin (substr($_POST['ENC'],0,32) );
$aes->setIV(  $IV    );
// Encrypted text in binary
$encryptedTextBin = base64_decode(substr($_POST['ENC'],32));
$decryptedRequest = $aes->decrypt( $encryptedTextBin );

echo $decryptedRequest; //no match

I also tried mcrypt in php directly with no success:

$decrypted_data="";
//128 is a hack as shown on: http://kix.in/2008/07/22/aes-256-using-php-mcrypt/
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
mcrypt_generic_init($td, $key, $iv);

$decrypted_data = mdecrypt_generic($td, $encryptedtext);

mcrypt_generic_deinit($td);
mcrypt_module_close($td);

EDIT:

I just tested in 128 bit for both Botan and phpseclib and I get a proper decryption in about 50% of cases. This is so weird. I tested different padding modes in Botan (CTS,PKCS7,OneAndZeros,X9.23) but again the success is only in 50% of the attempts.

Marcus Frenkel
  • 691
  • 10
  • 19

2 Answers2

1

It'd help if you posted a sample of a key you're using from Botan, the password (ie. pre-hashing), the IV you're using and plaintext you're using / ciphertext you're getting. That'd let people test various possibilities themselves instead of having you do everything on their behalf.

Anyway, my first guess would be that Botan maybe doesn't pad by default whereas phpseclib assumes, by default, that the plaintext has been padded.

neubert
  • 15,947
  • 24
  • 120
  • 212
  • I tried all the padding modes in Botan (in CBC it defaults to PKCS #5/#7 compatible padding). It seems that phpseclib & mcrypt only support PKCS#1 which is not supported by Botan. However I can leave with the padding issue, as far as I know it affects only the last block of plaintext. In my case the decrypted text is only a garbage of characters not anything close to the original text. – Marcus Frenkel Feb 13 '13 at 23:58
  • mcrypt null pads stuff - it doesn't do PKCS1 padding unless a wrapper does it. In the case of phpseclib.. you can disable padding and write your own function to pad as your see fit. – neubert Feb 14 '13 at 03:26
  • I implemented correct padding based on: http://www.coderelic.com/2011/10/aes-256-encryption-with-php/. Still the results are random. I also tried php openssl but still the results are random, once will succeed once not. I suspect that the issue is in Botan and I cannot change that library :( – Marcus Frenkel Feb 14 '13 at 03:48
  • Well as I said you could also post some sample keys / plaintext's / ciphertext's... – neubert Feb 14 '13 at 07:32
  • I solved the issue, it was related to Base64 encoded text sent in POST data. I any case thank you for your attention. – Marcus Frenkel Feb 18 '13 at 12:40
1

I finally solved the issue. The encrypted text is sent in Base64 format in the POST data to a certain web server. There are chars in Base64 that are invalid URL chars, so I percent encode them before sending the encrypted text as post data. Those chars are: '+', '/' and '='. See: http://en.wikipedia.org/wiki/Base64#URL_applications

Marcus Frenkel
  • 691
  • 10
  • 19