iOS/PHP kCCDecodeError - php

I can't for the life of me work out why when I encrypt something in PHP I can't then decrypt it in my iOS app, but PHP can decrypt iOS encrypted strings and decrypt/encrypt between itself.
PHP -> Obj-C FAILS.
Yes, I have looked across the net and the only solution I found was to use CBC in PHP which I'm already doing.
I'm using the FBEncryptor library for iOS and these are the encrypt/decrypt functions in PHP:
function encrypt($decrypted)
{
$iv = ''; for($i=0;$i<16;$i++){ $iv .= "\0";}
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $passKey, $decrypted, MCRYPT_MODE_CBC, $iv);
$ciphertext = base64_encode($ciphertext);
return $ciphertext;
}
function decrypt($encrypted)
{
$iv = ''; for($i=0;$i<16;$i++){ $iv .= "\0";}
$ciphertext = base64_decode($encrypted);
$plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $passKey, $ciphertext, MCRYPT_MODE_CBC, $iv);
return $plaintext;
}

From the FBEncryptor Github page (emphasis mine):
Supported encryption algorithm is AES 256 bit only.
But in your code snippet above, you're doing:
mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv);
i.e. decrypting with AES 128 bit as your cipher.
You'll need to correct your code accordingly. Other common mistakes include using mismatched padding and block cipher operation modes.

I managed to work out the problem. Was a silly mistake on my part with the pass key variable. Here is my final implementation anyway for anyone else that comes across this problem:
function encrypt($decrypted)
{
$thePassKey = "12345678901234567890123456789012";
# Add PKCS7 padding.
$str = $decrypted;
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
if (($pad = $block - (strlen($str) % $block)) < $block)
{
$str .= str_repeat(chr($pad), $pad);
}
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = ''; for($i=0;$i<$iv_size;$i++){ $iv .= "\0";}
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $thePassKey, $str, MCRYPT_MODE_CBC, $iv));
}
function decrypt($encrypted)
{
$thePassKey = "12345678901234567890123456789012";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = ''; for($i=0;$i<$iv_size;$i++){ $iv .= "\0";}
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $thePassKey, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv);
# Strip PKCS7 padding.
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = ord($str[($len = strlen($str)) - 1]);
if ($pad && $pad < $block && preg_match(
'/' . chr($pad) . '{' . $pad . '}$/', $str))
{
return substr($str, 0, strlen($str) - $pad);
}
return $str;
}

Related

I am Using AES ECB 256 padding - Encryption to send data , but Decryption i am not able to achieve

I am sending data to API and They uses Java Function, I Replicated Encryption in PHP but I am unable to Decrypt Response Data.
I tried Various Encryption but They Strictly Use this Encryption Decryption, I cannot Change Encryption I had to follow this.
Encryption Function Works Properly:
function encrypt($input, $key) {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$input = pkcs5_pad($input, $size);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
return $data;
}
function pkcs5_pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
Decryption Function I tried:
function decrypt($sStr, $sKey) {
$decrypted = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128, $sKey, base64_decode($sStr), MCRYPT_MODE_ECB
);
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s - 1]);
$decrypted = substr($decrypted, 0, -$padding);
return $decrypted;
}
As an Output I am Getting ??? which is wrong Encryption.
Do not Duplicate this As I have Searched More than 3 hours, then I posted Question.
function decrypt($sStr, $sKey) {
$decrypted = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128, $sKey, base64_decode($sStr), MCRYPT_MODE_ECB
);
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s - 1]);
$decrypted = substr($decrypted, 0, -$padding);
$decrypted = base64_encode($decrypted ); //This line Added.
return $decrypted;
}
I was getting Byte format I wasn't converting the data into base64_encode, Now It is Working.

PHP switch from MCRYPT_MODE_ECB to AES-256-ECB

I am rewriting code to be compatible with PHP 7.2. Old code is
public function encryptPasswordOld($password, $salt)
{
$key = md5($salt);
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_ECB);
return base64_encode($result);
}
New code should be according to my research something like this
public function encryptPasswordNew($password, $salt)
{
$method = 'AES-256-ECB';
$ivSize = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivSize);
$key = md5($salt);
$result = openssl_encrypt($password, $method, $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($result);
}
but I tried every combination of openssl_encrypt options: OPENSSL_RAW_DATA, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, OPENSSL_ZERO_PADDING, 0 and still ended up with different result as the old method returns
try to use pkcs5padding on value before encrypt. i.e.
remember the blocksize should be 8-byte based, i.e. 8/16/24 etc.
function pkcs5_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr(0), $pad);
}
and encrypt option should be OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, i.e.
openssl_encrypt(pkcs5_pad($value, 16), 'aes-256-ecb', $aes_key, 3, '')

