Я пытаюсь реализовать алгоритм Blowfish с CBC режим и kCCOptionPKCS7Padding набивка. Подобный сценарий выполняет кодирование и декодирование между двумя системами, такими как IOS (Objective C) и PHP.
Но результат шифрования не одинаков на двух платформах.
Вот мой объективный исходный код на C.
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
Функциональность кодирования и декодирования Работает нормально в Xcode.
Вот код PHP.
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 ?
}
}
// Результат шифрования в формате base64encoding
IOS -> 8IV / 2MGUY0HfwZLrd212fKNyp6AUzYl +
PHP -> xUCTX0jsB3XyDWSeyUszSbQ2t90 / DNDv
Здесь закодированный результат не одинаков в двух средах. Я пробую это за последние 7 дней.
Но пока не нашли решения.
Пока знаю CCCrypt используется для CBC Режим . Я не понял, где моя проблема.
Это конец PHP или конец IOS?
Небольшая помощь будет высоко ценится.
Благодарю.
Проблема в том, что вы проходите мимо nil
если твой iv
является non-nil
в (iv)?nil:iv.bytes
Либо это должно быть (iv)?iv.bytes:nil
или просто iv.bytes
потому что это нормально, чтобы отправить сообщение nil
объект
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);
Изменить выше на ниже
ccStatus = CCCrypt(kCCEncrypt_or_kCCDecrypt,
kCCAlgorithmBlowfish,
options,
key.bytes,
key.length,
iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
Я перезапускаю ваш код, и результат такой же, как у PHP, т.е.
xUCTX0jsB3XyDWSeyUszSbQ2t90/DNDv
Других решений пока нет …