我正在尝试使用CBC模式和kCCOptionPKCS7Padding填充来实现Blowfish算法。类场景在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''utest.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 ?
}
}
//基于加密结果的64编码格式IOS->8IV/2MGUY0HfwZLrd212fKNyp6AUzYl+
PHP->xUCTX0jsB3XyDWSeyUszSbQ2t90/DNDv
这里编码的结果在两个环境中是不一样的。我试了7天了。但还没有找到解决方案。
到目前为止,我知道CCCrypt用于CBC模式。我不明白我的问题在哪里。是PHP端还是IOS端?
一点点帮助将不胜感激。谢谢
三元运算符正在毁掉你过去7天的生活
问题是,如果您的iv
在(iv)?nil:iv.bytes
为non-nil
,则您正在通过nil
它应该是(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