我在使用 RC4 算法 ( http://rc4crypt.devhome.org) 加密的服务器上有一个 XML 文件
function encrypt ($pwd, $data, $ispwdHex = 0)
{
if ($ispwdHex)
$pwd = @pack('H*', $pwd); // valid input, please!
$key[] = '';
$box[] = '';
$cipher = '';
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++)
{
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++)
{
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++)
{
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
这是我用来解密的 Objective-C 代码:
NSData *dataToDecrypt = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.url.com/fileCrypted.xml"]] returningResponse:nil error:nil];
const void *vplainText;
size_t plainTextBufferSize;
plainTextBufferSize = [dataToDecrypt length];
vplainText = [dataToDecrypt bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
NSString *key = @"mykey";
//NSString *initVec = @"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
size_t keyLength = [[key dataUsingEncoding:NSUTF8StringEncoding] length];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmRC4,
0,
vkey,
kCCKeySizeDES,
nil,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result = [[ NSString alloc ] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIEncoding];
日志输出:成功但我的结果不好(我测试了很多编码但 ASCII 似乎是好的,参见 PHP 函数 ord ...)
我的两个 RC4 实现标准吗?
编辑:删除了 Objective-C 代码中的 IV Edit2: Objective-C KeyLength = 密码数据长度,移除选项
最佳答案
如果您不知道自己在密码学方面做什么,那么“自己动手”肯定会招致灾难。你不必相信我,阅读 John Viega on The Cult of Schneier关于试图“推出自己的”密码学的一般程序员。释义:不要这样做。
由于这是一个文件,我猜这是一个合理的小文件,您可以使用更多标准和更高级别的库,使用 SSL(OpenSSL 等)或 OpenPGP(GPG 等)等标准来执行必要的操作加密/解密。我相信在 Objective-C(或 iPhone 环境)和 PHP 中都有对 SSL 的库或模块支持。
特别是关于 RC4,它是一种流密码,编写起来看似简单,但在实现细节上却很容易搞砸。参见 The Misuse of RC4 in Microsoft Word and Excel , 和 Can you recommend RC4 128-bit encrypted software?一个众所周知的历史例子,以及安全/密码学专家(PGP Corp. 的前首席技术官和联合创始人)的推荐。
添加:
php 脚本中的 key 大小基于密码数据的原始长度。它也不使用任何 PKCS7 填充,所以我认为该字段应该为零 (0)(CCryptor 不支持流密码的填充,而 php 版本当然不使用它)。在您的代码中,CCCrypt 使用了 8 个字节(64* 位)的 key 大小,而我相信您希望它是密码(二进制数据)的长度(以字节为单位)。
没有 MAC或数据的散列,因此函数将无法从无效解码中确定有效。
我认为这将使您更接近与 RC4(PHP 中的 RC4crypt)的这种不安全实现的兼容性。
- DES 使用 56-bits of key from 64-bits of key inpu t.
关于php - RC4 加密 - CommonCrypto (Objective-C) 与 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2235698/