AES 128 CBC Encryption to PHP Interface
Posted: Mon Jul 14, 2014 10:51 pm
Forum,
I'm interfacing a LiveCode Mobil App with a Web Application that is developed in PHP. Part of the interface require that I send an AES-128-cbc encrypted string as a token to verify that it is a valid request. I need to generate a token on LiveCode and Decode it on the web site. The following is the Livecode Function that is being used and the PHP function that is being used on the web site. LiveCode is using OpenSSL and PHP is using mcrypt.
I've also tried to go to several OnLine AES sites to test the output, but haven't been able to decode the
The interface is using the following PHP Function to evaluate the token.
I'm using a simple password, do I need to define the SALT and IV when I encode the TokenText?
I don't see a way to turn off the SALT, so it is automatically generated.
Would it be better to define a specific Key and IV for both sides to use? Each system may be generating the Key and IV differently.
Is there a better way to encrypt on LiveCode and decrypt on PHP?
Any direction or ideas would be helpful as I'm pulling out my hair on this one. I know the setup needs to be exact on both systems.
Thanks
dcpbarrington
I'm interfacing a LiveCode Mobil App with a Web Application that is developed in PHP. Part of the interface require that I send an AES-128-cbc encrypted string as a token to verify that it is a valid request. I need to generate a token on LiveCode and Decode it on the web site. The following is the Livecode Function that is being used and the PHP function that is being used on the web site. LiveCode is using OpenSSL and PHP is using mcrypt.
I've also tried to go to several OnLine AES sites to test the output, but haven't been able to decode the
Code: Select all
function CreateToken pTokenText
encrypt pTokenText using "aes-128-cbc" with password "TESTKEY"
put it into tTokenValue
return base64Encode( tTokenValue )
end CreateToken
Code: Select all
/**
* AES decryption in CBC mode. This is the standard mode.
*
* Supports AES-128, AES-192 and AES-256. It supposes that the last 4 bytes
* contained a little-endian unsigned long integer representing the unpadded
* data length.
*
* @since 3.0.1
* @author Nicholas K. Dionysopoulos
*
* @param string $ciphertext The data to encrypt
* @param string $password Encryption password
* @param int $nBits Encryption key size. Can be 128, 192 or 256
* @return string The plaintext
*/
public static function AESDecryptCBC($ciphertext, $password, $nBits = 128)
{
if (!($nBits==128 || $nBits==192 || $nBits==256)) return false; // standard allows 128/192/256 bit keys
if(!function_exists('mcrypt_module_open')) return false;
// Try to fetch cached key/iv or create them if they do not exist
$lookupKey = $password.'-'.$nBits;
if(array_key_exists($lookupKey, self::$passwords))
{
$key = self::$passwords[$lookupKey]['key'];
$iv = self::$passwords[$lookupKey]['iv'];
}
else
{
// use AES itself to encrypt password to get cipher key (using plain password as source for
// key expansion) - gives us well encrypted key
$nBytes = $nBits/8; // no bytes in key
$pwBytes = array();
for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
$key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
$key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long
$newKey = '';
foreach($key as $int) { $newKey .= chr($int); }
$key = $newKey;
// Create an Initialization Vector (IV) based on the password, using the same technique as for the key
$nBytes = 16; // AES uses a 128 -bit (16 byte) block size, hence the IV size is always 16 bytes
$pwBytes = array();
for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
$iv = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
$newIV = '';
foreach($iv as $int) { $newIV .= chr($int); }
$iv = $newIV;
self::$passwords[$lookupKey]['key'] = $key;
self::$passwords[$lookupKey]['iv'] = $iv;
}
// Read the data size
$data_size = unpack('V', substr($ciphertext,-4) );
// Decrypt
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, substr($ciphertext,0,-4));
mcrypt_generic_deinit($td);
// Trim padding, if necessary
if(strlen($plaintext) > $data_size)
{
$plaintext = substr($plaintext, 0, $data_size);
}
return $plaintext;
}
}
I don't see a way to turn off the SALT, so it is automatically generated.
Would it be better to define a specific Key and IV for both sides to use? Each system may be generating the Key and IV differently.
Is there a better way to encrypt on LiveCode and decrypt on PHP?
Any direction or ideas would be helpful as I'm pulling out my hair on this one. I know the setup needs to be exact on both systems.
Thanks
dcpbarrington