Reputation: 1
I'm trying to send data from my Android application to my Apache2 server running PHP 5.5 while having AES-128 encryption/decryption on both sides.
The weird thing is when I run the java code on Eclipse to encrypt the data (as a test) and take the encrypted result to decrypt it using PHP on Netbeans, it works just fine. Transferring the code to Android also gives the same encrypted results, but the decryption function on the server doesn't give back any results, it just gives a null, I'm using the exact same code I used on Netbeans which worked.
Here's the code
if(isset($_POST['param']))
{
$param = $_POST['param'];
$param=decrypt($param, "57238004e784498bbc2f8bf984565090");
}
else
echo "No post Request Received";
function decrypt($encrypted, $key) {
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, hex2bin($key),hex2bin($encrypted), MCRYPT_MODE_ECB);
echo $decrypted;
$padSize = ord(substr($decrypted, -1));
return substr($decrypted, 0, $padSize*-1);
}
echo $decrypted gives a null and the return as well.
Example: Cipher: 269B3F5A2208C533AACB51243CFB9CFB Decrypted to: 28
Anybody know what the problem might be?
Upvotes: 0
Views: 207
Reputation: 32272
After reading up on padding methods I can no longer take issue with the method used to pad the input, PKCS5. However, the method used to strip the padding from the output still leaves a definite possibility for introducing the error you're encountering.
This is because a 16-byte string ending in z
[ord('z') == 122
] will cause the current method to do substr($data, 0, -122);
which returns false
.
In order to be certain that the final bytes are padding you need to read the last byte, validate that the last $padSize
bytes in the output are repetitions of that byte, and only trim the string in that case.
<?php
function decrypt($encrypted, $key) {
$decrypted = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
hex2bin($key),
hex2bin($encrypted),
MCRYPT_MODE_ECB);
return unpad($decrypted);
}
function unpad($data) {
$padSize = ord(substr($data, -1));
$padStr = substr($data, strlen($data) - $padSize);
$padCheck = str_pad('', $padSize, chr($padSize));
if( strcmp($padStr, $padCheck) === 0 ) {
return substr($data, 0, $padSize*-1);
} else {
return $data;
}
}
$key = '57238004e784498bbc2f8bf984565090';
$data = '269B3F5A2208C533AACB51243CFB9CFB';
var_dump(decrypt($data, $key));
// Output: string(2) "28"
Additionally, the ECB mode is pretty much the weakest you could possibly choose. See the images at the end of the ECB section in this wikipedia article for an excellent example.
Use CBC.
Upvotes: 1