PHP convert MCRYPT_ENCRYPT to OPENSSL_ENCRYPT (SOAP header)

I need to encrypt some SOAP header fields, and I currently have the following code working in a project with PHP 5.6 version.
function getBaseEncoded($data, $key)
{
$size = $this->pkcs5_pad($data, mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB));
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND);
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $size, MCRYPT_MODE_ECB, $iv);
return trim(base64_encode($result));
}
private function pkcs5_pad($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat (chr($pad), $pad);
}
What happens is that now I have in my hands a similiar project but with PHP 7, and the function MCRYPT is deprecated and I need to switch it to OPENSSL_ENCRYPT.
The code below is my first attempt:
function getBaseEncoded($data, $key)
{
$result = openssl_encrypt($data, 'AES-128-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
return trim(base64_encode($result));
}
But I'm now receiving a SOAP error with the message
SoapFault => Could not connect to host
and it got me thinking if the problem is on my new function?
You are missing some initializator vector data.
$ivsize = openssl_cipher_iv_length('AES-128-ECB');
$iv = openssl_random_pseudo_bytes($ivsize);
$ciphertext = openssl_encrypt(
$data,
'AES-128-ECB',
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
$iv
);
echo encrypt_openssl($data, $key);
function encrypt_openssl($msg, $key, $iv = null) {
$iv_size = openssl_cipher_iv_length('AES-128-ECB');
if (!$iv) {
$iv = openssl_random_pseudo_bytes($iv_size);
}
$encryptedMessage = openssl_encrypt($msg, 'AES-128-ECB', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($iv . $encryptedMessage);
}

Simple PHP Encryption / Decryption (Mcrypt, AES)

I'm looking for a simple yet cryptographically strong PHP implementation of AES using Mcrypt.
Hoping to boil it down to a simple pair of functions, $garble = encrypt($key, $payload) and $payload = decrypt($key, $garble).
I'm recently learning about this subject, and am posting this answer as a community wiki to share my knowledge, standing to be corrected.
Mcrypt Documentation
It's my understanding that AES can be achieved using Mcrypt with the following constants as options:
MCRYPT_RIJNDAEL_128 // as cipher
MCRYPT_MODE_CBC // as mode
MCRYPT_MODE_DEV_URANDOM // as random source (for IV)
During encryption, a randomized non-secret initialization vector (IV) should be used to randomize each encryption (so the same encryption never yields the same garble). This IV should be attached to the encryption result in order to be used later, during decryption.
Results should be Base 64 encoded for simple compatibility.
Implementation:
<?php
define('IV_SIZE', mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
function encrypt ($key, $payload) {
$iv = mcrypt_create_iv(IV_SIZE, MCRYPT_DEV_URANDOM);
$crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $payload, MCRYPT_MODE_CBC, $iv);
$combo = $iv . $crypt;
$garble = base64_encode($iv . $crypt);
return $garble;
}
function decrypt ($key, $garble) {
$combo = base64_decode($garble);
$iv = substr($combo, 0, IV_SIZE);
$crypt = substr($combo, IV_SIZE, strlen($combo));
$payload = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $crypt, MCRYPT_MODE_CBC, $iv);
return $payload;
}
//:::::::::::: TESTING ::::::::::::
$key = "secret-key-is-secret";
$payload = "In 1435 the abbey came into conflict with the townspeople of Bamberg and was plundered.";
// ENCRYPTION
$garble = encrypt($key, $payload);
// DECRYPTION
$end_result = decrypt($key, $garble);
// Outputting Results
echo "Encrypted: ", var_dump($garble), "<br/><br/>";
echo "Decrypted: ", var_dump($end_result);
?>
Output looks like this:
Encrypted: string(152) "4dZcfPgS9DRldq+2pzvi7oAth/baXQOrMmt42la06ZkcmdQATG8mfO+t233MyUXSPYyjnmFMLwwHxpYiDmxvkKvRjLc0qPFfuIG1VrVon5EFxXEFqY6dZnApeE2sRKd2iv8m+DiiiykXBZ+LtRMUCw=="
Decrypted: string(96) "In 1435 the abbey came into conflict with the townspeople of Bamberg and was plundered."
Add function to clean control characters (�).
function clean($string) {
return preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $string);
}
echo "Decrypted: ", clean($end_result);
Sentrapedagang.com
Simple and Usable:
$text= 'Hi, i am sentence';
$secret = 'RaNDoM cHars!##$%%^';
$encrypted = simple_encrypt($text, $secret);
$decrypted = simple_decrypt($encrypted_text, $secret);
codes:
function simple_encrypt($text_to_encrypt, $salt) {
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, pack('H*', $salt), $text_to_encrypt, MCRYPT_MODE_CBC, $iv = mcrypt_create_iv($iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND))));
}
function simple_decrypt($encrypted, $salt) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack('H*', $salt), base64_decode($encrypted), MCRYPT_MODE_CBC, $iv = mcrypt_create_iv($iv_size=mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND)));
}
Class Mycrypt
Try using this class. Here. All you need to pass is key and string.
class MCrypt
{
const iv = 'fedcba9876543210';
/**
* #param string $str
* #param bool $isBinary whether to encrypt as binary or not. Default is: false
* #return string Encrypted data
*/
public static function encrypt($str, $key="0123456789abcdef", $isBinary = false)
{
$iv = self::iv;
$str = $isBinary ? $str : utf8_decode($str);
$td = mcrypt_module_open('rijndael-128', ' ', 'cbc', $iv);
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $isBinary ? $encrypted : bin2hex($encrypted);
}
/**
* #param string $code
* #param bool $isBinary whether to decrypt as binary or not. Default is: false
* #return string Decrypted data
*/
public static function decrypt($code, $key="0123456789abcdef", $isBinary = false)
{
$code = $isBinary ? $code : self::hex2bin($code);
$iv = self::iv;
$td = mcrypt_module_open('rijndael-128', ' ', 'cbc', $iv);
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $isBinary ? trim($decrypted) : utf8_encode(trim($decrypted));
}
private static function hex2bin($hexdata)
{
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
}
How To Use
$var = json_encode(['name'=>['Savatar', 'Flash']]);
$encrypted = MCrypt::encrypt();
$decrypted = MCrypt::decrypt($encrypted);

Encrypting strings in PHP

Currently im using
$key="pass";
$val="secret";
$encp=mcrypt_encrypt(MCRYPT_DES, $key, $val, MCRYPT_MODE_ECB);
But when i call printf($encp)
No value is displayed,im using PHP version 5.2.17
Is there a better way to do it.Please help.
EDIT:
<?PHP
define('SECURE_KEY','Somekey');
function encrypt($value){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv);
}
function decrypt($value){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv));
}
$temp=encrypt("teststring");
printf($temp);
?>
Update (27/09/17):
Since mcrypt_encrypt is DEPRECATED as of PHP 7.1.0. Ive added a simple encrypt/decrypt using openssl.
function encrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// encrypt
$output = openssl_encrypt($string, $method, $key, 0, $iv);
// encode
return base64_encode($output);
}
function decrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// decode
$string = base64_decode($string);
// decrypt
return openssl_decrypt($string, $method, $key, 0, $iv);
}
$str = 'Encrypt this text';
echo "Plain: " .$str. "\n";
// encrypt
$encrypted_str = encrypt($str);
echo "Encrypted: " .$encrypted_str. "\n";
// decrypt
$decrypted_str = decrypt($encrypted_str);
echo "Decrypted: " .$decrypted_str. "\n";
Try these: (PHP < 7.1.0) If your using > PHP 7.1.0 see above.
define('SECURE_KEY','Somekey');//Assigned within a config, pref outside of root dir
function encrypt($value){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv);
}
function decrypt($value){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv));
}
//Simple usage
$encryptedString = encrypt('This String Will Be encrypted');
echo decrypt($encryptedString);
Edited from source - http://php.net/manual/en/function.mcrypt-encrypt.php
Try these PHP functions convert_uuencode and convert_uudecode:
function encrypt_decrypt ($data, $encrypt) {
if ($encrypt == true) {
$output = base64_encode (convert_uuencode ($data));
} else {
$output = convert_uudecode (base64_decode ($data));
}
return $output;
}
$enc_txt = encrypt_decrypt ("PASSWORD TEXT", true);
echo $enc_txt."\n";
// LTQkJTM0VT0vNEQwQDUkNTg1YGBgCmAK
echo encrypt_decrypt ($enc_txt, false);
// PASSWORD TEXT
This is much simpler and does not depend on libraries installed in PHP

Categories