I am trying to implement Blowfish algorithm with CBC mode and kCCOptionPKCS7Padding padding . Scenario like performs encoding and decoding between two systems like IOS(Objective C) and PHP. But, Encryption result are not same in two platform .
Here is my objective C source code .
ViewController.m
#import "ViewController.h"
#import <CommonCrypto/CommonCryptor.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// configure paremetre
NSData *IV = [@"aaaaaaaa" dataUsingEncoding:NSUTF8StringEncoding];// Constant IV
NSError *error;
NSData *key = [@"37501370571307510" dataUsingEncoding:NSUTF8StringEncoding]; // Constant Key
NSString *stringOriginal = @"Did you decrypt it ?";
NSData *dataOriginal = [stringOriginal dataUsingEncoding:NSUTF8StringEncoding];;
// Encryption
NSData *dataEncrypted = [self doBlowfish:dataOriginal
context:kCCEncrypt
key:key
options:kCCOptionPKCS7Padding
iv:IV
error:&error];
NSString *encryptedBase64String = [dataEncrypted base64EncodedStringWithOptions:0];
// Decryption
NSData *dataToDecrypt = [[NSData alloc] initWithBase64EncodedString:encryptedBase64String options:0];
NSData *dataDecrypted = [self doBlowfish:dataToDecrypt
context:kCCDecrypt
key:key
options:kCCOptionPKCS7Padding
iv:IV
error:&error];
NSString *stringDecrypted = [[NSString alloc] initWithData:dataDecrypted encoding:NSUTF8StringEncoding];
NSLog(@"stringDecrypted %@", stringDecrypted); // Did you decrypt it ?
NSLog(@"encryptedBase64String %@", encryptedBase64String);// 8IV/2MGUY0HfwZLrd212fKNyp6AUzYl+
}
// Blowfish Encryption and Decryption
- (NSData *)doBlowfish:(NSData *)dataIn
context:(CCOperation)kCCEncrypt_or_kCCDecrypt
key:(NSData *)key
options:(CCOptions)options
iv:(NSData *)iv
error:(NSError **)error
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeBlowfish];
ccStatus = CCCrypt( kCCEncrypt_or_kCCDecrypt,
kCCAlgorithmBlowfish,
options,
key.bytes,
key.length,
(iv)?nil:iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
if (ccStatus == kCCSuccess) {
dataOut.length = cryptBytes;
}
else {
if (error) {
*error = [NSError errorWithDomain:@"kEncryptionError"
code:ccStatus
userInfo:nil];
}
dataOut = nil;
}
return dataOut;
}
@end
the encoding and decoding functionalities Working fine in Xcode .
Here is PHP code .
crypt.php
<?php
class Crypt {
public $Algo;
public $Mode;
public function __construct()
{
$this->Algo = MCRYPT_BLOWFISH;
$this->Mode = MCRYPT_MODE_CBC;
}
public function ivGenerator()
{
$ivSize = mcrypt_get_iv_size($this->Algo, $this->Mode);
$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);
return base64_encode($iv);
}
public function encrypt($data, $key, $iv)
{
$iv = base64_decode($iv);
$blockSize = mcrypt_get_block_size($this->Algo, $this->Mode);
$pkcs = $blockSize - (strlen($data)%$blockSize);
$data .= str_repeat(chr($pkcs), $pkcs);
$encrypt = mcrypt_encrypt($this->Algo, $key, $data, $this->Mode, $iv);
return rtrim(base64_encode($encrypt));
}
public function decrypt($data, $key, $iv)
{
$encrypt = base64_decode($data);
$iv = base64_decode($iv);
$decrypt = mcrypt_decrypt($this->Algo, $key, $encrypt, $this->Mode, $iv);
//$pad = ord($decrypt[($len = strlen($decrypt)) - 1]);
//return substr($decrypt, 0, strlen($decrypt) - $pad);
return $decrypt;
}
}
?>
final_encryption_test.php
public function __construct()
{
parent::__construct();
date_default_timezone_set('Asia/Dhaka');
$this->load->helper('url');
$this->load->library('crypt');
}
public function index()
{
$iv = base64_encode("aaaaaaaa"); // same IV as IOS
$key = "37501370571307510"; // Same key
$data = "Did you decrypt it ?"; // same plain text
echo "Plain Text >> " . $data;
echo "<br>";
$enc = $this->crypt->encrypt($data, $key, $iv);// Output -> xUCTX0jsB3XyDWSeyUszSbQ2t90/DNDv which is not same with objective c result
echo "Enc text >> " . $enc;
echo "<br>";
$dec = $this->crypt->decrypt($enc, $key, $iv);
echo "Dec text >> " . $dec; // Result will -> Did you decrypt it ?
}
}
// Encryption result base64encoding format IOS -> 8IV/2MGUY0HfwZLrd212fKNyp6AUzYl+
PHP -> xUCTX0jsB3XyDWSeyUszSbQ2t90/DNDv
Here Encoded result is not same in two enviornment . I am trying it from last 7 days . But do not find a solution yet .
So far I know CCCrypt is used for CBC mode . I did not understand where is my problem . Is it PHP end or IOS end ?
A little help will be much appreciated. Thanks.
The problem is you are passing nil
if your iv
is non-nil
at (iv)?nil:iv.bytes
Either it should be (iv)?iv.bytes:nil
or simple iv.bytes
because it's perfectly okay to send message to a nil
object
ccStatus = CCCrypt(kCCEncrypt_or_kCCDecrypt,
kCCAlgorithmBlowfish,
options,
key.bytes,
key.length,
(iv)?nil:iv.bytes, //This is ruining your life
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
Change above to below
ccStatus = CCCrypt(kCCEncrypt_or_kCCDecrypt,
kCCAlgorithmBlowfish,
options,
key.bytes,
key.length,
iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
I re-run your code and the output is the same as PHP i.e.
xUCTX0jsB3XyDWSeyUszSbQ2t90/DNDv
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With